<commit_before>// Created: 05/05/2007
// Updated: 05/05/2007

// Select canvas
// Keeps track of all information related to the select canvas.
function SelectCanvas() {

  // *******************************************
  // Private variables:
  // *******************************************

  this.annotation = null; // includes name, deleted, verified info
  this.isEditingControlPoint = 0;
  this.isMovingCenterOfMass = 0;
  this.editedControlPoints = 0; // whether the control points were edited

  // *******************************************
  // Public methods:
  // *******************************************

  this.GetAnnotation = function () {
    return this.annotation;
  };

  this.GetAnnoID = function () {
    if(this.annotation) return this.annotation.GetAnnoID();
    return -1;
  }

  this.didEditControlPoints = function () {
    return this.editedControlPoints;
  }

  // Attach the annotation to the canvas.
  this.AttachAnnotation = function (anno) {
    this.editedControlPoints = 0;
    this.annotation = anno;
    this.annotation.SetDivAttach('select_canvas');

    if(username_flag) submit_username();

    // Make edit popup appear.
    var pt = anno.GetPopupPoint();
    if(anno.GetVerified()) {
      this.annotation.DrawPolygon(main_image.GetImRatio());
      this.annotation.FillPolygon();
      pt = main_image.SlideWindow(pt[0],pt[1]);
      mkVerifiedPopup(pt[0],pt[1]);
      main_image.ScrollbarsOff();
    }
    else {
      this.DrawPolygon();
      main_image.SlideWindow(this.annotation.center_x,this.annotation.center_y);
    }
  };

  // Detach the annotation from the canvas.
  this.DetachAnnotation = function () {
    var anno = this.annotation;
    this.annotation = null;
    anno.DeletePolygon();

    WriteLogMsg('*Closed_Edit_Popup');
    CloseEditPopup();
    main_image.ScrollbarsOn();

    return anno;
  };

  this.ClearAnnotation = function () {
    if(this.annotation) this.annotation.DeletePolygon();
    return this.annotation;
  };

  this.RedrawAnnotation = function () {
    if(this.annotation) {
      this.annotation.DeletePolygon();
      this.DrawPolygon();
    }
  };

  // Move this canvas to the front.
  this.MoveToFront = function () {
      document.getElementById('select_canvas').style.zIndex = 0;
      document.getElementById('select_canvas_div').style.zIndex = 0;
  };

  // Move this canvas to the back.
  this.MoveToBack = function () {
      document.getElementById('select_canvas').style.zIndex = -2;
      document.getElementById('select_canvas_div').style.zIndex = -2;
  };

  // Handles when the annotation gets deleted.
  this.DeleteAnnotation = function () {
    var idx = this.annotation.GetAnnoID();
//     if(IsUserAnonymous() && (idx<num_orig_anno)) {
    if((IsUserAnonymous() || (!IsCreator(this.annotation.GetUsername()))) && (!IsUserAdmin()) && (idx<num_orig_anno) && !action_DeleteExistingObjects) {
      alert('You do not have permission to delete this polygon');
      return;
    }

    this.annotation.SetDeleted(1);

    if(idx>=num_orig_anno) {
      anno_count--;
      global_count--;
      setCookie('counter',anno_count);
      UpdateCounterHTML();
    }

    if(view_ObjList) {
      RemoveAnnotationList();
      LoadAnnotationList();
    }

    submission_edited = 0;
    old_name = this.annotation.GetObjName();
    new_name = this.annotation.GetObjName();
    WriteLogMsg('*Deleting_object');

    SubmitAnnotations(0);
    main_canvas.unselectObjects(); // Perhaps this should go elsewhere...
    main_handler.SelectedToRest();
  };

  this.MouseDown = function (x,y,button) {
    if(button>1) return;
    if(!this.isEditingControlPoint && this.annotation.StartMoveControlPoint(x,y,main_image.GetImRatio())) {
      this.isEditingControlPoint = 1;
      this.editedControlPoints = 1;
    }
    else if(!this.isMovingCenterOfMass && this.annotation.StartMoveCenterOfMass(x,y,main_image.GetImRatio())) {
      this.isMovingCenterOfMass = 1;
      this.editedControlPoints = 1;
    }
    else main_handler.SubmitEditLabel();
  };

  this.MouseMove = function (x,y,button) {
    if(button>1) return;
    if(this.isEditingControlPoint) {
      this.annotation.MoveControlPoint(x,y,main_image.GetImRatio());
      return;
    }
    if(this.isMovingCenterOfMass) {
      this.annotation.MoveCenterOfMass(x,y,main_image.GetImRatio());
    }
  };

  this.MouseUp = function (x,y,button) {
    if(button>1) return;
    if(this.isEditingControlPoint) {
      this.annotation.MoveControlPoint(x,y,main_image.GetImRatio());
      this.annotation.FillPolygon();
//       this.annotation.ShowControlPoints();
      this.annotation.ShowCenterOfMass(main_image.GetImRatio());
      this.isEditingControlPoint = 0;
      return;
    }
    if(this.isMovingCenterOfMass) {
      this.annotation.MoveCenterOfMass(x,y,main_image.GetImRatio());
      this.annotation.FillPolygon();
//       this.annotation.ShowControlPoints();
      this.isMovingCenterOfMass = 0;
    }
  };

  this.AllowAdjustPolygon = function () {
    var im_ratio = main_image.GetImRatio();
    this.annotation.ShowControlPoints();
    this.annotation.ShowCenterOfMass(im_ratio);
  };

  // *******************************************
  // Private methods:
  // *******************************************

  // Draw the polygon.
  this.DrawPolygon = function () {
    if(!this.annotation) return;
    var im_ratio = main_image.GetImRatio();
    this.annotation.DrawPolygon(im_ratio);
    this.annotation.FillPolygon();

    // If point has been labeled, then make autocomplete have "point"
    // be option:
    var isPoint = 0;
    if((this.annotation.GetPtsX().length==1) && (object_choices=='...')) {
      object_choices = 'point';
      object_choices = object_choices.split(/,/);
      isPoint = 1;
    }

    // If line has been labeled, then make autocomplete have "line"
    // and "horizon line" be options:
    var isLine = 0;
    if((this.annotation.GetPtsX().length==2) && (object_choices=='...')) {
      object_choices = 'line,horizon line';
      object_choices = object_choices.split(/,/);
      isLine = 1;
    }

    var m = main_image.GetFileInfo().GetMode();
//     if((m=='im') || (m=='mt')) {
      // Popup edit bubble:
      var pt = this.annotation.GetPopupPoint();
      pt = main_image.SlideWindow(pt[0],pt[1]);
      main_image.ScrollbarsOff();
      WriteLogMsg('*Opened_Edit_Popup');
      mkEditPopup(pt[0],pt[1],this.annotation.GetObjName());
//     }
//     else {
//       this.annotation.ShowControlPoints();
//       this.annotation.ShowCenterOfMass(im_ratio);
//     }

    if(isPoint || isLine) object_choices = '...';
  };

}
<commit_msg>Antonio changes<commit_after>// Created: 05/05/2007
// Updated: 05/05/2007

// Select canvas
// Keeps track of all information related to the select canvas.
function SelectCanvas() {

  // *******************************************
  // Private variables:
  // *******************************************

  this.annotation = null; // includes name, deleted, verified info
  this.isEditingControlPoint = 0;
  this.isMovingCenterOfMass = 0;
  this.editedControlPoints = 0; // whether the control points were edited

  // *******************************************
  // Public methods:
  // *******************************************

  this.GetAnnotation = function () {
    return this.annotation;
  };

  this.GetAnnoID = function () {
    if(this.annotation) return this.annotation.GetAnnoID();
    return -1;
  }

  this.didEditControlPoints = function () {
    return this.editedControlPoints;
  }

  // Attach the annotation to the canvas.
  this.AttachAnnotation = function (anno) {
    this.editedControlPoints = 0;
    this.annotation = anno;
    this.annotation.SetDivAttach('select_canvas');

    if(username_flag) submit_username();

    // Make edit popup appear.
    var pt = anno.GetPopupPoint();
    if(anno.GetVerified()) {
      this.annotation.DrawPolygon(main_image.GetImRatio());
      this.annotation.FillPolygon();
      pt = main_image.SlideWindow(pt[0],pt[1]);
      mkVerifiedPopup(pt[0],pt[1]);
      main_image.ScrollbarsOff();
    }
    else {
      this.DrawPolygon();
      main_image.SlideWindow(this.annotation.center_x,this.annotation.center_y);
    }
  };

  // Detach the annotation from the canvas.
  this.DetachAnnotation = function () {
    var anno = this.annotation;
    this.annotation = null;
    anno.DeletePolygon();

    WriteLogMsg('*Closed_Edit_Popup');
    CloseEditPopup();
    main_image.ScrollbarsOn();

    return anno;
  };

  this.ClearAnnotation = function () {
    if(this.annotation) this.annotation.DeletePolygon();
    return this.annotation;
  };

  this.RedrawAnnotation = function () {
    if(this.annotation) {
      this.annotation.DeletePolygon();
      this.DrawPolygon();
    }
  };

  // Move this canvas to the front.
  this.MoveToFront = function () {
      document.getElementById('select_canvas').style.zIndex = 0;
      document.getElementById('select_canvas_div').style.zIndex = 0;
  };

  // Move this canvas to the back.
  this.MoveToBack = function () {
      document.getElementById('select_canvas').style.zIndex = -2;
      document.getElementById('select_canvas_div').style.zIndex = -2;
  };

  // Handles when the annotation gets deleted.
  this.DeleteAnnotation = function () {
    var idx = this.annotation.GetAnnoID();
//     if(IsUserAnonymous() && (idx<num_orig_anno)) {
    if((IsUserAnonymous() || (!IsCreator(this.annotation.GetUsername()))) && (!IsUserAdmin()) && (idx<num_orig_anno) && !action_DeleteExistingObjects) {
      alert('You do not have permission to delete this polygon');
      return;
    }

    this.annotation.SetDeleted(1);

    if(idx>=num_orig_anno) {
      anno_count--;
      global_count--;
      setCookie('counter',anno_count);
      UpdateCounterHTML();
    }

    if(view_ObjList) {
      RemoveAnnotationList();
      LoadAnnotationList();
    }

    submission_edited = 0;
    old_name = this.annotation.GetObjName();
    new_name = this.annotation.GetObjName();
    WriteLogMsg('*Deleting_object');

    SubmitAnnotations(0);
    main_canvas.unselectObjects(); // Perhaps this should go elsewhere...
    main_handler.SelectedToRest();
  };

  this.MouseDown = function (x,y,button) {
    if(button>1) return;
    if(!this.isEditingControlPoint && this.annotation.StartMoveControlPoint(x,y,main_image.GetImRatio())) {
      this.isEditingControlPoint = 1;
      this.editedControlPoints = 1;
    }
    else if(!this.isMovingCenterOfMass && this.annotation.StartMoveCenterOfMass(x,y,main_image.GetImRatio())) {
      this.isMovingCenterOfMass = 1;
      this.editedControlPoints = 1;
    }
    else main_handler.SubmitEditLabel();
  };

  this.MouseMove = function (x,y,button) {
    if(button>1) return;
    if(this.isEditingControlPoint) {
      this.annotation.MoveControlPoint(x,y,main_image.GetImRatio());
      return;
    }
    if(this.isMovingCenterOfMass) {
      this.annotation.MoveCenterOfMass(x,y,main_image.GetImRatio());
    }
  };

  this.MouseUp = function (x,y,button) {
    if(button>1) return;
    if(this.isEditingControlPoint) {
      this.annotation.MoveControlPoint(x,y,main_image.GetImRatio());
      this.annotation.FillPolygon();
//       this.annotation.ShowControlPoints();
      this.annotation.ShowCenterOfMass(main_image.GetImRatio());
      this.isEditingControlPoint = 0;
      return;
    }
    if(this.isMovingCenterOfMass) {
      this.annotation.MoveCenterOfMass(x,y,main_image.GetImRatio());
      this.annotation.FillPolygon();
//       this.annotation.ShowControlPoints();
      this.isMovingCenterOfMass = 0;
    }
  };

  this.AllowAdjustPolygon = function () {
    var im_ratio = main_image.GetImRatio();
    this.annotation.ShowControlPoints();
    this.annotation.ShowCenterOfMass(im_ratio);
  };

  // *******************************************
  // Private methods:
  // *******************************************

  // Draw the polygon.
  this.DrawPolygon = function () {
    if(!this.annotation) return;
    var im_ratio = main_image.GetImRatio();
    this.annotation.DrawPolygon(im_ratio);
    this.annotation.FillPolygon();

    // If point has been labeled, then make autocomplete have "point"
    // be option:
    var isPoint = 0;
    if((this.annotation.GetPtsX().length==1) && (object_choices=='...')) {
      object_choices = 'point';
      object_choices = object_choices.split(/,/);
      isPoint = 1;
    }

    // If line has been labeled, then make autocomplete have "line"
    // and "horizon line" be options:
    var isLine = 0;
    if((this.annotation.GetPtsX().length==2) && (object_choices=='...')) {
      object_choices = 'line,horizon line';
      object_choices = object_choices.split(/,/);
      isLine = 1;
    }

    var m = main_image.GetFileInfo().GetMode();
//     if((m=='im') || (m=='mt')) {
      // Popup edit bubble:
      var pt = this.annotation.GetPopupPoint();
      pt = main_image.SlideWindow(pt[0],pt[1]);
      main_image.ScrollbarsOff();
      WriteLogMsg('*Opened_Edit_Popup');
      mkEditPopup(pt[0],pt[1],this.annotation);
     // mkEditPopup(pt[0],pt[1],this.annotation.GetObjName());
//     }
//     else {
//       this.annotation.ShowControlPoints();
//       this.annotation.ShowCenterOfMass(im_ratio);
//     }

    if(isPoint || isLine) object_choices = '...';
  };

}
<|endoftext|>


<commit_before>
var jq = null;
var KillKat =
{
	init: 	function(){

        KillKat.loadStaticFiles();
        KillKat.initImgList();
	},
    sound: null,
    domImgs : [],
    listImgs : [],
	IMG_MIN_WIDTH : 100,
	IMG_MIN_HEIGHT : 100,
	KILL_TAG: 'killkat-shot',
    OVERLAY_TAG: 'killkat-overlay',

    loadStaticFiles: function()
    {
        var stylesheet = document.createElement('link');
        stylesheet.href = 'https://rawgit.com/jorisgrouillet/killkat/master/css/killkat.css';
        stylesheet.rel = 'stylesheet';
        stylesheet.type = 'text/css';
        document.getElementsByTagName('head')[0].appendChild(stylesheet);
    },

	requirements: {
		'min-dimensions' : function(img){ return ((img.width * img.height) > (KillKat.IMG_MIN_WIDTH * KillKat.IMG_MIN_HEIGHT)); }
	},

	initImgList : function()
	{
        KillKat.domImgs = jq('img');
        KillKat.domImgs.each(
			function(idx, domImg){
				KillKat.filterImg(domImg);

			}
		);
	},

	filterImg : function(domImg)
	{
		if (KillKat.meetRequirements(domImg)){
			KillKat.addToListImgs(domImg);
		}
	},

	meetRequirements : function(domImg)
	{
		var reqs = KillKat.requirements || [];
		var validateReqs = true;
		for (var rIdx in reqs){
			if (typeof(reqs[rIdx]) == 'function'){
				validateReqs &= reqs[rIdx].call(this, domImg);
			}
		}
		return (validateReqs===1);
	},

	addToListImgs: function(domImg)
	{
		jqImg = KillKat.overrideClickEvent(domImg);
		KillKat.listImgs.push(jqImg);
	},

	overrideClickEvent: function(domImg)
	{
		var jqImg = jq(domImg);
		var fct = KillKat.getClickEventFunction();
		jqImg.unbind('click').click(fct);
		return jqImg;
	},
	getClickEventFunction: function()
	{
		return function(e){
            e.preventDefault();
			KillKat.handleTarget(this);
			return false;
		};
	},
	handleTarget: function(domImg)
	{
		var jqImg = jq(domImg);
        KillKat.setOverlay(jqImg);

        /*
		if (! KillKat.isKatKilled(jqImg)){
			jqImg.closest('div').addClass(KillKat.KILL_TAG);
            KillKat.setOverlay(jqImg);

		}
		else {
			jqImg.closest('div').removeClass(KillKat.KILL_TAG);
		}
		*/
	},
    setOverlay: function(jqImg)
    {
        var imgContainer = jqImg.closest('div');
        //imgContainer.css('z-index', 99);
        var imgIndex = (KillKat.getImgIndex(jqImg)).toString();
        var domOverlay = jq('#killkat-tag-'+imgIndex);

        if (! domOverlay.length)
        {
            domOverlay = jq('

')
                            .css({  'width' : imgContainer.innerWidth(),
                                    'height' : imgContainer.innerHeight(),
                                    'top' : imgContainer.offset().top,
                                    'left' : imgContainer.offset().left,
                                    'z-index': 1
                                })
                            .appendTo(jq('body'));

            KillKat.playSound();
            return;
        }

        if (domOverlay.is(':visible')){
            domOverlay.fadeOut(1000);
        }
        else{
            domOverlay.show();
            KillKat.playSound();
        }
    },

	isKatKilled: function(jqImg)
	{
		return (jqImg.parent().hasClass(KillKat.KILL_TAG));
	},

    getImgIndex : function(jqImg)
    {
        return KillKat.domImgs.index(jqImg);
    },
    playSound : function()
    {
        if (! jq('#killkat-sound').length){
            KillKat.setSoundPlayer();
        }
        KillKat.sound.play();
    },
    setSoundPlayer: function()
    {
        if (! jq('#killkat-sound').length)
        {
            var sound = jq('<audio id="killkat-sound" preload="auto" autoplay>'+
                '<source src="https://rawgit.com/jorisgrouillet/killkat/master/audio/splatter-sound.mp3" type="audio/mp3" />'+
                            //'<source src="http://www.freesfx.co.uk/rx2/mp3s/2/1871_1272479313.mp3" type="audio/mp3" />'+
                            'Votre navigateur n\'est pas compatible'+
                            '</audio>');

            jq('body').append(sound);
            KillKat.sound = sound.get(0);
        }
    }
	/*convertImgToBase64 : function(url, callback, outputFormat)
	{
	    var canvas = document.createElement('canvas'),
	    ctx = canvas.getContext('2d'),
	    img = new Image();
	    img.crossOrigin = 'Anonymous';
	    img.onload = function(){
	        canvas.height = img.height;
	        canvas.width = img.width;
	        ctx.drawImage(img,0,0);
	        var dataURL = canvas.toDataURL(outputFormat || 'image/png');
	        callback.call(this, dataURL);
	        canvas = null;
	    };
	    img.src = url;
	}*/
};

(function (_callback) {

    function loadScript(url, callback) {

        var script = document.createElement("script")
        script.type = "text/javascript";

        if (script.readyState) { //IE
            script.onreadystatechange = function () {
                if (script.readyState == "loaded" || script.readyState == "complete") {
                    script.onreadystatechange = null;
                    callback();
                }
            };
        } else { //Others
            script.onload = function () {
			jq = jQuery;
                callback();
            };
        }

        script.src = url;
        document.getElementsByTagName("head")[0].appendChild(script);
    }

    loadScript("//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function () {

         //jQuery loaded
         console.log('jquery loaded');
		 _callback.call(this);
    });

})( function(){  KillKat.init();});
<commit_msg>Update killkat.js<commit_after>
var jq = null;
var KillKat =
{
	init: 	function(){
alert('sdfsdfsdf');
        KillKat.loadStaticFiles();
        KillKat.initImgList();
	},
    sound: null,
    domImgs : [],
    listImgs : [],
	IMG_MIN_WIDTH : 100,
	IMG_MIN_HEIGHT : 100,
	KILL_TAG: 'killkat-shot',
    OVERLAY_TAG: 'killkat-overlay',

    loadStaticFiles: function()
    {
        var stylesheet = document.createElement('link');
        stylesheet.href = 'https://rawgit.com/jorisgrouillet/killkat/master/css/killkat.css';
        stylesheet.rel = 'stylesheet';
        stylesheet.type = 'text/css';
        document.getElementsByTagName('head')[0].appendChild(stylesheet);
    },

	requirements: {
		'min-dimensions' : function(img){ return ((img.width * img.height) > (KillKat.IMG_MIN_WIDTH * KillKat.IMG_MIN_HEIGHT)); }
	},

	initImgList : function()
	{
        KillKat.domImgs = jq('img');
        KillKat.domImgs.each(
			function(idx, domImg){
				KillKat.filterImg(domImg);

			}
		);
	},

	filterImg : function(domImg)
	{
		if (KillKat.meetRequirements(domImg)){
			KillKat.addToListImgs(domImg);
		}
	},

	meetRequirements : function(domImg)
	{
		var reqs = KillKat.requirements || [];
		var validateReqs = true;
		for (var rIdx in reqs){
			if (typeof(reqs[rIdx]) == 'function'){
				validateReqs &= reqs[rIdx].call(this, domImg);
			}
		}
		return (validateReqs===1);
	},

	addToListImgs: function(domImg)
	{
		jqImg = KillKat.overrideClickEvent(domImg);
		KillKat.listImgs.push(jqImg);
	},

	overrideClickEvent: function(domImg)
	{
		var jqImg = jq(domImg);
		var fct = KillKat.getClickEventFunction();
		jqImg.unbind('click').click(fct);
		return jqImg;
	},
	getClickEventFunction: function()
	{
		return function(e){
            e.preventDefault();
			KillKat.handleTarget(this);
			return false;
		};
	},
	handleTarget: function(domImg)
	{
		var jqImg = jq(domImg);
        KillKat.setOverlay(jqImg);

        /*
		if (! KillKat.isKatKilled(jqImg)){
			jqImg.closest('div').addClass(KillKat.KILL_TAG);
            KillKat.setOverlay(jqImg);

		}
		else {
			jqImg.closest('div').removeClass(KillKat.KILL_TAG);
		}
		*/
	},
    setOverlay: function(jqImg)
    {
        var imgContainer = jqImg.closest('div');
        //imgContainer.css('z-index', 99);
        var imgIndex = (KillKat.getImgIndex(jqImg)).toString();
        var domOverlay = jq('#killkat-tag-'+imgIndex);

        if (! domOverlay.length)
        {
            domOverlay = jq('

')
                            .css({  'width' : imgContainer.innerWidth(),
                                    'height' : imgContainer.innerHeight(),
                                    'top' : imgContainer.offset().top,
                                    'left' : imgContainer.offset().left,
                                    'z-index': 1
                                })
                            .appendTo(jq('body'));

            KillKat.playSound();
            return;
        }

        if (domOverlay.is(':visible')){
            domOverlay.fadeOut(1000);
        }
        else{
            domOverlay.show();
            KillKat.playSound();
        }
    },

	isKatKilled: function(jqImg)
	{
		return (jqImg.parent().hasClass(KillKat.KILL_TAG));
	},

    getImgIndex : function(jqImg)
    {
        return KillKat.domImgs.index(jqImg);
    },
    playSound : function()
    {
        if (! jq('#killkat-sound').length){
            KillKat.setSoundPlayer();
        }
        KillKat.sound.play();
    },
    setSoundPlayer: function()
    {
        if (! jq('#killkat-sound').length)
        {
            var sound = jq('<audio id="killkat-sound" preload="auto" autoplay>'+
                '<source src="https://rawgit.com/jorisgrouillet/killkat/master/audio/splatter-sound.mp3" type="audio/mp3" />'+
                            //'<source src="http://www.freesfx.co.uk/rx2/mp3s/2/1871_1272479313.mp3" type="audio/mp3" />'+
                            'Votre navigateur n\'est pas compatible'+
                            '</audio>');

            jq('body').append(sound);
            KillKat.sound = sound.get(0);
        }
    }
	/*convertImgToBase64 : function(url, callback, outputFormat)
	{
	    var canvas = document.createElement('canvas'),
	    ctx = canvas.getContext('2d'),
	    img = new Image();
	    img.crossOrigin = 'Anonymous';
	    img.onload = function(){
	        canvas.height = img.height;
	        canvas.width = img.width;
	        ctx.drawImage(img,0,0);
	        var dataURL = canvas.toDataURL(outputFormat || 'image/png');
	        callback.call(this, dataURL);
	        canvas = null;
	    };
	    img.src = url;
	}*/
};

(function (_callback) {

    function loadScript(url, callback) {

        var script = document.createElement("script")
        script.type = "text/javascript";

        if (script.readyState) { //IE
            script.onreadystatechange = function () {
                if (script.readyState == "loaded" || script.readyState == "complete") {
                    script.onreadystatechange = null;
                    callback();
                }
            };
        } else { //Others
            script.onload = function () {
			jq = jQuery;
                callback();
            };
        }

        script.src = url;
        document.getElementsByTagName("head")[0].appendChild(script);
    }

    loadScript("//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function () {

         //jQuery loaded
         console.log('jquery loaded');
		 _callback.call(this);
    });

})( function(){  KillKat.init();});
<|endoftext|>


<commit_before>// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//

// jquery and angular
//= require jquery2
//= require jquery_ujs
//= require jquery.ui.all
//= require jquery.powertip
//= require jquery.cookie
//= require jquery.jstree/jquery.jstree
//= require jquery.vAlign
//= require angular
//= require angular-resource
//= require angular-animate
//= require angularjs-file-upload
//= require ../shared/ng-infinite-scroll.min.js
//= require ../shared/ng-tags-input.min.js
//= require angular-rails-templates
//= require lodash.underscore.js

// datetimepicker  (fil, nb)
//= require flatpickr/dist/flatpickr.min
//= require flatpickr/dist/l10n/ar
//= require flatpickr/dist/l10n/cat
//= require flatpickr/dist/l10n/cy
//= require flatpickr/dist/l10n/de
//= require flatpickr/dist/l10n/es
//= require flatpickr/dist/l10n/fr
//= require flatpickr/dist/l10n/it
//= require flatpickr/dist/l10n/nl
//= require flatpickr/dist/l10n/pl
//= require flatpickr/dist/l10n/pt
//= require flatpickr/dist/l10n/ru
//= require flatpickr/dist/l10n/sv
//= require flatpickr/dist/l10n/tr
//= require shortcut-buttons-flatpickr/dist/shortcut-buttons-flatpickr.min
//= require flatpickr/dist/plugins/labelPlugin/labelPlugin

// spree
//= require admin/spree/spree
//= require admin/spree/spree-select2
//= require modernizr
//= require equalize
//= require css_browser_selector_dev
//= require responsive-tables
//= require admin/spree/handlebar_extensions

// OFN specific
//= require ../shared/shared
//= require_tree ../shared/directives
//= require_tree ../templates/shared
//= require_tree ../templates/admin
//= require ./admin_ofn
//= require ./customers/customers
//= require ./dropdown/dropdown
//= require ./enterprises/enterprises
//= require ./enterprise_fees/enterprise_fees
//= require ./enterprise_groups/enterprise_groups
//= require ./index_utils/index_utils
//= require ./inventory_items/inventory_items
//= require ./line_items/line_items
//= require ./orders/orders
//= require ./order_cycles/order_cycles
//= require ./payment_methods/payment_methods
//= require ./payments/payments
//= require ./product_import/product_import
//= require ./products/products
//= require ./resources/resources
//= require ./shipping_methods/shipping_methods
//= require ./side_menu/side_menu
//= require ./subscriptions/subscriptions
//= require ./tag_rules/tag_rules
//= require ./taxons/taxons
//= require ./utils/utils
//= require ./users/users
//= require ./variant_overrides/variant_overrides

// text, dates and translations
//= require textAngular-rangy.min.js
// This replaces angular-sanitize. We should include only one.
// https://github.com/textAngular/textAngular#where-to-get-it
//= require textAngular-sanitize.min.js
//= require textAngular.min.js
//= require i18n/translations
//= require darkswarm/i18n.translate.js
//= require moment/min/moment.min.js
//= require moment/locale/ar.js
//= require moment/locale/ca.js
//= require moment/locale/de.js
//= require moment/locale/en-gb.js
//= require moment/locale/es.js
//= require moment/locale/fil.js
//= require moment/locale/fr.js
//= require moment/locale/it.js
//= require moment/locale/nb.js
//= require moment/locale/nl-be.js
//= require moment/locale/pt-br.js
//= require moment/locale/pt.js
//= require moment/locale/ru.js
//= require moment/locale/sv.js
//= require moment/locale/tr.js
//= require moment/locale/pl.js

//= require js-big-decimal/dist/web/js-big-decimal.min.js

// foundation
//= require ../shared/mm-foundation-tpls-0.9.0-20180826174721.min.js

// LocalStorage
//= require ../shared/angular-local-storage.js

// requires the rest of the JS code in this folder
//= require_tree .
<commit_msg>Do not import flatpickr via this require<commit_after>// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//

// jquery and angular
//= require jquery2
//= require jquery_ujs
//= require jquery.ui.all
//= require jquery.powertip
//= require jquery.cookie
//= require jquery.jstree/jquery.jstree
//= require jquery.vAlign
//= require angular
//= require angular-resource
//= require angular-animate
//= require angularjs-file-upload
//= require ../shared/ng-infinite-scroll.min.js
//= require ../shared/ng-tags-input.min.js
//= require angular-rails-templates
//= require lodash.underscore.js

// datetimepicker  (fil, nb)
//= require flatpickr/dist/l10n/ar
//= require flatpickr/dist/l10n/cat
//= require flatpickr/dist/l10n/cy
//= require flatpickr/dist/l10n/de
//= require flatpickr/dist/l10n/es
//= require flatpickr/dist/l10n/fr
//= require flatpickr/dist/l10n/it
//= require flatpickr/dist/l10n/nl
//= require flatpickr/dist/l10n/pl
//= require flatpickr/dist/l10n/pt
//= require flatpickr/dist/l10n/ru
//= require flatpickr/dist/l10n/sv
//= require flatpickr/dist/l10n/tr
//= require shortcut-buttons-flatpickr/dist/shortcut-buttons-flatpickr.min
//= require flatpickr/dist/plugins/labelPlugin/labelPlugin

// spree
//= require admin/spree/spree
//= require admin/spree/spree-select2
//= require modernizr
//= require equalize
//= require css_browser_selector_dev
//= require responsive-tables
//= require admin/spree/handlebar_extensions

// OFN specific
//= require ../shared/shared
//= require_tree ../shared/directives
//= require_tree ../templates/shared
//= require_tree ../templates/admin
//= require ./admin_ofn
//= require ./customers/customers
//= require ./dropdown/dropdown
//= require ./enterprises/enterprises
//= require ./enterprise_fees/enterprise_fees
//= require ./enterprise_groups/enterprise_groups
//= require ./index_utils/index_utils
//= require ./inventory_items/inventory_items
//= require ./line_items/line_items
//= require ./orders/orders
//= require ./order_cycles/order_cycles
//= require ./payment_methods/payment_methods
//= require ./payments/payments
//= require ./product_import/product_import
//= require ./products/products
//= require ./resources/resources
//= require ./shipping_methods/shipping_methods
//= require ./side_menu/side_menu
//= require ./subscriptions/subscriptions
//= require ./tag_rules/tag_rules
//= require ./taxons/taxons
//= require ./utils/utils
//= require ./users/users
//= require ./variant_overrides/variant_overrides

// text, dates and translations
//= require textAngular-rangy.min.js
// This replaces angular-sanitize. We should include only one.
// https://github.com/textAngular/textAngular#where-to-get-it
//= require textAngular-sanitize.min.js
//= require textAngular.min.js
//= require i18n/translations
//= require darkswarm/i18n.translate.js
//= require moment/min/moment.min.js
//= require moment/locale/ar.js
//= require moment/locale/ca.js
//= require moment/locale/de.js
//= require moment/locale/en-gb.js
//= require moment/locale/es.js
//= require moment/locale/fil.js
//= require moment/locale/fr.js
//= require moment/locale/it.js
//= require moment/locale/nb.js
//= require moment/locale/nl-be.js
//= require moment/locale/pt-br.js
//= require moment/locale/pt.js
//= require moment/locale/ru.js
//= require moment/locale/sv.js
//= require moment/locale/tr.js
//= require moment/locale/pl.js

//= require js-big-decimal/dist/web/js-big-decimal.min.js

// foundation
//= require ../shared/mm-foundation-tpls-0.9.0-20180826174721.min.js

// LocalStorage
//= require ../shared/angular-local-storage.js

// requires the rest of the JS code in this folder
//= require_tree .
<|endoftext|>


<commit_before>module.exports = function runTask(req, res, next) {
  const seriesTask = req.apisTask.series;
  const parallelTask = req.apisTask.parallel;

  const runParallelTask = () => parallelTask.error(error => {
    next(error);
  }).run(() => {
    if (req.router.handle) {
      res.apiData = req.router.handle(res.apiData, req, res);
    }

    next();
  });

  if (seriesTask) {
    seriesTask.error(error => {
      next(error);
    }).run(() => {
      if (res.forwardSent || res.hasSent || res.headersSent) {
        return;
      }

      runParallelTask();
    });
  } else {
    runParallelTask();
  }
};
<commit_msg>update task run<commit_after>module.exports = function runTask(req, res, next) {
  const seriesTask = req.apisTask.series;
  const parallelTask = req.apisTask.parallel;

  const runParallelTask = () => {
    if (!parallelTask) {
      return next();
    }

    return parallelTask.error(error => {
      next(error);
    }).run(() => {
      if (req.router.handle) {
        res.apiData = req.router.handle(res.apiData, req, res);
      }

      next();
    });
  };

  if (seriesTask) {
    seriesTask.error(error => {
      next(error);
    }).run(() => {
      if (res.forwardSent || res.hasSent || res.headersSent) {
        return;
      }

      runParallelTask();
    });
  } else {
    runParallelTask();
  }
};
<|endoftext|>


<commit_before>var inherits = require('util').inherits;
var EventEmitter = require('events').EventEmitter;
var _ = require('lodash');

module.exports = FirebaseSearch;
var firebaseSearch;

function FirebaseSearch(ref, options, type) {
  if (!(this instanceof FirebaseSearch)) {
    return new FirebaseSearch(ref, options, type);
  }
  firebaseSearch = this;
  this.ref = ref;
  this.options = options;
  this.type = type || ref.toString().replace(/.+\.com\//, '').replace(/\//g, ':');
  if (options.log) {
    this.log = require('./services/log')(ref.parent.child(`firebase-search/logs/${this.type}`));
  }
  if (this.options.elasticsearch) {
    var elasticsearch = require('elasticsearch');
    this.elasticsearch.client = new elasticsearch.Client(_.clone(this.options.elasticsearch));
  } else {
    this.elasticsearch = 'Elasticsearch options undefined';
  }

  if (this.options.algolia) {
    var algoliasearch = require('algoliasearch');
    this.algolia.client = algoliasearch(this.options.algolia.applicationID, this.options.algolia.apiKey);
    this.algolia.index = this.algolia.client.initIndex(this.type);
  } else {
    this.algolia = 'Algolia options undefined';
  }

  this.ensureExistingUser = function () {
    ref.orderByKey().limitToLast(1).once('value', function (snap) {
      if (!snap.numChildren()) {
        var fakeRef = ref.push();
        fakeRef.set(true)
          .then(function () {
            fakeRef.remove();
          })
      }
    });
  };

  this.getLastKey = function () {
    return new Promise(function (resolve, reject) {
      var ref = firebaseSearch.ref.orderByKey().limitToLast(1);
      var handler = function (snap) {
        ref.off('child_added', handler);
        resolve(snap.key);
      };
      var timer = setTimeout(function () { // Must be empty if no response in 1000 millis
        ref.off('child_added', handler);
        reject('Timeout! Could be an empty Firebase collection.');
      }, 1000);
      ref.on('child_added', handler);
    });
  };
  this.fire = function (name, detail) {
    firebaseSearch.emit(name, detail);
    firebaseSearch.emit('all', {
      name: name,
      detail: detail
    });
  };
};

inherits(FirebaseSearch, EventEmitter);

function toPromise(fn, args, algoliaWait) {
  return new Promise(function (resolve, reject) {
    var argsArray = Array.isArray(args) ? args : [args];

    if (algoliaWait) {
      argsArray = argsArray.concat([function (err, content) {
        if (err) {
          reject(err);
        } else {
          firebaseSearch.algolia.index.waitTask(content.taskID, function (err) {
            err ? reject(err) : resolve(content);
          });
        }
      }]);
    } else {
      argsArray = argsArray.concat([function (err, res) {
        err ? reject(err) : resolve(res);
      }]);
    }

    if (typeof argsArray[0] === 'undefined') {
      argsArray.splice(0, 1);
    }
    fn.apply(this, argsArray);
  }.bind(this));
};

function addKeyToSnap(snap) {
  var obj = snap.val();
  obj.__id__ = snap.key;
  return obj;
};

FirebaseSearch.prototype.elasticsearch = {
  indices: {
    exists: function (params) {
      var params = _.defaults(params, {
        index: firebaseSearch.options.elasticsearch.index
      });
      return toPromise(firebaseSearch.elasticsearch.client.indices.exists.bind(firebaseSearch.elasticsearch.client.indices), params);
    },
    delete: function (params) {
      var params = _.defaults(params, {
        index: firebaseSearch.options.elasticsearch.index
      });
      return toPromise(firebaseSearch.elasticsearch.client.indices.delete.bind(firebaseSearch.elasticsearch.client.indices), params);
    },
    create: function (params) {
      var params = _.defaults(params, {
        index: firebaseSearch.options.elasticsearch.index
      });
      return toPromise(firebaseSearch.elasticsearch.client.indices.create.bind(firebaseSearch.elasticsearch.client.indices), params);
    },
    ensure: function () {
      var params = _.defaults(params, {
        index: firebaseSearch.options.elasticsearch.index
      });
      return firebaseSearch.elasticsearch.indices.exists()
        .then(function (exists) {
          return exists || firebaseSearch.elasticsearch.indices.create(params);
        });
    }
  },
  ping: function () {
    return toPromise(firebaseSearch.elasticsearch.client.ping.bind(firebaseSearch.elasticsearch.client), { hello: 'elasticsearch!' });
  },
  create: function (params) {
    var params = _.defaults(params, {
      index: firebaseSearch.options.elasticsearch.index,
      type: firebaseSearch.type
    });
    return firebaseSearch.elasticsearch.exists(params)
      .then(function (exists) {
        return !exists ? true : firebaseSearch.elasticsearch.delete(params);
      })
      .then(function () {
        return toPromise(firebaseSearch.elasticsearch.client.create.bind(firebaseSearch.elasticsearch.client), params);
      });
  },
  update: function (params) {
    var params = _.defaults(params, {
      index: firebaseSearch.options.elasticsearch.index,
      type: firebaseSearch.type
    });
    return toPromise(firebaseSearch.elasticsearch.client.update.bind(firebaseSearch.elasticsearch.client), params);
  },
  delete: function (params) {
    var params = _.defaults(params, {
      index: firebaseSearch.options.elasticsearch.index,
      type: firebaseSearch.type
    });
    return toPromise(firebaseSearch.elasticsearch.client.delete.bind(firebaseSearch.elasticsearch.client), params);
  },
  exists: function (params) {
    var params = _.defaults(params, {
      index: firebaseSearch.options.elasticsearch.index,
      type: firebaseSearch.type
    });
    return toPromise(firebaseSearch.elasticsearch.client.exists.bind(firebaseSearch.elasticsearch.client), params);
  },
  get: function (params) {
    var params = _.defaults(params, {
      index: firebaseSearch.options.elasticsearch.index,
      type: firebaseSearch.type
    });
    return toPromise(firebaseSearch.elasticsearch.client.get.bind(firebaseSearch.elasticsearch.client), params);
  },
  search: function (params) {
    var params = _.defaults(params, {
      index: firebaseSearch.options.elasticsearch.index,
      type: firebaseSearch.type
    });
    return toPromise(firebaseSearch.elasticsearch.client.search.bind(firebaseSearch.elasticsearch.client), params);
  },
  firebase: { // Firebase index management
    build: function (returnPromise) {
      return firebaseSearch.getLastKey()
        .then(function (lastKey) {
          return new Promise(function (resolve, reject) {
            var ref = firebaseSearch.ref.orderByKey();
            var promises = [];
            var finish = false;
            var successful = 0;
            var failed = 0;
            var total = 0;
            var handler = function (snap) {
              var promise = firebaseSearch.elasticsearch.create({
                id: snap.key,
                body: snap.val()
              }).then(function (res) {
                successful += res._shards.successful;
                failed += res._shards.failed;
                total += 1;
                return res;
              });

              if (returnPromise) {
                promises.push(promise);
              }

              if (snap.key === lastKey) {
                ref.off('child_added', handler);
                finish = _.debounce(function () {
                  resolve({
                    successful: successful,
                    failed: failed,
                    total: total
                  });
                }, 250);
              }

              if (finish) {
                promise.then(function () {
                  if (returnPromise) {
                    resolve(Promise.all(promises));
                  } else {
                    finish();
                  }
                });
              }
            }
            ref.on('child_added', handler);
          });
        });
    },
    start: function () {
      return new Promise(function (resolve, reject) {
        var ref = firebaseSearch.ref;
        var started;
        firebaseSearch.elasticsearch.handlers = {
          child_added: function (snap) {
            if (!started) { // Skip the first child_added event. It's often an existing record.
              started = true;
              resolve(snap.key);
            } else {
              firebaseSearch.fire('elasticsearch_child_added', addKeyToSnap(snap));
              // firebaseSearch.log('elasticsearch_child_added', snap.key);
              firebaseSearch.elasticsearch.create({
                id: snap.key,
                body: snap.val()
              });
            }
          },
          child_changed: function (snap) {
            firebaseSearch.fire('elasticsearch_child_changed', addKeyToSnap(snap));
            // firebaseSearch.log('elasticsearch_child_changed', snap.key);
            firebaseSearch.elasticsearch.update({
              id: snap.key,
              body: {
                doc: snap.val()
              }
            });
          },
          child_removed: function (snap) {
            firebaseSearch.fire('elasticsearch_child_removed', addKeyToSnap(snap));
            // firebaseSearch.log('elasticsearch_child_removed', snap.key);
            firebaseSearch.elasticsearch.delete({
              id: snap.key
            });
          }
        };
        firebaseSearch.elasticsearch.listeningRefs = {
          child_added: ref.orderByKey().limitToLast(1),
          child_changed: ref,
          child_removed: ref
        };
        firebaseSearch.elasticsearch.listeningRefs.child_added.once('value')
          .then(function (snap) {
            if (!snap.numChildren()) started = true, resolve(true);
            firebaseSearch.elasticsearch.listeningRefs.child_added.on('child_added', firebaseSearch.elasticsearch.handlers.child_added);
            firebaseSearch.elasticsearch.listeningRefs.child_changed.on('child_changed', firebaseSearch.elasticsearch.handlers.child_changed);
            firebaseSearch.elasticsearch.listeningRefs.child_removed.on('child_removed', firebaseSearch.elasticsearch.handlers.child_removed);
          });
      });
    },
    stop: function () {
      if (firebaseSearch.elasticsearch.handlers && firebaseSearch.elasticsearch.listeningRefs) {
        firebaseSearch.elasticsearch.listeningRefs.child_added.off('child_added', firebaseSearch.elasticsearch.handlers.child_added);
        firebaseSearch.elasticsearch.listeningRefs.child_changed.off('child_changed', firebaseSearch.elasticsearch.handlers.child_changed);
        firebaseSearch.elasticsearch.listeningRefs.child_removed.off('child_removed', firebaseSearch.elasticsearch.handlers.child_removed);
      } else {
        firebaseSearch.log('Firebase elasticsearch listeners not started.');
      }
    }
  }
};

FirebaseSearch.prototype.algolia = {
  search: function (query, options) {
    return toPromise(firebaseSearch.algolia.index.search.bind(firebaseSearch.algolia.index), [query, options]);
  },
  addObject: function (args, shouldWait) {
    return toPromise(firebaseSearch.algolia.index.addObject.bind(firebaseSearch.algolia.index), args, shouldWait);
  },
  saveObject: function (args, shouldWait) {
    return toPromise(firebaseSearch.algolia.index.saveObject.bind(firebaseSearch.algolia.index), args, shouldWait);
  },
  deleteObject: function (args, shouldWait) {
    return toPromise(firebaseSearch.algolia.index.deleteObject.bind(firebaseSearch.algolia.index), args, shouldWait);
  },
  setSettings: function (args) {
    return toPromise(firebaseSearch.algolia.index.setSettings.bind(firebaseSearch.algolia.index), args);
  },
  listIndexes: function () {
    return toPromise(firebaseSearch.algolia.client.listIndexes.bind(firebaseSearch.algolia.client));
  },
  clearIndex: function (shouldWait) {
    return toPromise(firebaseSearch.algolia.index.clearIndex.bind(firebaseSearch.algolia.index), undefined, shouldWait);
  },
  waitTask: function (args) {
    return toPromise(firebaseSearch.algolia.index.waitTask.bind(firebaseSearch.algolia.index), args);
  },
  exists: function (name) {
    var name = name || firebaseSearch.type;
    return firebaseSearch.algolia.listIndexes()
      .then(function (indexes) {
        return !!~_.map(indexes.items, 'name').indexOf(name);
      });
  },
  firebase: {
    build: function () {
      return firebaseSearch.getLastKey()
        .then(function (lastKey) {
          return new Promise(function (resolve, reject) {
            var ref = firebaseSearch.ref.orderByKey();
            var first = true;
            var finish = false;
            var successful = 0;
            var failed = 0;
            var total = 0;
            var children = [];
            var timeouts = 0;
            var processObj = function () {
              if (children.length) {
                var obj = children.shift();
                firebaseSearch.algolia.addObject(obj)
                  .then(function (res) {
                    if (res.createdAt) {
                      successful += 1;
                    } else {
                      failed += 1;
                    }
                    total += 1;
                    processObj(); // Process next record from front of list
                  });
              } else {
                if (finish) {
                  resolve({
                    successful: successful,
                    failed: failed,
                    total: total
                  });
                } else { // Wait for lagging child_added events and try again.
                  if (timeouts < 10) {
                    setTimeout(function () {
                      timeouts += 1;
                      processObj();
                    }, 500);
                  } else {
                    reject('child_added events took too long.');
                  }
                }
              }
            };
            var handler = function (snap) {
              var obj = snap.val();
              obj.objectID = snap.key;
              children.push(obj);

              if (first) {
                first = false;
                processObj();
              }

              if (snap.key === lastKey) {
                ref.off('child_added', handler);
                finish = true;
              }
            }
            ref.on('child_added', handler);
          });
        });
    },
    start: function () {
      return new Promise(function (resolve, reject) {
        var ref = firebaseSearch.ref;
        var started;
        firebaseSearch.algolia.handlers = {
          child_added: function (snap) {
            if (!started) { // Skip the first child_added event. It's often an existing record.
              started = true;
              resolve(snap.key);
            } else {
              var obj = snap.val();
              obj.objectID = snap.key;
              firebaseSearch.algolia.addObject(obj, true)
                .then(function () {
                  // firebaseSearch.log('algolia_child_added', snap.key);
                  firebaseSearch.fire('algolia_child_added', obj);
                });
            }
          },
          child_changed: function (snap) {
            var obj = snap.val();
            obj.objectID = snap.key;
            firebaseSearch.algolia.saveObject(obj, true)
              .then(function () {
                // firebaseSearch.log('algolia_child_changed', snap.key);
                firebaseSearch.fire('algolia_child_changed', obj);
              });
          },
          child_removed: function (snap) {
            firebaseSearch.algolia.deleteObject(snap.key, true)
              .then(function () {
                // firebaseSearch.log('algolia_child_removed', snap.key);
                firebaseSearch.fire('algolia_child_removed', snap.key);
              });
          }
        };
        firebaseSearch.algolia.listeningRefs = {
          child_added: ref.orderByKey().limitToLast(1),
          child_changed: ref,
          child_removed: ref
        };

        firebaseSearch.algolia.listeningRefs.child_added.once('value')
          .then(function (snap) {
            if (!snap.numChildren()) started = true, resolve(true);
            firebaseSearch.algolia.listeningRefs.child_added.on('child_added', firebaseSearch.algolia.handlers.child_added);
            firebaseSearch.algolia.listeningRefs.child_changed.on('child_changed', firebaseSearch.algolia.handlers.child_changed);
            firebaseSearch.algolia.listeningRefs.child_removed.on('child_removed', firebaseSearch.algolia.handlers.child_removed);
          });
      });
    },
    stop: function () {
      if (firebaseSearch.algolia.handlers && firebaseSearch.algolia.listeningRefs) {
        firebaseSearch.algolia.listeningRefs.child_added.off('child_added', firebaseSearch.algolia.handlers.child_added);
        firebaseSearch.algolia.listeningRefs.child_changed.off('child_changed', firebaseSearch.algolia.handlers.child_changed);
        firebaseSearch.algolia.listeningRefs.child_removed.off('child_removed', firebaseSearch.algolia.handlers.child_removed);
      } else {
        firebaseSearch.log('Firebase algolia listeners not started.');
      }
    }
  }
};
<commit_msg>Reworking prototype.<commit_after>var inherits = require('util').inherits;
var EventEmitter = require('events').EventEmitter;
var _ = require('lodash');

inherits(FirebaseSearch, EventEmitter);

module.exports = FirebaseSearch;

function FirebaseSearch(ref, options, type) {
  if (!(this instanceof FirebaseSearch)) {
    return new FirebaseSearch(ref, options, type);
  }

  var firebaseSearch = this;

  setPrototype(firebaseSearch);

  this.ensureExistingUser = function () {
    ref.orderByKey().limitToLast(1).once('value', function (snap) {
      if (!snap.numChildren()) {
        var fakeRef = ref.push();
        fakeRef.set(true)
          .then(function () {
            fakeRef.remove();
          })
      }
    });
  };

  this.getLastKey = function () {
    return new Promise(function (resolve, reject) {
      var ref = firebaseSearch.ref.orderByKey().limitToLast(1);
      var handler = function (snap) {
        ref.off('child_added', handler);
        resolve(snap.key);
      };
      var timer = setTimeout(function () { // Must be empty if no response in 1000 millis
        ref.off('child_added', handler);
        reject('Timeout! Could be an empty Firebase collection.');
      }, 1000);
      ref.on('child_added', handler);
    });
  };

  this.fire = function (name, detail) {
    firebaseSearch.emit(name, detail);
    firebaseSearch.emit('all', {
      name: name,
      detail: detail
    });
  };

  this.ref = ref;
  this.options = options;
  this.type = type || ref.toString().replace(/.+\.com\//, '').replace(/\//g, ':');
  if (options.log) {
    this.log = require('./services/log')(ref.parent.child(`firebase-search/logs/${this.type}`));
  }
  if (this.options.elasticsearch) {
    var elasticsearch = require('elasticsearch');
    this.elasticsearch.client = new elasticsearch.Client(_.clone(this.options.elasticsearch));
  } else {
    this.elasticsearch = 'Elasticsearch options undefined';
  }

  if (this.options.algolia) {
    var algoliasearch = require('algoliasearch');
    this.algolia.client = algoliasearch(this.options.algolia.applicationID, this.options.algolia.apiKey);
    this.algolia.index = this.algolia.client.initIndex(this.type);
  } else {
    this.algolia = 'Algolia options undefined';
  }
};

function setPrototype(firebaseSearch) {

  function toPromise(fn, args, algoliaWait) {
    return new Promise(function (resolve, reject) {
      var argsArray = Array.isArray(args) ? args : [args];

      if (algoliaWait) {
        argsArray = argsArray.concat([function (err, content) {
          if (err) {
            reject(err);
          } else {
            firebaseSearch.algolia.index.waitTask(content.taskID, function (err) {
              err ? reject(err) : resolve(content);
            });
          }
        }]);
      } else {
        argsArray = argsArray.concat([function (err, res) {
          err ? reject(err) : resolve(res);
        }]);
      }

      if (typeof argsArray[0] === 'undefined') {
        argsArray.splice(0, 1);
      }
      fn.apply(this, argsArray);
    }.bind(this));
  };

  function addKeyToSnap(snap) {
    var obj = snap.val();
    obj.__id__ = snap.key;
    return obj;
  };

  FirebaseSearch.prototype.elasticsearch = {
    indices: {
      exists: function (params) {
        var params = _.defaults(params, {
          index: firebaseSearch.options.elasticsearch.index
        });
        return toPromise(firebaseSearch.elasticsearch.client.indices.exists.bind(firebaseSearch.elasticsearch.client.indices), params);
      },
      delete: function (params) {
        var params = _.defaults(params, {
          index: firebaseSearch.options.elasticsearch.index
        });
        return toPromise(firebaseSearch.elasticsearch.client.indices.delete.bind(firebaseSearch.elasticsearch.client.indices), params);
      },
      create: function (params) {
        var params = _.defaults(params, {
          index: firebaseSearch.options.elasticsearch.index
        });
        return toPromise(firebaseSearch.elasticsearch.client.indices.create.bind(firebaseSearch.elasticsearch.client.indices), params);
      },
      ensure: function () {
        var params = _.defaults(params, {
          index: firebaseSearch.options.elasticsearch.index
        });
        return firebaseSearch.elasticsearch.indices.exists()
          .then(function (exists) {
            return exists || firebaseSearch.elasticsearch.indices.create(params);
          });
      }
    },
    ping: function () {
      return toPromise(firebaseSearch.elasticsearch.client.ping.bind(firebaseSearch.elasticsearch.client), { hello: 'elasticsearch!' });
    },
    create: function (params) {
      var params = _.defaults(params, {
        index: firebaseSearch.options.elasticsearch.index,
        type: firebaseSearch.type
      });
      return firebaseSearch.elasticsearch.exists(params)
        .then(function (exists) {
          return !exists ? true : firebaseSearch.elasticsearch.delete(params);
        })
        .then(function () {
          return toPromise(firebaseSearch.elasticsearch.client.create.bind(firebaseSearch.elasticsearch.client), params);
        });
    },
    update: function (params) {
      var params = _.defaults(params, {
        index: firebaseSearch.options.elasticsearch.index,
        type: firebaseSearch.type
      });
      return toPromise(firebaseSearch.elasticsearch.client.update.bind(firebaseSearch.elasticsearch.client), params);
    },
    delete: function (params) {
      var params = _.defaults(params, {
        index: firebaseSearch.options.elasticsearch.index,
        type: firebaseSearch.type
      });
      return toPromise(firebaseSearch.elasticsearch.client.delete.bind(firebaseSearch.elasticsearch.client), params);
    },
    exists: function (params) {
      var params = _.defaults(params, {
        index: firebaseSearch.options.elasticsearch.index,
        type: firebaseSearch.type
      });
      return toPromise(firebaseSearch.elasticsearch.client.exists.bind(firebaseSearch.elasticsearch.client), params);
    },
    get: function (params) {
      var params = _.defaults(params, {
        index: firebaseSearch.options.elasticsearch.index,
        type: firebaseSearch.type
      });
      return toPromise(firebaseSearch.elasticsearch.client.get.bind(firebaseSearch.elasticsearch.client), params);
    },
    search: function (params) {
      var params = _.defaults(params, {
        index: firebaseSearch.options.elasticsearch.index,
        type: firebaseSearch.type
      });
      return toPromise(firebaseSearch.elasticsearch.client.search.bind(firebaseSearch.elasticsearch.client), params);
    },
    firebase: { // Firebase index management
      build: function (returnPromise) {
        return firebaseSearch.getLastKey()
          .then(function (lastKey) {
            return new Promise(function (resolve, reject) {
              var ref = firebaseSearch.ref.orderByKey();
              var promises = [];
              var finish = false;
              var successful = 0;
              var failed = 0;
              var total = 0;
              var handler = function (snap) {
                var promise = firebaseSearch.elasticsearch.create({
                  id: snap.key,
                  body: snap.val()
                }).then(function (res) {
                  successful += res._shards.successful;
                  failed += res._shards.failed;
                  total += 1;
                  return res;
                });

                if (returnPromise) {
                  promises.push(promise);
                }

                if (snap.key === lastKey) {
                  ref.off('child_added', handler);
                  finish = _.debounce(function () {
                    resolve({
                      successful: successful,
                      failed: failed,
                      total: total
                    });
                  }, 250);
                }

                if (finish) {
                  promise.then(function () {
                    if (returnPromise) {
                      resolve(Promise.all(promises));
                    } else {
                      finish();
                    }
                  });
                }
              }
              ref.on('child_added', handler);
            });
          });
      },
      start: function () {
        return new Promise(function (resolve, reject) {
          var ref = firebaseSearch.ref;
          var started;
          firebaseSearch.elasticsearch.handlers = {
            child_added: function (snap) {
              if (!started) { // Skip the first child_added event. It's often an existing record.
                started = true;
                resolve(snap.key);
              } else {
                firebaseSearch.fire('elasticsearch_child_added', addKeyToSnap(snap));
                // firebaseSearch.log('elasticsearch_child_added', snap.key);
                firebaseSearch.elasticsearch.create({
                  id: snap.key,
                  body: snap.val()
                });
              }
            },
            child_changed: function (snap) {
              firebaseSearch.fire('elasticsearch_child_changed', addKeyToSnap(snap));
              // firebaseSearch.log('elasticsearch_child_changed', snap.key);
              firebaseSearch.elasticsearch.update({
                id: snap.key,
                body: {
                  doc: snap.val()
                }
              });
            },
            child_removed: function (snap) {
              firebaseSearch.fire('elasticsearch_child_removed', addKeyToSnap(snap));
              // firebaseSearch.log('elasticsearch_child_removed', snap.key);
              firebaseSearch.elasticsearch.delete({
                id: snap.key
              });
            }
          };
          firebaseSearch.elasticsearch.listeningRefs = {
            child_added: ref.orderByKey().limitToLast(1),
            child_changed: ref,
            child_removed: ref
          };
          firebaseSearch.elasticsearch.listeningRefs.child_added.once('value')
            .then(function (snap) {
              if (!snap.numChildren()) started = true, resolve(true);
              firebaseSearch.elasticsearch.listeningRefs.child_added.on('child_added', firebaseSearch.elasticsearch.handlers.child_added);
              firebaseSearch.elasticsearch.listeningRefs.child_changed.on('child_changed', firebaseSearch.elasticsearch.handlers.child_changed);
              firebaseSearch.elasticsearch.listeningRefs.child_removed.on('child_removed', firebaseSearch.elasticsearch.handlers.child_removed);
            });
        });
      },
      stop: function () {
        if (firebaseSearch.elasticsearch.handlers && firebaseSearch.elasticsearch.listeningRefs) {
          firebaseSearch.elasticsearch.listeningRefs.child_added.off('child_added', firebaseSearch.elasticsearch.handlers.child_added);
          firebaseSearch.elasticsearch.listeningRefs.child_changed.off('child_changed', firebaseSearch.elasticsearch.handlers.child_changed);
          firebaseSearch.elasticsearch.listeningRefs.child_removed.off('child_removed', firebaseSearch.elasticsearch.handlers.child_removed);
        } else {
          firebaseSearch.log('Firebase elasticsearch listeners not started.');
        }
      }
    }
  };

  FirebaseSearch.prototype.algolia = {
    search: function (query, options) {
      return toPromise(firebaseSearch.algolia.index.search.bind(firebaseSearch.algolia.index), [query, options]);
    },
    addObject: function (args, shouldWait) {
      return toPromise(firebaseSearch.algolia.index.addObject.bind(firebaseSearch.algolia.index), args, shouldWait);
    },
    saveObject: function (args, shouldWait) {
      return toPromise(firebaseSearch.algolia.index.saveObject.bind(firebaseSearch.algolia.index), args, shouldWait);
    },
    deleteObject: function (args, shouldWait) {
      return toPromise(firebaseSearch.algolia.index.deleteObject.bind(firebaseSearch.algolia.index), args, shouldWait);
    },
    setSettings: function (args) {
      return toPromise(firebaseSearch.algolia.index.setSettings.bind(firebaseSearch.algolia.index), args);
    },
    listIndexes: function () {
      return toPromise(firebaseSearch.algolia.client.listIndexes.bind(firebaseSearch.algolia.client));
    },
    clearIndex: function (shouldWait) {
      return toPromise(firebaseSearch.algolia.index.clearIndex.bind(firebaseSearch.algolia.index), undefined, shouldWait);
    },
    waitTask: function (args) {
      return toPromise(firebaseSearch.algolia.index.waitTask.bind(firebaseSearch.algolia.index), args);
    },
    exists: function (name) {
      var name = name || firebaseSearch.type;
      return firebaseSearch.algolia.listIndexes()
        .then(function (indexes) {
          return !!~_.map(indexes.items, 'name').indexOf(name);
        });
    },
    firebase: {
      build: function () {
        return firebaseSearch.getLastKey()
          .then(function (lastKey) {
            return new Promise(function (resolve, reject) {
              var ref = firebaseSearch.ref.orderByKey();
              var first = true;
              var finish = false;
              var successful = 0;
              var failed = 0;
              var total = 0;
              var children = [];
              var timeouts = 0;
              var processObj = function () {
                if (children.length) {
                  var obj = children.shift();
                  firebaseSearch.algolia.addObject(obj)
                    .then(function (res) {
                      if (res.createdAt) {
                        successful += 1;
                      } else {
                        failed += 1;
                      }
                      total += 1;
                      processObj(); // Process next record from front of list
                    });
                } else {
                  if (finish) {
                    resolve({
                      successful: successful,
                      failed: failed,
                      total: total
                    });
                  } else { // Wait for lagging child_added events and try again.
                    if (timeouts < 10) {
                      setTimeout(function () {
                        timeouts += 1;
                        processObj();
                      }, 500);
                    } else {
                      reject('child_added events took too long.');
                    }
                  }
                }
              };
              var handler = function (snap) {
                var obj = snap.val();
                obj.objectID = snap.key;
                children.push(obj);

                if (first) {
                  first = false;
                  processObj();
                }

                if (snap.key === lastKey) {
                  ref.off('child_added', handler);
                  finish = true;
                }
              }
              ref.on('child_added', handler);
            });
          });
      },
      start: function () {
        return new Promise(function (resolve, reject) {
          var ref = firebaseSearch.ref;
          var started;
          firebaseSearch.algolia.handlers = {
            child_added: function (snap) {
              if (!started) { // Skip the first child_added event. It's often an existing record.
                started = true;
                resolve(snap.key);
              } else {
                var obj = snap.val();
                obj.objectID = snap.key;
                firebaseSearch.algolia.addObject(obj, true)
                  .then(function () {
                    // firebaseSearch.log('algolia_child_added', snap.key);
                    firebaseSearch.fire('algolia_child_added', obj);
                  });
              }
            },
            child_changed: function (snap) {
              var obj = snap.val();
              obj.objectID = snap.key;
              firebaseSearch.algolia.saveObject(obj, true)
                .then(function () {
                  // firebaseSearch.log('algolia_child_changed', snap.key);
                  firebaseSearch.fire('algolia_child_changed', obj);
                });
            },
            child_removed: function (snap) {
              firebaseSearch.algolia.deleteObject(snap.key, true)
                .then(function () {
                  // firebaseSearch.log('algolia_child_removed', snap.key);
                  firebaseSearch.fire('algolia_child_removed', snap.key);
                });
            }
          };
          firebaseSearch.algolia.listeningRefs = {
            child_added: ref.orderByKey().limitToLast(1),
            child_changed: ref,
            child_removed: ref
          };

          firebaseSearch.algolia.listeningRefs.child_added.once('value')
            .then(function (snap) {
              if (!snap.numChildren()) started = true, resolve(true);
              firebaseSearch.algolia.listeningRefs.child_added.on('child_added', firebaseSearch.algolia.handlers.child_added);
              firebaseSearch.algolia.listeningRefs.child_changed.on('child_changed', firebaseSearch.algolia.handlers.child_changed);
              firebaseSearch.algolia.listeningRefs.child_removed.on('child_removed', firebaseSearch.algolia.handlers.child_removed);
            });
        });
      },
      stop: function () {
        if (firebaseSearch.algolia.handlers && firebaseSearch.algolia.listeningRefs) {
          firebaseSearch.algolia.listeningRefs.child_added.off('child_added', firebaseSearch.algolia.handlers.child_added);
          firebaseSearch.algolia.listeningRefs.child_changed.off('child_changed', firebaseSearch.algolia.handlers.child_changed);
          firebaseSearch.algolia.listeningRefs.child_removed.off('child_removed', firebaseSearch.algolia.handlers.child_removed);
        } else {
          firebaseSearch.log('Firebase algolia listeners not started.');
        }
      }
    }
  };
};
<|endoftext|>


<commit_before>module.exports = [
	{
		id: 'global--admin-bar',
		kind: 'Global',
		name: 'Admin Bar',
		story: 'Admin Bar',
		parameters: {
			fileName: './stories/adminbar.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-data-block',
			},
		},
	},
	{
		id: 'global--buttons',
		kind: 'Global',
		name: 'Buttons',
		story: 'Buttons',
		parameters: {
			fileName: './stories/buttons.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				hoverSelector: '.googlesitekit-button--hover',
				postInteractionWait: 3000,
				onReadyScript: 'mouse.js',
			},
		},
	},
	{
		id: 'dashboard--module-header',
		kind: 'Dashboard',
		name: 'Module Header',
		story: 'Module Header',
		parameters: {
			fileName: './stories/dashboard.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'dashboard--post-searcher',
		kind: 'Dashboard',
		name: 'Post Searcher',
		story: 'Post Searcher',
		parameters: {
			fileName: './stories/dashboard.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'dashboard--search-funnel-analytics-inactive',
		kind: 'Dashboard',
		name: 'Search Funnel Analytics Inactive',
		story: 'Search Funnel Analytics Inactive',
		parameters: {
			fileName: './stories/dashboard.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-chart-v2 .googlesitekit-chart-v2__inner',
			},
		},
	},
	{
		id: 'dashboard--search-funnel',
		kind: 'Dashboard',
		name: 'Search Funnel',
		story: 'Search Funnel',
		parameters: {
			fileName: './stories/dashboard.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-chart-v2 .googlesitekit-chart-v2__inner',
			},
		},
	},
	{
		id: 'global--data-table',
		kind: 'Global',
		name: 'Data Table',
		story: 'Data Table',
		parameters: {
			fileName: './stories/data-table.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-table-overflow',
				delay: 2000,
			},
		},
	},
	{
		id: 'global--plugin-header',
		kind: 'Global',
		name: 'Plugin Header',
		story: 'Plugin Header',
		parameters: {
			fileName: './stories/header.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 3000,
			},
		},
	},
	{
		id: 'global--plugin-header-with-date-selector',
		kind: 'Global',
		name: 'Plugin Header with Date Selector',
		story: 'Plugin Header with Date Selector',
		parameters: {
			fileName: './stories/header-date-selector.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 3000,
			},
		},
	},
	{
		id: 'global-layout--layout-with-header-footer-and-ctas',
		kind: 'Global/Layout',
		name: 'Layout with Header Footer and CTAs',
		story: 'Layout with Header Footer and CTAs',
		parameters: {
			fileName: './stories/layout.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-layout--layout-with-header-and-footer',
		kind: 'Global/Layout',
		name: 'Layout with Header and Footer',
		story: 'Layout with Header and Footer',
		parameters: {
			fileName: './stories/layout.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--links',
		kind: 'Global',
		name: 'Links',
		story: 'Links',
		parameters: {
			fileName: './stories/links.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				hoverSelector: '.googlesitekit-cta-link--hover',
				onReadyScript: 'mouse.js',
			},
		},
	},
	{
		id: 'global--modal-dialog',
		kind: 'Global',
		name: 'Modal Dialog',
		story: 'Modal Dialog',
		parameters: {
			fileName: './stories/modal-dialog.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 1000,
			},
		},
	},
	{
		id: 'adsense-module--performance',
		kind: 'AdSense Module',
		name: 'Performance',
		story: 'Performance',
		parameters: {
			fileName: './stories/module-adsense.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 1000,
			},
		},
	},
	{
		id: 'analytics-module--audience-overview-chart',
		kind: 'Analytics Module',
		name: 'Audience Overview Chart',
		story: 'Audience Overview Chart',
		parameters: {
			fileName: './stories/module-analytics.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-line-chart div[style="position: relative;"]',
			},
		},
	},
	{
		id: 'analytics-module--top-acquisition-pie-chart',
		kind: 'Analytics Module',
		name: 'Top Acquisition Pie Chart',
		story: 'Top Acquisition Pie Chart',
		parameters: {
			fileName: './stories/module-analytics.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-line-chart div[style="position: relative;"]',
			},
		},
	},
	{
		id: 'search-console-module--overview-chart',
		kind: 'Search Console Module',
		name: 'Overview Chart',
		story: 'Overview Chart',
		parameters: {
			fileName: './stories/module-search-console.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-line-chart div[style="position: relative;"]',
			},
		},
	},
	{
		id: 'global-notifications--module-setup-complete',
		kind: 'Global/Notifications',
		name: 'Module Setup Complete',
		story: 'Module Setup Complete',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-notifications--small-with-image',
		kind: 'Global/Notifications',
		name: 'Small with Image',
		story: 'Small with Image',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-notifications--small-with-no-image',
		kind: 'Global/Notifications',
		name: 'Small with No Image',
		story: 'Small with No Image',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-notifications--small-with-error',
		kind: 'Global/Notifications',
		name: 'Small with Error',
		story: 'Small with Error',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-notifications--small-with-warning',
		kind: 'Global/Notifications',
		name: 'Small with Warning',
		story: 'Small with Warning',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-notifications--user-input-success-notification',
		kind: 'Global/Notifications',
		name: 'User Input Success Notification',
		story: 'User Input Success Notification',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--page-headers',
		kind: 'Global',
		name: 'Page Headers',
		story: 'Page Headers',
		parameters: {
			fileName: './stories/page-header.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--progress-bars',
		kind: 'Global',
		name: 'Progress Bars',
		story: 'Progress Bars',
		parameters: {
			fileName: './stories/progress-bars.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				misMatchThreshold: 10,
			},
		},
	},
	{
		id: 'global--radios',
		kind: 'Global',
		name: 'Radios',
		story: 'Radios',
		parameters: {
			fileName: './stories/radio.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--selects',
		kind: 'Global',
		name: 'Selects',
		story: 'Selects',
		parameters: {
			fileName: './stories/select.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 3000,
				clickSelector: '.googlesitekit-story-select-click',
				postInteractionWait: 3000,
				onReadyScript: 'mouse.js',
			},
		},
	},
	{
		id: 'settings--settings-tabs',
		kind: 'Settings',
		name: 'Settings Tabs',
		story: 'Settings Tabs',
		parameters: {
			fileName: './stories/settings.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 3000,
			},
		},
	},
	{
		id: 'settings--connected-services',
		kind: 'Settings',
		name: 'Connected Services',
		story: 'Connected Services',
		parameters: {
			fileName: './stories/settings.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 1000,
			},
		},
	},
	{
		id: 'settings--connect-more-services',
		kind: 'Settings',
		name: 'Connect More Services',
		story: 'Connect More Services',
		parameters: {
			fileName: './stories/settings.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'settings--admin-settings',
		kind: 'Settings',
		name: 'Admin Settings',
		story: 'Admin Settings',
		parameters: {
			fileName: './stories/settings.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'setup-using-gcp--step-one',
		kind: 'Setup / Using GCP',
		name: 'Step One',
		story: 'Step One',
		parameters: {
			fileName: './stories/setup.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--switches',
		kind: 'Global',
		name: 'Switches',
		story: 'Switches',
		parameters: {
			fileName: './stories/switch.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--text-fields',
		kind: 'Global',
		name: 'Text Fields',
		story: 'Text Fields',
		parameters: {
			fileName: './stories/text-field.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--visually-hidden',
		kind: 'Global',
		name: 'Visually Hidden',
		story: 'Visually Hidden',
		parameters: {
			fileName: './stories/visually-hidden.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'wordpress--wordpress-dashboard',
		kind: 'WordPress',
		name: 'WordPress Dashboard',
		story: 'WordPress Dashboard',
		parameters: {
			fileName: './stories/wp-dashboard.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-data-block',
				delay: 2000,
			},
		},
	},
];
<commit_msg>Re-introduce direct child selector in VRT tests.<commit_after>module.exports = [
	{
		id: 'global--admin-bar',
		kind: 'Global',
		name: 'Admin Bar',
		story: 'Admin Bar',
		parameters: {
			fileName: './stories/adminbar.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-data-block',
			},
		},
	},
	{
		id: 'global--buttons',
		kind: 'Global',
		name: 'Buttons',
		story: 'Buttons',
		parameters: {
			fileName: './stories/buttons.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				hoverSelector: '.googlesitekit-button--hover',
				postInteractionWait: 3000,
				onReadyScript: 'mouse.js',
			},
		},
	},
	{
		id: 'dashboard--module-header',
		kind: 'Dashboard',
		name: 'Module Header',
		story: 'Module Header',
		parameters: {
			fileName: './stories/dashboard.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'dashboard--post-searcher',
		kind: 'Dashboard',
		name: 'Post Searcher',
		story: 'Post Searcher',
		parameters: {
			fileName: './stories/dashboard.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'dashboard--search-funnel-analytics-inactive',
		kind: 'Dashboard',
		name: 'Search Funnel Analytics Inactive',
		story: 'Search Funnel Analytics Inactive',
		parameters: {
			fileName: './stories/dashboard.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-chart-v2 .googlesitekit-chart-v2__inner',
			},
		},
	},
	{
		id: 'dashboard--search-funnel',
		kind: 'Dashboard',
		name: 'Search Funnel',
		story: 'Search Funnel',
		parameters: {
			fileName: './stories/dashboard.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-chart-v2 .googlesitekit-chart-v2__inner',
			},
		},
	},
	{
		id: 'global--data-table',
		kind: 'Global',
		name: 'Data Table',
		story: 'Data Table',
		parameters: {
			fileName: './stories/data-table.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-table-overflow',
				delay: 2000,
			},
		},
	},
	{
		id: 'global--plugin-header',
		kind: 'Global',
		name: 'Plugin Header',
		story: 'Plugin Header',
		parameters: {
			fileName: './stories/header.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 3000,
			},
		},
	},
	{
		id: 'global--plugin-header-with-date-selector',
		kind: 'Global',
		name: 'Plugin Header with Date Selector',
		story: 'Plugin Header with Date Selector',
		parameters: {
			fileName: './stories/header-date-selector.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 3000,
			},
		},
	},
	{
		id: 'global-layout--layout-with-header-footer-and-ctas',
		kind: 'Global/Layout',
		name: 'Layout with Header Footer and CTAs',
		story: 'Layout with Header Footer and CTAs',
		parameters: {
			fileName: './stories/layout.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-layout--layout-with-header-and-footer',
		kind: 'Global/Layout',
		name: 'Layout with Header and Footer',
		story: 'Layout with Header and Footer',
		parameters: {
			fileName: './stories/layout.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--links',
		kind: 'Global',
		name: 'Links',
		story: 'Links',
		parameters: {
			fileName: './stories/links.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				hoverSelector: '.googlesitekit-cta-link--hover',
				onReadyScript: 'mouse.js',
			},
		},
	},
	{
		id: 'global--modal-dialog',
		kind: 'Global',
		name: 'Modal Dialog',
		story: 'Modal Dialog',
		parameters: {
			fileName: './stories/modal-dialog.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 1000,
			},
		},
	},
	{
		id: 'adsense-module--performance',
		kind: 'AdSense Module',
		name: 'Performance',
		story: 'Performance',
		parameters: {
			fileName: './stories/module-adsense.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 1000,
			},
		},
	},
	{
		id: 'analytics-module--audience-overview-chart',
		kind: 'Analytics Module',
		name: 'Audience Overview Chart',
		story: 'Audience Overview Chart',
		parameters: {
			fileName: './stories/module-analytics.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-line-chart > div[style="position: relative;"]',
			},
		},
	},
	{
		id: 'analytics-module--top-acquisition-pie-chart',
		kind: 'Analytics Module',
		name: 'Top Acquisition Pie Chart',
		story: 'Top Acquisition Pie Chart',
		parameters: {
			fileName: './stories/module-analytics.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-line-chart > div[style="position: relative;"]',
			},
		},
	},
	{
		id: 'search-console-module--overview-chart',
		kind: 'Search Console Module',
		name: 'Overview Chart',
		story: 'Overview Chart',
		parameters: {
			fileName: './stories/module-search-console.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-line-chart > div[style="position: relative;"]',
			},
		},
	},
	{
		id: 'global-notifications--module-setup-complete',
		kind: 'Global/Notifications',
		name: 'Module Setup Complete',
		story: 'Module Setup Complete',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-notifications--small-with-image',
		kind: 'Global/Notifications',
		name: 'Small with Image',
		story: 'Small with Image',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-notifications--small-with-no-image',
		kind: 'Global/Notifications',
		name: 'Small with No Image',
		story: 'Small with No Image',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-notifications--small-with-error',
		kind: 'Global/Notifications',
		name: 'Small with Error',
		story: 'Small with Error',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-notifications--small-with-warning',
		kind: 'Global/Notifications',
		name: 'Small with Warning',
		story: 'Small with Warning',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global-notifications--user-input-success-notification',
		kind: 'Global/Notifications',
		name: 'User Input Success Notification',
		story: 'User Input Success Notification',
		parameters: {
			fileName: './stories/notifications.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--page-headers',
		kind: 'Global',
		name: 'Page Headers',
		story: 'Page Headers',
		parameters: {
			fileName: './stories/page-header.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--progress-bars',
		kind: 'Global',
		name: 'Progress Bars',
		story: 'Progress Bars',
		parameters: {
			fileName: './stories/progress-bars.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				misMatchThreshold: 10,
			},
		},
	},
	{
		id: 'global--radios',
		kind: 'Global',
		name: 'Radios',
		story: 'Radios',
		parameters: {
			fileName: './stories/radio.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--selects',
		kind: 'Global',
		name: 'Selects',
		story: 'Selects',
		parameters: {
			fileName: './stories/select.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 3000,
				clickSelector: '.googlesitekit-story-select-click',
				postInteractionWait: 3000,
				onReadyScript: 'mouse.js',
			},
		},
	},
	{
		id: 'settings--settings-tabs',
		kind: 'Settings',
		name: 'Settings Tabs',
		story: 'Settings Tabs',
		parameters: {
			fileName: './stories/settings.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 3000,
			},
		},
	},
	{
		id: 'settings--connected-services',
		kind: 'Settings',
		name: 'Connected Services',
		story: 'Connected Services',
		parameters: {
			fileName: './stories/settings.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				delay: 1000,
			},
		},
	},
	{
		id: 'settings--connect-more-services',
		kind: 'Settings',
		name: 'Connect More Services',
		story: 'Connect More Services',
		parameters: {
			fileName: './stories/settings.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'settings--admin-settings',
		kind: 'Settings',
		name: 'Admin Settings',
		story: 'Admin Settings',
		parameters: {
			fileName: './stories/settings.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'setup-using-gcp--step-one',
		kind: 'Setup / Using GCP',
		name: 'Step One',
		story: 'Step One',
		parameters: {
			fileName: './stories/setup.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--switches',
		kind: 'Global',
		name: 'Switches',
		story: 'Switches',
		parameters: {
			fileName: './stories/switch.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--text-fields',
		kind: 'Global',
		name: 'Text Fields',
		story: 'Text Fields',
		parameters: {
			fileName: './stories/text-field.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'global--visually-hidden',
		kind: 'Global',
		name: 'Visually Hidden',
		story: 'Visually Hidden',
		parameters: {
			fileName: './stories/visually-hidden.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
			},
		},
	},
	{
		id: 'wordpress--wordpress-dashboard',
		kind: 'WordPress',
		name: 'WordPress Dashboard',
		story: 'WordPress Dashboard',
		parameters: {
			fileName: './stories/wp-dashboard.stories.js',
			options: {
				hierarchyRootSeparator: '|',
				hierarchySeparator: {},
				readySelector: '.googlesitekit-data-block',
				delay: 2000,
			},
		},
	},
];
<|endoftext|>


<commit_before>(function() {
    function trackTaskCompletion(needID, format) {
        if (format == "guide") {
            trackGuideFormatSuccess(needID);
        }
    }

    function trackFormatEntry(needID, format)
    {
        _gaq.push(['_trackEvent', 'MS_'+format, needID, 'Entry']);
    }

    function trackGuideFormatSuccess(needID)
    {
        var success = { "success": false };
        setTimeout(function() {
            onSuccess(success, needID);
        }, 7000);
        $("#content a").click(function() {
            onSuccess(success, needID);
            try {
                setTimeout('document.location = "' + $(this).attr("href") + '"', 50)
            }catch(err){}
            return false;
        });
    }

    function onSuccess(dict, needID) {
        if (dict.success) {
            return;
        }
        dict.success = true;
        _gaq.push(['_trackEvent', 'MS_guide', needID, 'Success']);
    }

    function userCameFromThePageWithinTheSameArtefact() {
        var artefactURL = document.URL.split('/').slice(0,4).join('/');
        return (document.referrer.indexOf(artefactURL) == 0);
    }

    // Track format entry before DOM ready
    var userFromSameArtefact = userCameFromThePageWithinTheSameArtefact();
    if (!userFromSameArtefact) {
        trackFormatEntry(GOVUK.Analytics.NeedID, GOVUK.Analytics.Format);
    }

    // Track format success on DOM ready
    $(function() {
        if (!userFromSameArtefact) {
            trackTaskCompletion(GOVUK.Analytics.NeedID, GOVUK.Analytics.Format);
        }

    });
})();
<commit_msg>Prevent analytics from breaking guides link events<commit_after>(function() {
    function trackTaskCompletion(needID, format) {
        if (format == "guide") {
            trackGuideFormatSuccess(needID);
        }
    }

    function trackFormatEntry(needID, format)
    {
        _gaq.push(['_trackEvent', 'MS_'+format, needID, 'Entry']);
    }

    function trackGuideFormatSuccess(needID)
    {
        var success = { "success": false };
        setTimeout(function() {
            onSuccess(success, needID);
        }, 7000);
        $("#content a").click(function() {
            onSuccess(success, needID);
            if ($(this).data('events').click.length === 0) {
              return true;
            }
        });
    }

    function onSuccess(dict, needID) {
        if (dict.success) {
            return;
        }
        dict.success = true;
        _gaq.push(['_trackEvent', 'MS_guide', needID, 'Success']);
    }

    function userCameFromThePageWithinTheSameArtefact() {
        var artefactURL = document.URL.split('/').slice(0,4).join('/');
        return (document.referrer.indexOf(artefactURL) == 0);
    }

    // Track format entry before DOM ready
    var userFromSameArtefact = userCameFromThePageWithinTheSameArtefact();
    if (!userFromSameArtefact) {
        trackFormatEntry(GOVUK.Analytics.NeedID, GOVUK.Analytics.Format);
    }

    // Track format success on DOM ready
    $(function() {
        if (!userFromSameArtefact) {
            trackTaskCompletion(GOVUK.Analytics.NeedID, GOVUK.Analytics.Format);
        }

    });
})();
<|endoftext|>


<commit_before>// load the default config generator.
var genDefaultConfig = require('@kadira/storybook/dist/server/config/defaults/webpack.config.js');

module.exports = function(config, env) {
  var config = genDefaultConfig(config, env);

  // Extend it as you need.
  config.resolve.alias['react-native'] = 'react-native-web'

  return config;
};
<commit_msg>add __DEV__ to storybook's webpack<commit_after>// load the default config generator.
var webpack = require('webpack')
var genDefaultConfig = require('@kadira/storybook/dist/server/config/defaults/webpack.config.js');

module.exports = function(config, env) {
  var config = genDefaultConfig(config, env);

  // Extend it as you need.
  config.resolve.alias['react-native'] = 'react-native-web'

  config.plugins.push(
    new webpack.DefinePlugin({
        __DEV__: true
        // __PROD__: env.prod || false,

        // Note: `process.env.NODE_ENV` is automatically set with `webpack -p`
        //       which is needed for build React in prod mode
      })
  )

  return config;
};
<|endoftext|>


<commit_before>/*
 *= require         'jquery'
 *= require         'jquery_ujs'
 *= require         'underscore'
 *= require         'backbone'
 *= require         'swfobject'
 *= require         'jquery.uploadify'
 *= require_self
 *= require_tree    ./crowdblog/models
 *= require_tree    ./crowdblog/views
 *= require_tree    ./crowdblog/templates
 *= require         ./crowdblog/posts_main
 *= require         ./crowdblog/xhr_fix
 */

window.PostsApp = {};
<commit_msg>Load markdown.js in the asset pipeline<commit_after>/*
 *= require         'jquery'
 *= require         'jquery_ujs'
 *= require         'underscore'
 *= require         'backbone'
 *= require         'swfobject'
 *= require         'jquery.uploadify'
 *= require         'markdown'
 *= require_self
 *= require_tree    ./crowdblog/models
 *= require_tree    ./crowdblog/views
 *= require_tree    ./crowdblog/templates
 *= require         ./crowdblog/posts_main
 *= require         ./crowdblog/xhr_fix
 */

window.PostsApp = {};
<|endoftext|>