<commit_before>/**
 * @fileOverview reading_process.js manages the process of reading content
 * injected into host pages. The process is as follows:
 *
 * 1. The manifest.json file injects a content script, privly.js, into every
 *    websites the user visits, including iframes.
 * 2. This background script messages the privly.js content script the user's
 *    whitelist. This whitelist defines domains the user trust in addition to
 *    the default white list. see: readingProcess.updateContentScriptWhitelist()
 * 3. This background script checks the state of the modal button, and turns
 *    on the privly.js content script if the modal button is on. This
 *    background script also defines a click listener on the modal button,
 *    that will start or stop the content scripts depending on the new state
 *    of the button. see: readingProcess.tabChange()
 * 4. The content script, privly.js, discovers whitelisted links or
 *    clicks on a passive link, then it requests a source URL from the
 *    extension using the message interface. The source URL
 *    will be assigned to the URL returned by
 *    readingProcess.getApplicationInjectionUrlResponse(). If the
 *    application behind the URL is known, the application will be served
 *    from local storage and not the remote content server.
 *
 **/

/**
 * @namespace For functionality related to reading content injected into
 * a host page.
 */
var readingProcess = {

  /**
   * If the content script has been injected, this will ask it to run.
   *
   * @param {tab} tabId The integer identifier of the tab to activate with
   * the content script.
   *
   * @see readingProcess.deactivateContentInjectionScript
   */
  activateContentInjectionScript: function (tabId) {
    chrome.tabs.executeScript(tabId, {
        code: "if(typeof privly != 'undefined'){privly.start();}",
        allFrames: true
    });
  },

  /**
   * If the content script has been injected, this will ask it to not run.
   *
   * @param {tab} tabId The integer identifier of the tab who needs to stop
   * running the content script.
   *
   * @see readingProcess.activateContentInjectionScript
   */
  deactivateContentInjectionScript: function(tabId) {
    chrome.tabs.executeScript(tabId, {
        code: "if(typeof privly != 'undefined'){privly.stop();}",
        allFrames: true
    });
  },

  /**
   * Notifies content script of additions to injection whitelist. This list is
   * assigned from the options page.
   *
   * @param {integer} tabId The integer identifier of the tab who needs to be told
   * the updated whitelist.
   *
   */
  updateContentScriptWhitelist: function(tabId) {
    var user_whitelist_regexp = localStorage["user_whitelist_regexp"];
    if (!user_whitelist_regexp) {
      return;
    }
    chrome.tabs.executeScript(tabId, {
        code: "if(typeof privly != 'undefined'){privly.updateWhitelist('"+user_whitelist_regexp+"');}",
        allFrames: true
    });
  },

  /**
   * Callback assigns content script state according to the modal button.
   *
   * @param {tab} tab The tab that
   * needs to be sent the operation mode and user's whitelist.
   */
  tabChange: function(tab) {

    if (tab.status !== "complete" ||
        tab.title === "New Tab" ||          // Solves hard to replicate error
        (tab.url.indexOf("http") !== 0 &&
         tab.url.indexOf("file") !== 0)) {
           return;
    }

    readingProcess.updateContentScriptWhitelist(tab.id);
    if( modalButton.badgeText === "off" ) {
      readingProcess.deactivateContentInjectionScript(tab.id);
    } else {
      readingProcess.activateContentInjectionScript(tab.id);
    }

  },

  /**
   * Helper for updating multiple tabs simultaneously. Relies on
   * the readingProcess.tabChange function.
   *
   * @param {[tab,...]} tabs The array of tabs that
   * needs to be sent the operation mode and user's whitelist.
   */
  tabsChange: function(tabs) {

    // Facilitate modifying an array of tabs by recursively
    // calling this function on every tab.
    if ( typeof tabs.length !== "undefined" ) {
      for( var i = 0; i < tabs.length; i++)
        readingProcess.tabChange(tabs[i]);
      return;
    }
  },

  /**
   * Gives the URL to inject an iframe from local storage if it is a known
   * application.
   *
   * @param {object} request The json request object sent by the content scrpt.
   * @param {object} sender The sender of the message.
   * @param {function} sendResponse The callback function of the message from
   * the content script.
   *
   */
  getApplicationInjectionUrlResponse: function(request, sender, sendResponse) {
    var url = request.privlyOriginalURL;
    var response = "";

    if( url.indexOf("privlyApp=Message") > 0 ) {
      response = chrome.extension.getURL(
                  "privly-applications/Message/show.html?privlyOriginalURL=");
    } else if( url.indexOf("privlyApp=ZeroBin") > 0) {
      // Deprecated
      response = chrome.extension.getURL(
                  "privly-applications/Message/show.html?privlyOriginalURL=");
    } else if( url.indexOf("privlyApp=PlainPost") > 0) {
      response = chrome.extension.getURL(
                  "privly-applications/PlainPost/show.html?privlyOriginalURL=");
    } else {
      console.warn("Injectable App not specified, defaulting to sanitized " +
                   "PlainPost: "+ request.privlyOriginalURL);
      response = chrome.extension.getURL(
                  "privly-applications/PlainPost/show.html?privlyOriginalURL=");
    }
    response += encodeURIComponent(url);
    sendResponse( {privlyApplicationURL: response} );
  },

  /**
   * Monitor tabs and messages to facilitate reading injected content.
   */
  addListeners: function() {

    // Message listeners are currently distinguised by whether they contain
    // the appropriate JSON in their request.
    chrome.extension.onMessage.addListener(
      function(request, sender, sendResponse) {
        if (request.privlyOriginalURL !== undefined) {
          return readingProcess.getApplicationInjectionUrlResponse(request, sender, sendResponse);
        }
      });

    // When the active tab changes we must update the tab's content script for
    // the current operation mode of the modal button.
    chrome.tabs.onActivated.addListener(function(activeInfo) {
      chrome.tabs.get(activeInfo.tabId, readingProcess.tabChange);
    });

    // Respond to every request to start the content script.
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        if (request.ask === "shouldStartPrivly?") {
          if(modalButton.badgeText !== "off") {
            sendResponse({tell: "yes"});
          }
        }
    });
  }
}

readingProcess.addListeners();
<commit_msg>update whitelist anytime the page changes<commit_after>/**
 * @fileOverview reading_process.js manages the process of reading content
 * injected into host pages. The process is as follows:
 *
 * 1. The manifest.json file injects a content script, privly.js, into every
 *    websites the user visits, including iframes.
 * 2. This background script messages the privly.js content script the user's
 *    whitelist. This whitelist defines domains the user trust in addition to
 *    the default white list. see: readingProcess.updateContentScriptWhitelist()
 * 3. This background script checks the state of the modal button, and turns
 *    on the privly.js content script if the modal button is on. This
 *    background script also defines a click listener on the modal button,
 *    that will start or stop the content scripts depending on the new state
 *    of the button. see: readingProcess.tabChange()
 * 4. The content script, privly.js, discovers whitelisted links or
 *    clicks on a passive link, then it requests a source URL from the
 *    extension using the message interface. The source URL
 *    will be assigned to the URL returned by
 *    readingProcess.getApplicationInjectionUrlResponse(). If the
 *    application behind the URL is known, the application will be served
 *    from local storage and not the remote content server.
 *
 **/

/**
 * @namespace For functionality related to reading content injected into
 * a host page.
 */
var readingProcess = {

  /**
   * If the content script has been injected, this will ask it to run.
   *
   * @param {tab} tabId The integer identifier of the tab to activate with
   * the content script.
   *
   * @see readingProcess.deactivateContentInjectionScript
   */
  activateContentInjectionScript: function (tabId) {
    chrome.tabs.executeScript(tabId, {
        code: "if(typeof privly != 'undefined'){privly.start();}",
        allFrames: true
    });
  },

  /**
   * If the content script has been injected, this will ask it to not run.
   *
   * @param {tab} tabId The integer identifier of the tab who needs to stop
   * running the content script.
   *
   * @see readingProcess.activateContentInjectionScript
   */
  deactivateContentInjectionScript: function(tabId) {
    chrome.tabs.executeScript(tabId, {
        code: "if(typeof privly != 'undefined'){privly.stop();}",
        allFrames: true
    });
  },

  /**
   * Notifies content script of additions to injection whitelist. This list is
   * assigned from the options page.
   *
   * @param {integer} tabId The integer identifier of the tab who needs to be told
   * the updated whitelist.
   *
   */
  updateContentScriptWhitelist: function(tabId) {
    var user_whitelist_regexp = ls.getItem("user_whitelist_regexp");
    if (!user_whitelist_regexp) {
      return;
    }
    chrome.tabs.executeScript(tabId, {
        code: "if(typeof privly != 'undefined'){privly.updateWhitelist('"+user_whitelist_regexp+"');}",
        allFrames: true
    });
  },

  /**
   * Callback assigns content script state according to the modal button.
   *
   * @param {tab} tab The tab that
   * needs to be sent the operation mode and user's whitelist.
   */
  tabChange: function(tab) {

    if (tab.status !== "complete" ||
        tab.title === "New Tab" ||          // Solves hard to replicate error
        (tab.url.indexOf("http") !== 0 &&
         tab.url.indexOf("file") !== 0)) {
           return;
    }

    readingProcess.updateContentScriptWhitelist(tab.id);
    if( modalButton.badgeText === "off" ) {
      readingProcess.deactivateContentInjectionScript(tab.id);
    } else {
      readingProcess.activateContentInjectionScript(tab.id);
    }

  },

  /**
   * Helper for updating multiple tabs simultaneously. Relies on
   * the readingProcess.tabChange function.
   *
   * @param {[tab,...]} tabs The array of tabs that
   * needs to be sent the operation mode and user's whitelist.
   */
  tabsChange: function(tabs) {

    // Facilitate modifying an array of tabs by recursively
    // calling this function on every tab.
    if ( typeof tabs.length !== "undefined" ) {
      for( var i = 0; i < tabs.length; i++)
        readingProcess.tabChange(tabs[i]);
      return;
    }
  },

  /**
   * Gives the URL to inject an iframe from local storage if it is a known
   * application.
   *
   * @param {object} request The json request object sent by the content scrpt.
   * @param {object} sender The sender of the message.
   * @param {function} sendResponse The callback function of the message from
   * the content script.
   *
   */
  getApplicationInjectionUrlResponse: function(request, sender, sendResponse) {
    var url = request.privlyOriginalURL;
    var response = "";

    if( url.indexOf("privlyApp=Message") > 0 ) {
      response = chrome.extension.getURL(
                  "privly-applications/Message/show.html?privlyOriginalURL=");
    } else if( url.indexOf("privlyApp=ZeroBin") > 0) {
      // Deprecated
      response = chrome.extension.getURL(
                  "privly-applications/Message/show.html?privlyOriginalURL=");
    } else if( url.indexOf("privlyApp=PlainPost") > 0) {
      response = chrome.extension.getURL(
                  "privly-applications/PlainPost/show.html?privlyOriginalURL=");
    } else {
      console.warn("Injectable App not specified, defaulting to sanitized " +
                   "PlainPost: "+ request.privlyOriginalURL);
      response = chrome.extension.getURL(
                  "privly-applications/PlainPost/show.html?privlyOriginalURL=");
    }
    response += encodeURIComponent(url);
    sendResponse( {privlyApplicationURL: response} );
  },

  /**
   * Monitor tabs and messages to facilitate reading injected content.
   */
  addListeners: function() {

    // Message listeners are currently distinguised by whether they contain
    // the appropriate JSON in their request.
    chrome.extension.onMessage.addListener(
      function(request, sender, sendResponse) {
        if (request.privlyOriginalURL !== undefined) {
          return readingProcess.getApplicationInjectionUrlResponse(request, sender, sendResponse);
        }
      });

    // When the active tab changes we must update the tab's content script for
    // the current operation mode of the modal button.
    chrome.tabs.onActivated.addListener(function(activeInfo) {
      chrome.tabs.get(activeInfo.tabId, readingProcess.tabChange);
    });
    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
      chrome.tabs.get(tabId, readingProcess.tabChange);
    });

    // Respond to every request to start the content script.
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        if (request.ask === "shouldStartPrivly?") {
          if(modalButton.badgeText !== "off") {
            sendResponse({tell: "yes"});
          }
        }
    });
  }
}

readingProcess.addListeners();
<|endoftext|>


<commit_before>Facet.render_buffer = function(opts)
{
    var ctx = Facet._globals.ctx;
    var frame_buffer = ctx.createFramebuffer();
    opts = _.defaults(opts || {}, {
        width: 512,
        height: 512,
        mag_filter: ctx.LINEAR,
        min_filter: ctx.LINEAR,
        wrap_s: ctx.CLAMP_TO_EDGE,
        wrap_t: ctx.CLAMP_TO_EDGE
    });

    // Weird:
    // http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf
    // Page 118
    //
    // Seems unenforced in my implementations of WebGL, even though
    // the WebGL spec defers to GLSL ES spec.
    //
    // if (opts.width != opts.height)
    //     throw "renderbuffers must be square (blame GLSL ES!)";

    var rttTexture = Facet.texture(opts);

    frame_buffer.init = function(width, height) {
        Facet.set_context(ctx);
        this.width  = opts.width;
        this.height = opts.height;
        ctx.bindFramebuffer(ctx.FRAMEBUFFER, this);
        var renderbuffer = ctx.createRenderbuffer();
        ctx.bindRenderbuffer(ctx.RENDERBUFFER, renderbuffer);
        ctx.renderbufferStorage(ctx.RENDERBUFFER, ctx.DEPTH_COMPONENT16, this.width, this.height);

        ctx.framebufferTexture2D(ctx.FRAMEBUFFER, ctx.COLOR_ATTACHMENT0, ctx.TEXTURE_2D, rttTexture, 0);
        ctx.framebufferRenderbuffer(ctx.FRAMEBUFFER, ctx.DEPTH_ATTACHMENT, ctx.RENDERBUFFER, renderbuffer);
        var status = ctx.checkFramebufferStatus(ctx.FRAMEBUFFER);
        try {
            switch (status) {
            case ctx.FRAMEBUFFER_COMPLETE:
                break;
            case ctx.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
                throw "incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
            case ctx.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
                throw "incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
            case ctx.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
                throw "incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
            case ctx.FRAMEBUFFER_UNSUPPORTED:
                throw "incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED";
            default:
                throw "incomplete framebuffer: " + status;
            }
        } finally {
            ctx.bindTexture(ctx.TEXTURE_2D, null);
            ctx.bindRenderbuffer(ctx.RENDERBUFFER, null);
            ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
        }
    };

    frame_buffer.init(opts.width, opts.height);
    frame_buffer._shade_type = 'render_buffer';
    frame_buffer.texture = rttTexture;
    frame_buffer.resize = function(width, height) {
        opts.width = width;
        opts.height = height;
        this.texture.init(opts);
        this.init(width, height);
    };
    frame_buffer.with_bound_buffer = function(what) {
        try {
            ctx.bindFramebuffer(ctx.FRAMEBUFFER, this);
            ctx.viewport(0, 0, this.width, this.height);
            return what();
        } finally {
            ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
        }
    };
    frame_buffer.make_screen_batch = function(with_texel_at_uv) {
        var sq = Facet.Models.square();
        return Facet.bake(sq, {
            position: sq.vertex.mul(2).sub(1),
            color: with_texel_at_uv(Shade.texture2D(this.texture, sq.tex_coord), sq.tex_coord)
        });
    };
    return frame_buffer;
};
<commit_msg>make_screen_batch takes drawing mode as an option<commit_after>Facet.render_buffer = function(opts)
{
    var ctx = Facet._globals.ctx;
    var frame_buffer = ctx.createFramebuffer();
    opts = _.defaults(opts || {}, {
        width: 512,
        height: 512,
        mag_filter: ctx.LINEAR,
        min_filter: ctx.LINEAR,
        wrap_s: ctx.CLAMP_TO_EDGE,
        wrap_t: ctx.CLAMP_TO_EDGE
    });

    // Weird:
    // http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf
    // Page 118
    //
    // Seems unenforced in my implementations of WebGL, even though
    // the WebGL spec defers to GLSL ES spec.
    //
    // if (opts.width != opts.height)
    //     throw "renderbuffers must be square (blame GLSL ES!)";

    var rttTexture = Facet.texture(opts);

    frame_buffer.init = function(width, height) {
        Facet.set_context(ctx);
        this.width  = opts.width;
        this.height = opts.height;
        ctx.bindFramebuffer(ctx.FRAMEBUFFER, this);
        var renderbuffer = ctx.createRenderbuffer();
        ctx.bindRenderbuffer(ctx.RENDERBUFFER, renderbuffer);
        ctx.renderbufferStorage(ctx.RENDERBUFFER, ctx.DEPTH_COMPONENT16, this.width, this.height);

        ctx.framebufferTexture2D(ctx.FRAMEBUFFER, ctx.COLOR_ATTACHMENT0, ctx.TEXTURE_2D, rttTexture, 0);
        ctx.framebufferRenderbuffer(ctx.FRAMEBUFFER, ctx.DEPTH_ATTACHMENT, ctx.RENDERBUFFER, renderbuffer);
        var status = ctx.checkFramebufferStatus(ctx.FRAMEBUFFER);
        try {
            switch (status) {
            case ctx.FRAMEBUFFER_COMPLETE:
                break;
            case ctx.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
                throw "incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
            case ctx.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
                throw "incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
            case ctx.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
                throw "incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
            case ctx.FRAMEBUFFER_UNSUPPORTED:
                throw "incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED";
            default:
                throw "incomplete framebuffer: " + status;
            }
        } finally {
            ctx.bindTexture(ctx.TEXTURE_2D, null);
            ctx.bindRenderbuffer(ctx.RENDERBUFFER, null);
            ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
        }
    };

    frame_buffer.init(opts.width, opts.height);
    frame_buffer._shade_type = 'render_buffer';
    frame_buffer.texture = rttTexture;
    frame_buffer.resize = function(width, height) {
        opts.width = width;
        opts.height = height;
        this.texture.init(opts);
        this.init(width, height);
    };
    frame_buffer.with_bound_buffer = function(what) {
        try {
            ctx.bindFramebuffer(ctx.FRAMEBUFFER, this);
            ctx.viewport(0, 0, this.width, this.height);
            return what();
        } finally {
            ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
        }
    };
    frame_buffer.make_screen_batch = function(with_texel_at_uv, mode) {
        mode = mode || Facet.DrawingMode.standard;
        var sq = Facet.Models.square();
        return Facet.bake(sq, {
            position: sq.vertex.mul(2).sub(1),
            color: with_texel_at_uv(Shade.texture2D(this.texture, sq.tex_coord), sq.tex_coord),
            mode: mode
        });
    };
    return frame_buffer;
};
<|endoftext|>


<commit_before>angular.module('records-module', ['ui.bootstrap','bootstrap-modal','school-year','pnotify-module','block-ui','window-open-post','module-access']).factory('records', function($http,$timeout,$compile,bootstrapModal,schoolYear,pnotify,blockUI,printPost,access) {

	function records() {

		var self = this;

		self.data = function(scope) {

			scope.views.records = {};

			scope.data.record = {};
			scope.data.record.id = 0;
			scope.data.records = [];

			scope.pagination.records = {};

			scope.views.record_panel_title = '';

			schoolYear.get(scope);
			schoolYear.current(scope);

		};

		function validate(scope) {

			var controls = scope.formHolder.record.$$controls;

			angular.forEach(controls,function(elem,i) {

				if (elem.$$attr.$attr.required) scope.$apply(function() { elem.$touched = elem.$invalid; });

			});

			return scope.formHolder.record.$invalid;

		};

		self.list = function(scope,opt) {

			scope.views.records.list = false;

			scope.data.record = {};
			scope.data.record.id = 0;

			scope.pagination.records.currentPage = 1;
			scope.pagination.records.pageSize = 15;
			scope.pagination.records.maxSize = 5;

			$http({
			  method: 'POST',
			  url: 'handlers/student-records-list.php',
			  data: {id: scope.student_id}
			}).then(function mySucces(response) {

				angular.copy(response.data, scope.data.records);
				scope.pagination.records.filterData = scope.data.records;
				$timeout(function() { scope.$apply(); }, 500);

			}, function myError(response) {

			  // error

			});

			if (opt) {
				$('#x_content_records').html('Loading...');
				$('#x_content_records').load('lists/student-records.html',function() {
					$compile($('#x_content_records')[0])(scope);
				});
			};

		};

		self.record = function(scope,record) {

			if (row != null) {
				if (!access.has(scope,scope.module.id,scope.module.privileges.view_record)) return;
			} else {
				if (!access.has(scope,scope.module.id,scope.module.privileges.add_record)) return;
			};

			var title = 'Add Record';

			if (record == null) {
				scope.data.record = {};
				scope.data.record.id = 0;
				scope.data.record.student_id = scope.student_id;
				scope.data.record.record_sy = scope.current_sy;
			} else {
				scope.data.record = angular.copy(record);
				title = 'Edit Record Info';
			};

			var content = 'dialogs/student-record.html';

			bootstrapModal.box(scope,title,content,self.save);

		};

		self.save = function(scope) {

			if (scope.data.record.id > 0) {
				if (!access.has(scope,scope.module.id,scope.module.privileges.update_record)) return false;
			};

			if (validate(scope)) return false;

			$http({
			  method: 'POST',
			  url: 'handlers/student-record-save.php',
			  data: scope.data.record
			}).then(function mySucces(response) {

				self.list(scope,false);

			}, function myError(response) {

			  // error

			});

			return true;

		};

		self.delete = function(scope,row) {

			if (!access.has(scope,scope.module.id,scope.module.privileges.delete_record)) return;

			var onOk = function() {

				$http({
				  method: 'POST',
				  url: 'handlers/student-record-delete.php',
				  data: {id: [row.id]}
				}).then(function mySucces(response) {

					self.list(scope,false);

				}, function myError(response) {

				  // error

				});

			};

			bootstrapModal.confirm(scope,'Confirmation','Are you sure you want to delete this record?',onOk,function() {});

		};

	};

	return new records();

});<commit_msg>student records fix<commit_after>angular.module('records-module', ['ui.bootstrap','bootstrap-modal','school-year','pnotify-module','block-ui','window-open-post','module-access']).factory('records', function($http,$timeout,$compile,bootstrapModal,schoolYear,pnotify,blockUI,printPost,access) {

	function records() {

		var self = this;

		self.data = function(scope) {

			scope.views.records = {};

			scope.data.record = {};
			scope.data.record.id = 0;
			scope.data.records = [];

			scope.pagination.records = {};

			scope.views.record_panel_title = '';

			schoolYear.get(scope);
			schoolYear.current(scope);

		};

		function validate(scope) {

			var controls = scope.formHolder.record.$$controls;

			angular.forEach(controls,function(elem,i) {

				if (elem.$$attr.$attr.required) scope.$apply(function() { elem.$touched = elem.$invalid; });

			});

			return scope.formHolder.record.$invalid;

		};

		self.list = function(scope,opt) {

			scope.views.records.list = false;

			scope.data.record = {};
			scope.data.record.id = 0;

			scope.pagination.records.currentPage = 1;
			scope.pagination.records.pageSize = 15;
			scope.pagination.records.maxSize = 5;

			$http({
			  method: 'POST',
			  url: 'handlers/student-records-list.php',
			  data: {id: scope.student_id}
			}).then(function mySucces(response) {

				angular.copy(response.data, scope.data.records);
				scope.pagination.records.filterData = scope.data.records;
				$timeout(function() { scope.$apply(); }, 500);

			}, function myError(response) {

			  // error

			});

			if (opt) {
				$('#x_content_records').html('Loading...');
				$('#x_content_records').load('lists/student-records.html',function() {
					$compile($('#x_content_records')[0])(scope);
				});
			};

		};

		self.record = function(scope,record) {

			if (record != null) {
				if (!access.has(scope,scope.module.id,scope.module.privileges.view_record)) return;
			} else {
				if (!access.has(scope,scope.module.id,scope.module.privileges.add_record)) return;
			};

			var title = 'Add Record';

			if (record == null) {
				scope.data.record = {};
				scope.data.record.id = 0;
				scope.data.record.student_id = scope.student_id;
				scope.data.record.record_sy = scope.current_sy;
			} else {
				scope.data.record = angular.copy(record);
				title = 'Edit Record Info';
			};

			var content = 'dialogs/student-record.html';

			bootstrapModal.box(scope,title,content,self.save);

		};

		self.save = function(scope) {

			if (scope.data.record.id > 0) {
				if (!access.has(scope,scope.module.id,scope.module.privileges.update_record)) return false;
			};

			if (validate(scope)) return false;

			$http({
			  method: 'POST',
			  url: 'handlers/student-record-save.php',
			  data: scope.data.record
			}).then(function mySucces(response) {

				self.list(scope,false);

			}, function myError(response) {

			  // error

			});

			return true;

		};

		self.delete = function(scope,row) {

			if (!access.has(scope,scope.module.id,scope.module.privileges.delete_record)) return;

			var onOk = function() {

				$http({
				  method: 'POST',
				  url: 'handlers/student-record-delete.php',
				  data: {id: [row.id]}
				}).then(function mySucces(response) {

					self.list(scope,false);

				}, function myError(response) {

				  // error

				});

			};

			bootstrapModal.confirm(scope,'Confirmation','Are you sure you want to delete this record?',onOk,function() {});

		};

	};

	return new records();

});<|endoftext|>


<commit_before>/** @jsx m */

"use strict";
require("./AboutPage.scss");

var _ = require("underscore");
var Layout = require("../layouts/FullLayout.js");
var OnUnload = require("../utils/OnUnload.js");

var AboutPage = {};

AboutPage.controller = function(options) {
  OnUnload(this);
  options = _.extend({id: "AboutPage"}, options);
  this.controllers.layout = new Layout.controller(options);
};

AboutPage.view = function(ctrl) {
  var content = (

About

        Independent verification is what makes science the most successful approach to understanding how our world works. In academic science, however, independent verification of empirical results is difficult and not rewarded. Curate Science is a tool to make it easier for researchers to independently verify each other's results and to award appropriate credit to individuals who engage in such activities.

        Independent verification is facilitated by enabling researchers to (1) link independent replications to original studies (& eventually linking conceptual replication studies meta-analytically), (2) curate available data/syntax to verify reproducibility of results within one’s web browser, and (3) evaluate the interpretation/validity of original and replication results in nuanced ways via in-line comments.

        Curate Science incentivizes independent verification by publicly recognizing user contributions on the homepage. Centralizing such activities further motivates independent verification because researchers get the satisfaction of knowing their contributions will benefit other researchers (e.g., once open data are curated, re-analyzing data from different theoretical perspectives is greatly facilitated).

        For more details about Curate Science, please click here.

  );

  return new Layout.view(ctrl.controllers.layout, content);
};

module.exports = AboutPage;
<commit_msg>Update AboutPage.js<commit_after>/** @jsx m */

"use strict";
require("./AboutPage.scss");

var _ = require("underscore");
var Layout = require("../layouts/FullLayout.js");
var OnUnload = require("../utils/OnUnload.js");

var AboutPage = {};

AboutPage.controller = function(options) {
  OnUnload(this);
  options = _.extend({id: "AboutPage"}, options);
  this.controllers.layout = new Layout.controller(options);
};

AboutPage.view = function(ctrl) {
  var content = (

About

        Independent verification is what makes science the most successful approach to understanding how our world works. In academic science, however, independent verification of empirical results is difficult and not rewarded. Curate Science is a tool to make it easier for researchers to independently verify each other’s results and to award appropriate credit to individuals who engage in such activities.

        Independent verification is facilitated by enabling researchers to (1) link independent replications to original studies (& eventually linking conceptual replication studies meta-analytically), (2) curate available data/syntax to verify reproducibility of results within one’s web browser, and (3) evaluate the interpretation/validity of original and replication results in nuanced ways via in-line comments.

        Curate Science incentivizes independent verification by publicly recognizing user contributions on the homepage. Centralizing such activities further motivates independent verification because researchers get the satisfaction of knowing their contributions will benefit other researchers (e.g., once open data are curated, re-analyzing data from different theoretical perspectives is greatly facilitated).

        For more details about Curate Science, please click here.

  );

  return new Layout.view(ctrl.controllers.layout, content);
};

module.exports = AboutPage;
<|endoftext|>


<commit_before>module.exports = function RequestPlugin (options={}) {
  var {request} = options

  return {
    name: 'RequestPlugin',
    plugContext
  }

  function plugContext (contextOptions) {
    request = contextOptions.request || request

    return {
      plugActionContext
    }

    function plugActionContext (actionContext) {
      actionContext.request = request
    }
  }
}
<commit_msg>use param destructuring<commit_after>module.exports = function RequestPlugin ({request}={}) {
  return {
    name: 'RequestPlugin',
    plugContext
  }

  function plugContext (contextOptions) {
    request = contextOptions.request || request

    return {
      plugActionContext
    }

    function plugActionContext (actionContext) {
      actionContext.request = request
    }
  }
}
<|endoftext|>


<commit_before>/**
* Module: Mortgage Calculation
*
* Description: This is an AngularJS module for calculating a mortgage loan
*/
(function () {
  // body..
  'use strict';

  /**
    * Config
    */
  var moduleName = 'dirMortgage';

  /**
    * Module
    */
  var module;
  try {
    module = angular.module(moduleName);
  } catch (err) {
    // named module doesn't exist, so create one
    module = angular.module(moduleName, ['ng']);
  }

  module.directive('dirMortgage', function ($parse, dirMortgageService, mortgageCalculator) {
    // Runs during compile
    return {
      restrict: 'AE',
      scope: true,
      replace: true,
      templateUrl: function(elem, attrs) {
        return attrs.dmTemplateUrl || dirMortgageService.getTemplatePath();
      },
      compile: function () {
        return function postCompile (scope, element, attrs) {
          var principal = $parse(attrs.dmPrincipalAmount)(scope) || attrs.dmPrincipalAmount || 0;
          scope.loan = {
            downPayment: 0,
            principal:  parseFloat(principal) || dirMortgageService.getDefaultPrincipalAmount(),
            years: parseFloat(attrs.dmMinYear) || dirMortgageService.getMinYear(),
            months: (dirMortgageService.getMinYear() * 12),
            rate: parseFloat(attrs.dmDefaultRate) || dirMortgageService.getDefaultRate(),
            startDate: new Date(),
            monthlyPayments: 0,
            payOffDate: ''
          };
          scope.defaults = {
            minRate: parseFloat(attrs.dmMinRate) || dirMortgageService.getMinRate(),
            maxRate: parseFloat(attrs.dmMaxRate) || dirMortgageService.getMaxRate(),
            minYear: parseFloat(attrs.dmMinYear) || dirMortgageService.getMinYear(),
            maxYear: parseFloat(attrs.dmMaxYear) || dirMortgageService.getMaxYear(),
            stepRate: parseFloat(attrs.dmStepRate) || dirMortgageService.getStepRate(),
            stepYear: parseFloat(attrs.dmStepYear) || dirMortgageService.getStepYear(),
            currency: attrs.dmCurrency || dirMortgageService.getCurrency()
          };

          scope.$watch(function(){
            return scope.loan;
          }, function(nv){
            if(nv.years){
              scope.loan.months = parseFloat((nv.years * 12).toFixed(0));
            }
          }, true);

          scope.calculate = function () {
            mortgageCalculator.calculate(scope.loan);
          };
        }
      }
    };
  });

  module.service('mortgageCalculator', [function () {
    this.calculate = function (loan) {
      var principal;
      if (loan.downPayment && loan.principal > 0) {
        principal = (loan.principal - loan.downPayment);
      } else {
        principal = loan.principal;
      }
      var interestRatePerMonth = ((loan.rate / 100) / 12)
      var term = Math.pow((1 + interestRatePerMonth), loan.months);
      try {
        loan.monthlyPayments = (principal * ((interestRatePerMonth * term) / (term - 1)));
        this.overrideDate();
        loan.payOffDate = (new Date(loan.startDate).addMonths(loan.months))
      } catch (err) {
        throw 'Loan Calculation Exception: ' + err;
      }
    };
    this.overrideDate = function () {
      //to handle possible future edge cases, let's overridate with this functions
      //stripped and modified from datejs
      Date.isLeapYear = function (year) {
        return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
      };
      Date.getDaysInMonth = function (year, month) {
        return [31, (Date.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
      };
      Date.prototype.isLeapYear = function () {
        return Date.isLeapYear(this.getFullYear());
      };
      Date.prototype.getDaysInMonth = function() {
        return Date.getDaysInMonth(this.getFullYear(), this.getMonth());
      };
      Date.prototype.addMonths = function (value) {
        var n = this.getDate();
        this.setDate(1);
        this.setMonth(this.getMonth() + value);
        this.setDate(Math.min(n, this.getDaysInMonth()));
        return this;
      }
    };
  }]);

  module.provider('dirMortgageService', function () {
    var dirMortgageValues = {
      templatePath: 'scripts/modules/dirMortgage/templates/dirMortgage.tpl.html',
      minYear: 1,
      maxYear: 30,
      stepYear: 0.1,
      minRate: 0.5,
      maxRate: 10,
      stepRate: 0.1,
      defaultRate: 4.0,
      defaultPrincipalAmount: 0.0,
      currency: '$'
    };
    this.setPath = function (path) {
      dirMortgageValues.templatePath = path;
    };
    this.setMinYear = function (year) {
      dirMortgageValues.minYear = year;
    };
    this.setMaxYear = function (year) {
      dirMortgageValues.maxYear = year;
    };
    this.setStepYear = function (steps) {
      dirMortgageValues.stepYear = steps;
    };
    this.setMinRate = function (rate) {
      dirMortgageValues.minRate = rate;
    };
    this.setMaxRate = function (rate) {
      dirMortgageValues.maxRate = rate;
    };
    this.setStepRate = function (steps) {
      dirMortgageValues.stepRate = steps;
    };
    this.setDefaultRate = function (rate) {
      dirMortgageValues.defaultRate = rate;
    };
    this.setDefaultPrincipalAmount = function (amount) {
      dirMortgageValues.defaultPrincipalAmount = amount;
    };
    this.setCurrency = function (currency) {
      dirMortgageValues.currency = currency;
    };
    this.$get = function () {
      return {
        getTemplatePath: function () {
          return dirMortgageValues.templatePath;
        },
        getMinYear: function () {
          return dirMortgageValues.minYear;
        },
        getMaxYear: function () {
          return dirMortgageValues.maxYear;
        },
        getMinRate: function () {
          return dirMortgageValues.minRate;
        },
        getMaxRate: function () {
          return dirMortgageValues.maxRate;
        },
        getDefaultRate: function () {
          return dirMortgageValues.defaultRate;
        },
        getDefaultPrincipalAmount: function () {
          return parseFloat(dirMortgageValues.defaultPrincipalAmount);
        },
        getStepRate: function () {
          return dirMortgageValues.stepRate;
        },
        getStepYear: function () {
          return dirMortgageValues.stepYear;
        },
        getCurrency: function () {
          return dirMortgageValues.currency;
        }
      };
    };
  });

})();
<commit_msg>change function name<commit_after>/**
* Module: Mortgage Calculation
*
* Description: This is an AngularJS module for calculating a mortgage loan
*/
(function () {
  // body..
  'use strict';

  /**
    * Config
    */
  var moduleName = 'dirMortgage';

  /**
    * Module
    */
  var module;
  try {
    module = angular.module(moduleName);
  } catch (err) {
    // named module doesn't exist, so create one
    module = angular.module(moduleName, ['ng']);
  }

  module.directive('dirMortgage', function ($parse, dirMortgageService, mortgageCalculator) {
    // Runs during compile
    return {
      restrict: 'AE',
      scope: true,
      replace: true,
      templateUrl: function(elem, attrs) {
        return attrs.dmTemplateUrl || dirMortgageService.getTemplatePath();
      },
      compile: function () {
        return function postCompile (scope, element, attrs) {
          var principal = $parse(attrs.dmPrincipalAmount)(scope) || attrs.dmPrincipalAmount || 0;
          scope.loan = {
            downPayment: 0,
            principal:  parseFloat(principal) || dirMortgageService.getDefaultPrincipalAmount(),
            years: parseFloat(attrs.dmMinYear) || dirMortgageService.getMinYear(),
            months: (dirMortgageService.getMinYear() * 12),
            rate: parseFloat(attrs.dmDefaultRate) || dirMortgageService.getDefaultRate(),
            startDate: new Date(),
            monthlyPayments: 0,
            payOffDate: ''
          };
          scope.defaults = {
            minRate: parseFloat(attrs.dmMinRate) || dirMortgageService.getMinRate(),
            maxRate: parseFloat(attrs.dmMaxRate) || dirMortgageService.getMaxRate(),
            minYear: parseFloat(attrs.dmMinYear) || dirMortgageService.getMinYear(),
            maxYear: parseFloat(attrs.dmMaxYear) || dirMortgageService.getMaxYear(),
            stepRate: parseFloat(attrs.dmStepRate) || dirMortgageService.getStepRate(),
            stepYear: parseFloat(attrs.dmStepYear) || dirMortgageService.getStepYear(),
            currency: attrs.dmCurrency || dirMortgageService.getCurrency()
          };

          scope.$watch(function(){
            return scope.loan;
          }, function(nv){
            if(nv.years){
              scope.loan.months = parseFloat((nv.years * 12).toFixed(0));
            }
          }, true);

          scope.calculate = function () {
            mortgageCalculator.calculate(scope.loan);
          };
        }
      }
    };
  });

  module.service('mortgageCalculator', [function () {
    this.calculate = function (loan) {
      var principal;
      if (loan.downPayment && loan.principal > 0) {
        principal = (loan.principal - loan.downPayment);
      } else {
        principal = loan.principal;
      }
      var interestRatePerMonth = ((loan.rate / 100) / 12)
      var term = Math.pow((1 + interestRatePerMonth), loan.months);
      try {
        loan.monthlyPayments = (principal * ((interestRatePerMonth * term) / (term - 1)));
        this.overrideDate();
        loan.payOffDate = (new Date(loan.startDate).addMonths(loan.months))
      } catch (err) {
        throw 'Loan Calculation Exception: ' + err;
      }
    };
    this.overrideDate = function () {
      //to handle possible future edge cases, let's overridate with this functions
      //stripped and modified from datejs
      Date.isLeapYear = function (year) {
        return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
      };
      Date.getDaysInMonth = function (year, month) {
        return [31, (Date.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
      };
      Date.prototype.isLeapYear = function () {
        return Date.isLeapYear(this.getFullYear());
      };
      Date.prototype.getDaysInMonth = function() {
        return Date.getDaysInMonth(this.getFullYear(), this.getMonth());
      };
      Date.prototype.addMonths = function (value) {
        var n = this.getDate();
        this.setDate(1);
        this.setMonth(this.getMonth() + value);
        this.setDate(Math.min(n, this.getDaysInMonth()));
        return this;
      }
    };
  }]);

  module.provider('dirMortgageService', function () {
    var dirMortgageValues = {
      templatePath: 'scripts/modules/dirMortgage/templates/dirMortgage.tpl.html',
      minYear: 1,
      maxYear: 30,
      stepYear: 0.1,
      minRate: 0.5,
      maxRate: 10,
      stepRate: 0.1,
      defaultRate: 4.0,
      defaultPrincipalAmount: 0.0,
      currency: '$'
    };
    this.setTemplatePath = function (path) {
      dirMortgageValues.templatePath = path;
    };
    this.setMinYear = function (year) {
      dirMortgageValues.minYear = year;
    };
    this.setMaxYear = function (year) {
      dirMortgageValues.maxYear = year;
    };
    this.setStepYear = function (steps) {
      dirMortgageValues.stepYear = steps;
    };
    this.setMinRate = function (rate) {
      dirMortgageValues.minRate = rate;
    };
    this.setMaxRate = function (rate) {
      dirMortgageValues.maxRate = rate;
    };
    this.setStepRate = function (steps) {
      dirMortgageValues.stepRate = steps;
    };
    this.setDefaultRate = function (rate) {
      dirMortgageValues.defaultRate = rate;
    };
    this.setDefaultPrincipalAmount = function (amount) {
      dirMortgageValues.defaultPrincipalAmount = amount;
    };
    this.setCurrency = function (currency) {
      dirMortgageValues.currency = currency;
    };
    this.$get = function () {
      return {
        getTemplatePath: function () {
          return dirMortgageValues.templatePath;
        },
        getMinYear: function () {
          return dirMortgageValues.minYear;
        },
        getMaxYear: function () {
          return dirMortgageValues.maxYear;
        },
        getMinRate: function () {
          return dirMortgageValues.minRate;
        },
        getMaxRate: function () {
          return dirMortgageValues.maxRate;
        },
        getDefaultRate: function () {
          return dirMortgageValues.defaultRate;
        },
        getDefaultPrincipalAmount: function () {
          return parseFloat(dirMortgageValues.defaultPrincipalAmount);
        },
        getStepRate: function () {
          return dirMortgageValues.stepRate;
        },
        getStepYear: function () {
          return dirMortgageValues.stepYear;
        },
        getCurrency: function () {
          return dirMortgageValues.currency;
        }
      };
    };
  });

})();
<|endoftext|>


<commit_before>var $fh = require('fh-mbaas-api');
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');

function leadRoute() {
  var lead = new express.Router();
  lead.use(cors());
  lead.use(bodyParser());

  // POST REST endpoint - note we use 'body-parser' middleware above to parse the request body in this route.
  // This can also be added in application.js
  // See: https://github.com/senchalabs/connect#middleware for a list of Express 4 middleware
  lead.post('/', function(req, res) {

    // DEBUG-START
    /**
    console.log("##################");

    var options = {
      "act": "list",
      "type": "question", // Entity/Collection name
    };

    $fh.db(options, function (err, data) {
      if (err) {
        console.error("Error 1 " + err);
      } else {
        for (i = 0; i < data.list.length; i++) {
          console.log("Question id: " + data.list[i].guid);

            $fh.db({
                "act": "read",
                "type": "question",
                "guid": data.list[i].guid
              }, function (err, data) {
              if (err) {
                console.error("Error 2 " + err);
              } else {
                console.log(JSON.stringify(data));
              }
            });
        }
      }
    });
    console.log("##################");
    **/
    // DEBUG-END

    // check question
    var lottery = '0';
    var options = {
      "act": "read",
      "type": "question",
      "guid": req.body.answer.split(":")[0]
    };

    $fh.db(options, function (err, data) {
      if (err) {
        console.error("Error " + err);
      } else {
        console.log("Question: " + JSON.stringify(data));
        console.log("Correct Answr: " + data.fields.correct);
        console.log("User Asnwer: " + req.body.answer.split(":")[1]);
        console.log(req.body.answer.split(":")[1] == data.correct, typeof(data.fields.correct), typeof(req.body.answer.split(":")[1]));

        if (data.fields.correct == req.body.answer.split(":")[1]) {
          lottery = 1;
        }
      }
    });

    var options = {
      "act": "create",
      "type": "lead", // Entity/Collection name
      "fields": { // The structure of the entry/row data. A data is analogous to "Row" in MySql or "Documents" in MongoDB
        "name": req.body.name,
        "email": req.body.email,
        "company": req.body.company,
        "job": req.body.job,
        "lottery": lottery
      }
    };

    $fh.db(options, function (err, data) {
      if (err) {
        console.error("Error " + err);
        res.json({msg: err, status: 'error'});
      } else {
        res.json({msg: "Registered", status: 'success'});
      }
    });
  });

  return lead;
}

module.exports = leadRoute;

<commit_msg>updated<commit_after>var $fh = require('fh-mbaas-api');
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');

function leadRoute() {
  var lead = new express.Router();
  lead.use(cors());
  lead.use(bodyParser());

  // POST REST endpoint - note we use 'body-parser' middleware above to parse the request body in this route.
  // This can also be added in application.js
  // See: https://github.com/senchalabs/connect#middleware for a list of Express 4 middleware
  lead.post('/', function(req, res) {

    // DEBUG-START
    /**
    console.log("##################");

    var options = {
      "act": "list",
      "type": "question", // Entity/Collection name
    };

    $fh.db(options, function (err, data) {
      if (err) {
        console.error("Error 1 " + err);
      } else {
        for (i = 0; i < data.list.length; i++) {
          console.log("Question id: " + data.list[i].guid);

            $fh.db({
                "act": "read",
                "type": "question",
                "guid": data.list[i].guid
              }, function (err, data) {
              if (err) {
                console.error("Error 2 " + err);
              } else {
                console.log(JSON.stringify(data));
              }
            });
        }
      }
    });
    console.log("##################");
    **/
    // DEBUG-END

    // check question
    var lottery = '0';
    var options = {
      "act": "read",
      "type": "question",
      "guid": req.body.answer.split(":")[0]
    };

    $fh.db(options, function (err, data) {
      if (err) {
        console.error("Error " + err);
      } else {
        console.log("Question: " + JSON.stringify(data));
        console.log("Correct Answr: " + data.fields.correct);
        console.log("User Asnwer: " + req.body.answer.split(":")[1]);
        console.log(data.fields.correct.valueOf() == req.body.answer.split(":")[1].valueOf());

        if (data.fields.correct.valueOf() == req.body.answer.split(":")[1].valueOf()) {
          lottery = 1;
        }
      }
    });

    var options = {
      "act": "create",
      "type": "lead", // Entity/Collection name
      "fields": { // The structure of the entry/row data. A data is analogous to "Row" in MySql or "Documents" in MongoDB
        "name": req.body.name,
        "email": req.body.email,
        "company": req.body.company,
        "job": req.body.job,
        "lottery": lottery
      }
    };

    $fh.db(options, function (err, data) {
      if (err) {
        console.error("Error " + err);
        res.json({msg: err, status: 'error'});
      } else {
        res.json({msg: "Registered", status: 'success'});
      }
    });
  });

  return lead;
}

module.exports = leadRoute;

<|endoftext|>


<commit_before>import {exec, spawn} from 'child_process';
import fs from 'fs';
import os from 'os';
import log from 'loglevel';
import path from 'path';

const suffix = os.platform() === 'win32' ? '.exe' : '';

export class LocalGeth {
    constructor(bin, network, rpcPort) {
        this.bin = bin;
        this.network = network || 'morden';
        this.rpcPort = rpcPort || 8545;
    }

    launch() {
        return new Promise((resolve, reject) => {
            log.info("Starting Geth...");
            const bin = path.join(this.bin, 'geth' + suffix);
            fs.access(bin, fs.constants.X_OK, (err) => {
                if (err) {
                    log.error(`File ${bin} doesn't exist or app doesn't have execution flag`);
                    reject(err)
                } else {
                    let options = [
                        '--chain', this.network,
                        '--rpc',
                        '--rpc-port', this.rpcPort,
                        '--rpc-cors-domain', 'http://localhost:8000',
                        '--cache=32',
                    ];
                    this.proc = spawn(bin, options);
                    resolve(this.proc)
                }
            });
        })
    }

    shutdown() {
        log.info('Shutting down Local Geth');
        return new Promise((resolve, reject) => {
            if (!this.proc) {
                resolve('not_started');
                return;
            }
            this.proc.on('exit', () => {
                resolve('killed');
                this.proc = null;
            });
            this.proc.on('error', (err) => {
                log.error('Failed to shutdown Local Geth', err);
                reject(err);
            });
            this.proc.kill();
        });
    }

    getHost() {
        return '127.0.0.1';
    }

    getPort() {
        return this.rpcPort;
    }
}

export class RemoteGeth {
    constructor(host, port) {
        this.host = host;
        this.port = port;
    }

    getHost() {
        return this.host;
    }

    getPort() {
        return this.port;
    }
}

export class LocalConnector {

    constructor(bin, target) {
        this.bin = bin;
        this.target = target;
    }

    launch() {
        return new Promise((resolve, reject) => {
            log.info("Starting Emerald Connector...");
            const bin = path.join(this.bin, 'emerald-cli' + suffix);
            fs.access(bin, fs.constants.F_OK | fs.constants.R_OK | fs.constants.X_OK, (err) => {
                if (err) {
                    log.error(`File ${bin} doesn't exist or app doesn't have execution flag`);
                    reject(err)
                } else {
                    let options = [
                        '--client-host', this.target.getHost(),
                        '--client-port', this.target.getPort()
                    ];
                    this.proc = spawn(bin, options);
                    resolve(this.proc);
                }
            });
        })
    }

    shutdown() {
        log.info('Shutting down Local Connector');
        return new Promise((resolve, reject) => {
            if (!this.proc) {
                resolve('not_started');
                return;
            }
            this.proc.on('exit', () => {
                resolve('killed');
                this.proc = null;
            });
            this.proc.on('error', (err) => {
                log.error('Failed to shutdown Emerald Connector', err);
                reject(err);
            });
            this.proc.kill();
        });
    }
}
<commit_msg>problem: should add more cache and use --fast for geth<commit_after>import {exec, spawn} from 'child_process';
import fs from 'fs';
import os from 'os';
import log from 'loglevel';
import path from 'path';

const suffix = os.platform() === 'win32' ? '.exe' : '';

export class LocalGeth {
    constructor(bin, network, rpcPort) {
        this.bin = bin;
        this.network = network || 'morden';
        this.rpcPort = rpcPort || 8545;
    }

    launch() {
        return new Promise((resolve, reject) => {
            log.info("Starting Geth...");
            const bin = path.join(this.bin, 'geth' + suffix);
            fs.access(bin, fs.constants.X_OK, (err) => {
                if (err) {
                    log.error(`File ${bin} doesn't exist or app doesn't have execution flag`);
                    reject(err)
                } else {
                    let options = [
                        '--chain', this.network,
                        '--rpc',
                        '--rpc-port', this.rpcPort,
                        '--rpc-cors-domain', 'http://localhost:8000',
                        '--cache=128',
                        '--fast', // (auto-disables when at or upon reaching current bc height)
                    ];
                    this.proc = spawn(bin, options);
                    resolve(this.proc)
                }
            });
        })
    }

    shutdown() {
        log.info('Shutting down Local Geth');
        return new Promise((resolve, reject) => {
            if (!this.proc) {
                resolve('not_started');
                return;
            }
            this.proc.on('exit', () => {
                resolve('killed');
                this.proc = null;
            });
            this.proc.on('error', (err) => {
                log.error('Failed to shutdown Local Geth', err);
                reject(err);
            });
            this.proc.kill();
        });
    }

    getHost() {
        return '127.0.0.1';
    }

    getPort() {
        return this.rpcPort;
    }
}

export class RemoteGeth {
    constructor(host, port) {
        this.host = host;
        this.port = port;
    }

    getHost() {
        return this.host;
    }

    getPort() {
        return this.port;
    }
}

export class LocalConnector {

    constructor(bin, target) {
        this.bin = bin;
        this.target = target;
    }

    launch() {
        return new Promise((resolve, reject) => {
            log.info("Starting Emerald Connector...");
            const bin = path.join(this.bin, 'emerald-cli' + suffix);
            fs.access(bin, fs.constants.F_OK | fs.constants.R_OK | fs.constants.X_OK, (err) => {
                if (err) {
                    log.error(`File ${bin} doesn't exist or app doesn't have execution flag`);
                    reject(err)
                } else {
                    let options = [
                        '--client-host', this.target.getHost(),
                        '--client-port', this.target.getPort()
                    ];
                    this.proc = spawn(bin, options);
                    resolve(this.proc);
                }
            });
        })
    }

    shutdown() {
        log.info('Shutting down Local Connector');
        return new Promise((resolve, reject) => {
            if (!this.proc) {
                resolve('not_started');
                return;
            }
            this.proc.on('exit', () => {
                resolve('killed');
                this.proc = null;
            });
            this.proc.on('error', (err) => {
                log.error('Failed to shutdown Emerald Connector', err);
                reject(err);
            });
            this.proc.kill();
        });
    }
}
<|endoftext|>


<commit_before>var Node = require('./node');
var Sequence = require('./sequence');
var Load = require('./load');
var Parse = require('./parse');

module.exports = function Link (scope, event, options) {

    var node = Node();

    // load instance, parse event and get flow stream sequences
    Load(scope, node, event[0], options, function (instance) {
        Parse(scope, node, instance, event[1], options, function (parsed) {

            // pipe event transform streams
            parsed.s.forEach(function (sequence) {

                options._ = sequence.a || {};

                // create sequence transform
                if (sequence.s) {
                    node.join(Sequence(options, sequence.s));
                }

                // link to next node
                if (sequence.p) {

                    // pipe to flow event
                    if (typeof sequence.p[1] === 'string') {
                        node.join(sequence.p[0].flow(sequence.p[1], options));

                    // call stream handler
                    } else {
                        node.join(sequence.p[1].call(sequence.p[0], options, node._o || node._i));
                    }
                }
            });

            // end event
            if (parsed.e) {
                node.on('end', function () {
                    instance.inst.flow(parsed.e, options).end(event);

                    // end also error event
                    if (node._re) {
                        node._re.end();
                    }
                });
            }

            // error events
            if (parsed.r) {
                node.on('error', function (err) {
                    node._re = node._re || instance.inst.flow(parsed.r, options);
                    node._re.write(err);
                });

            // log error and prevent process crash
            } else if (node.listenerCount('error') < 1) {
                node.on('error', console.error.bind(console));
            }

            // link sequence to node
            node.link();
        });
    });

    return node;
};
<commit_msg>pass scope and node name to node constructor<commit_after>var Node = require('./node');
var Sequence = require('./sequence');
var Load = require('./load');
var Parse = require('./parse');

module.exports = function Link (scope, key, event, options) {

    var node = Node(scope, key);

    // load instance, parse event and get flow stream sequences
    Load(scope, node, event[0], options, function (instance) {
        Parse(scope, node, instance, event[1], options, function (parsed) {

            // pipe event transform streams
            parsed.s.forEach(function (sequence) {

                options._ = sequence.a || {};

                // create sequence transform
                if (sequence.s) {
                    node.join(Sequence(options, sequence.s));
                }

                // link to next node
                if (sequence.p) {

                    // pipe to flow event
                    if (typeof sequence.p[1] === 'string') {
                        node.join(sequence.p[0].flow(sequence.p[1], options));

                    // call stream handler
                    } else {
                        node.join(sequence.p[1].call(sequence.p[0], options, node._o || node._i));
                    }
                }
            });

            // end event
            if (parsed.e) {
                node.on('end', function () {
                    instance.inst.flow(parsed.e, options).end(event);

                    // end also error event
                    if (node._re) {
                        node._re.end();
                    }
                });
            }

            // error events
            if (parsed.r) {
                node.on('error', function (err) {
                    node._re = node._re || instance.inst.flow(parsed.r, options);
                    node._re.write(err);
                });

            // log error and prevent process crash
            } else if (node.listenerCount('error') < 1) {
                node.on('error', console.error.bind(console));
            }

            // link sequence to node
            node.link();
        });
    });

    return node;
};
<|endoftext|>


<commit_before>/* global __NEXT_DATA__ */

import { resolve, format, parse } from 'url'
import React, { Component, Children } from 'react'
import PropTypes from 'prop-types'
import exact from 'prop-types-exact'
import Router, { _rewriteUrlForNextExport } from './router'
import { warn, execOnce, getLocationOrigin } from './utils'

export default class Link extends Component {
  constructor (props, ...rest) {
    super(props, ...rest)
    this.linkClicked = this.linkClicked.bind(this)
    this.formatUrls(props)
  }

  static propTypes = exact({
    href: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
    as: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    prefetch: PropTypes.bool,
    replace: PropTypes.bool,
    shallow: PropTypes.bool,
    passHref: PropTypes.bool,
    children: PropTypes.oneOfType([
      PropTypes.element,
      (props, propName) => {
        const value = props[propName]

        if (typeof value === 'string') {
          warnLink(`Warning: You're using a string directly inside <Link>. This usage has been deprecated. Please add an <a> tag as child of <Link>`)
        }

        return null
      }
    ]).isRequired
  })

  componentWillReceiveProps (nextProps) {
    this.formatUrls(nextProps)
  }

  linkClicked (e) {
    if (e.currentTarget.nodeName === 'A' &&
      (e.metaKey || e.ctrlKey || e.shiftKey || (e.nativeEvent && e.nativeEvent.which === 2))) {
      // ignore click for new tab / new window behavior
      return
    }

    const { shallow } = this.props
    let { href, as } = this

    if (!isLocal(href)) {
      // ignore click if it's outside our scope
      return
    }

    const { pathname } = window.location
    href = resolve(pathname, href)
    as = as ? resolve(pathname, as) : href

    e.preventDefault()

    //  avoid scroll for urls with anchor refs
    let { scroll } = this.props
    if (scroll == null) {
      scroll = as.indexOf('#') < 0
    }

    // replace state instead of push if prop is present
    const { replace } = this.props
    const changeMethod = replace ? 'replace' : 'push'

    // straight up redirect
    Router[changeMethod](href, as, { shallow })
      .then((success) => {
        if (!success) return
        if (scroll) window.scrollTo(0, 0)
      })
      .catch((err) => {
        if (this.props.onError) this.props.onError(err)
      })
  }

  prefetch () {
    if (!this.props.prefetch) return
    if (typeof window === 'undefined') return

    // Prefetch the JSON page if asked (only in the client)
    const { pathname } = window.location
    const href = resolve(pathname, this.href)
    Router.prefetch(href)
  }

  componentDidMount () {
    this.prefetch()
  }

  componentDidUpdate (prevProps) {
    if (JSON.stringify(this.props.href) !== JSON.stringify(prevProps.href)) {
      this.prefetch()
    }
  }

  // We accept both 'href' and 'as' as objects which we can pass to `url.format`.
  // We'll handle it here.
  formatUrls (props) {
    this.href = props.href && typeof props.href === 'object'
      ? format(props.href)
      : props.href
    this.as = props.as && typeof props.as === 'object'
      ? format(props.as)
      : props.as
  }

  render () {
    let { children } = this.props
    let { href, as } = this
    // Deprecated. Warning shown by propType check. If the childen provided is a string (<Link>example</Link>) we wrap it in an  tag
    if (typeof children === 'string') {
      children = {children}
    }

    // This will return the first child, if multiple are provided it will throw an error
    const child = Children.only(children)
    const props = {
      onClick: this.linkClicked
    }

    // If child is an  tag and doesn't have a href attribute, or if the 'passHref' property is
    // defined, we specify the current 'href', so that repetition is not needed by the user
    if (this.props.passHref || (child.type === 'a' && !('href' in child.props))) {
      props.href = as || href
    }

    // Add the ending slash to the paths. So, we can serve the
    // "<page>/index.html" directly.
    if (
      props.href &&
      typeof __NEXT_DATA__ !== 'undefined' &&
      __NEXT_DATA__.nextExport
    ) {
      props.href = _rewriteUrlForNextExport(props.href)
    }

    return React.cloneElement(child, props)
  }
}

function isLocal (href) {
  const url = parse(href, false, true)
  const origin = parse(getLocationOrigin(), false, true)
  return !url.host ||
    (url.protocol === origin.protocol && url.host === origin.host)
}

const warnLink = execOnce(warn)
<commit_msg>Added <Link scroll> PropType (#3003)<commit_after>/* global __NEXT_DATA__ */

import { resolve, format, parse } from 'url'
import React, { Component, Children } from 'react'
import PropTypes from 'prop-types'
import exact from 'prop-types-exact'
import Router, { _rewriteUrlForNextExport } from './router'
import { warn, execOnce, getLocationOrigin } from './utils'

export default class Link extends Component {
  constructor (props, ...rest) {
    super(props, ...rest)
    this.linkClicked = this.linkClicked.bind(this)
    this.formatUrls(props)
  }

  static propTypes = exact({
    href: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
    as: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    prefetch: PropTypes.bool,
    replace: PropTypes.bool,
    shallow: PropTypes.bool,
    passHref: PropTypes.bool,
    scroll: PropTypes.bool,
    children: PropTypes.oneOfType([
      PropTypes.element,
      (props, propName) => {
        const value = props[propName]

        if (typeof value === 'string') {
          warnLink(`Warning: You're using a string directly inside <Link>. This usage has been deprecated. Please add an <a> tag as child of <Link>`)
        }

        return null
      }
    ]).isRequired
  })

  componentWillReceiveProps (nextProps) {
    this.formatUrls(nextProps)
  }

  linkClicked (e) {
    if (e.currentTarget.nodeName === 'A' &&
      (e.metaKey || e.ctrlKey || e.shiftKey || (e.nativeEvent && e.nativeEvent.which === 2))) {
      // ignore click for new tab / new window behavior
      return
    }

    const { shallow } = this.props
    let { href, as } = this

    if (!isLocal(href)) {
      // ignore click if it's outside our scope
      return
    }

    const { pathname } = window.location
    href = resolve(pathname, href)
    as = as ? resolve(pathname, as) : href

    e.preventDefault()

    //  avoid scroll for urls with anchor refs
    let { scroll } = this.props
    if (scroll == null) {
      scroll = as.indexOf('#') < 0
    }

    // replace state instead of push if prop is present
    const { replace } = this.props
    const changeMethod = replace ? 'replace' : 'push'

    // straight up redirect
    Router[changeMethod](href, as, { shallow })
      .then((success) => {
        if (!success) return
        if (scroll) window.scrollTo(0, 0)
      })
      .catch((err) => {
        if (this.props.onError) this.props.onError(err)
      })
  }

  prefetch () {
    if (!this.props.prefetch) return
    if (typeof window === 'undefined') return

    // Prefetch the JSON page if asked (only in the client)
    const { pathname } = window.location
    const href = resolve(pathname, this.href)
    Router.prefetch(href)
  }

  componentDidMount () {
    this.prefetch()
  }

  componentDidUpdate (prevProps) {
    if (JSON.stringify(this.props.href) !== JSON.stringify(prevProps.href)) {
      this.prefetch()
    }
  }

  // We accept both 'href' and 'as' as objects which we can pass to `url.format`.
  // We'll handle it here.
  formatUrls (props) {
    this.href = props.href && typeof props.href === 'object'
      ? format(props.href)
      : props.href
    this.as = props.as && typeof props.as === 'object'
      ? format(props.as)
      : props.as
  }

  render () {
    let { children } = this.props
    let { href, as } = this
    // Deprecated. Warning shown by propType check. If the childen provided is a string (<Link>example</Link>) we wrap it in an  tag
    if (typeof children === 'string') {
      children = {children}
    }

    // This will return the first child, if multiple are provided it will throw an error
    const child = Children.only(children)
    const props = {
      onClick: this.linkClicked
    }

    // If child is an  tag and doesn't have a href attribute, or if the 'passHref' property is
    // defined, we specify the current 'href', so that repetition is not needed by the user
    if (this.props.passHref || (child.type === 'a' && !('href' in child.props))) {
      props.href = as || href
    }

    // Add the ending slash to the paths. So, we can serve the
    // "<page>/index.html" directly.
    if (
      props.href &&
      typeof __NEXT_DATA__ !== 'undefined' &&
      __NEXT_DATA__.nextExport
    ) {
      props.href = _rewriteUrlForNextExport(props.href)
    }

    return React.cloneElement(child, props)
  }
}

function isLocal (href) {
  const url = parse(href, false, true)
  const origin = parse(getLocationOrigin(), false, true)
  return !url.host ||
    (url.protocol === origin.protocol && url.host === origin.host)
}

const warnLink = execOnce(warn)
<|endoftext|>


<commit_before>var Backbone = require('backbone');
var QueryRowModel = require('./query-row-model');
var syncAbort = require('./backbone/sync-abort');
var _ = require('underscore');
var STATUS = require('./query-base-status');

var MAX_GET_LENGTH = 1024;
var WRAP_SQL_TEMPLATE = 'select <%= selectedColumns %> from (<%= sql %>) __wrapped';
var MAX_REPEATED_ERRORS = 3;

module.exports = Backbone.Collection.extend({
  defaults: {
    empty: true
  },

  DEFAULT_FETCH_OPTIONS: {
    rows_per_page: 40,
    sort_order: 'asc',
    page: 0
  },

  // Due to a problem how Backbone checks if there is a duplicated model
  // or not, we can't create the model with a function + its necessary options
  model: QueryRowModel,

  sync: syncAbort,

  url: function () {
    return this._configModel.getSqlApiUrl();
  },

  initialize: function (models, opts) {
    opts = opts || {};

    this._repeatedErrors = 0;
    this._tableName = opts.tableName;
    this._querySchemaModel = opts.querySchemaModel;
    this._configModel = opts.configModel;

    this.statusModel = new Backbone.Model({
      status: STATUS.initial
    });

    this._initBinds();
  },

  _initBinds: function () {
    this.listenTo(this._querySchemaModel, 'change:query', this._onQuerySchemaQueryChange);

    if (this._querySchemaModel && this._querySchemaModel.columnsCollection) {
      this.listenTo(this._querySchemaModel.columnsCollection, 'reset', this._onColumnsCollectionReset);
    }

    this.listenTo(this.statusModel, 'change:status', this._onStatusChanged);
  },

  _onColumnsCollectionReset: function () {
    this._onQuerySchemaQueryChange();

    if (this.shouldFetch()) {
      this.fetch();
    }
  },

  getStatusValue: function () {
    return this.statusModel.get('status');
  },

  isInInitialStatus: function () {
    return this.getStatusValue() === STATUS.initial;
  },

  isFetched: function () {
    return this.getStatusValue() === STATUS.fetched;
  },

  isErrored: function () {
    return this.getStatusValue() === STATUS.errored;
  },

  isFetching: function () {
    return this.getStatusValue() === STATUS.fetching;
  },

  isDone: function () {
    return this.isFetched() || this.isErrored();
  },

  isInFinalStatus: function () {
    var finalStatuses = [STATUS.unavailable, STATUS.fetched, STATUS.errored];
    return _.contains(finalStatuses, this.getStatusValue());
  },

  isUnavailable: function () {
    return this.getStatusValue() === STATUS.unavailable;
  },

  canFetch: function () {
    var hasQuery = !!this._querySchemaModel.get('query');
    var isReady = this._querySchemaModel.get('ready');
    var isFetched = this._querySchemaModel.isFetched();
    var isErrored = this._querySchemaModel.isErrored();

    return hasQuery && isReady && isFetched && !isErrored;
  },

  shouldFetch: function () {
    return !this.isFetched() && !this.isFetching() && this.canFetch() && !this.isErrored();
  },

  resetFetch: function () {
    this.statusModel.set('status', STATUS.unfetched);
  },

  isEmpty: function () {
    throw new Error('QueryRowsCollection.isEmpty() is an async operation. Use `.isEmptyAsync` instead.');
  },

  isEmptyAsync: function () {
    if (this.isInFinalStatus()) {
      return Promise.resolve(this.size() === 0);
    } else {
      return new Promise(function (resolve) {
        this.listenToOnce(this, 'inFinalStatus', function () {
          resolve(this.size() === 0);
        });
      }.bind(this));
    }
  },

  _onStatusChanged: function () {
    if (this.isInFinalStatus()) {
      this.trigger('inFinalStatus');
    }
  },

  _onQuerySchemaQueryChange: function () {
    this.statusModel.set('status', 'unfetched');
    this.reset([], { silent: true });
  },

  _geometryColumnSQL: function (column) {
    /* eslint-disable */
    return [
      "CASE",
      "WHEN GeometryType(" + column + ") = 'POINT' THEN",
        "ST_AsGeoJSON(" + column + ",8)",
      "WHEN (" + column + " IS NULL) THEN",
        "NULL",
      "ELSE",
        "GeometryType(" + column + ")",
      "END " + column
    ].join(' ');
    /* eslint-enable */
  },

  // return wrapped SQL removing the_geom and the_geom_webmercator
  // to avoid fetching those columns.
  // So for a sql like
  // select * from table the returned value is
  // select column1, column2, column3... from table
  _getWrappedSQL: function (excludeColumns) {
    var self = this;
    var schema = this._querySchemaModel.columnsCollection.toJSON();

    var selectedColumns = _
      .chain(schema)
      .omit(function (item) {
        return _.contains(excludeColumns, item.name);
      })
      .map(function (item, index) {
        if (item.type === 'geometry') {
          return self._geometryColumnSQL(item.name);
        }
        return '"' + item.name + '"';
      })
      .value()
      .join(',');

    return _.template(WRAP_SQL_TEMPLATE)({
      selectedColumns: selectedColumns,
      sql: this._querySchemaModel.get('query')
    });
  },

  _httpMethod: function () {
    return this._querySchemaModel.get('query').length > MAX_GET_LENGTH
      ? 'POST'
      : 'GET';
  },

  _incrementRepeatedError: function () {
    this._repeatedErrors++;
  },

  _resetRepeatedError: function () {
    this._repeatedErrors = 0;
  },

  hasRepeatedErrors: function () {
    return this._repeatedErrors >= MAX_REPEATED_ERRORS;
  },

  fetch: function (opts) {
    opts = opts || {};

    var previousStatus = this.getStatusValue();
    this.statusModel.set('status', STATUS.fetching);

    var excludeColumns = (opts.data && opts.data.exclude) || [];

    opts = opts || {};
    opts.data = _.extend(
      {},
      this.DEFAULT_FETCH_OPTIONS,
      opts.data && _.omit(opts.data, 'exclude') || {},
      {
        api_key: this._configModel.get('api_key'),
        q: this._getWrappedSQL(excludeColumns)
      }
    );

    opts.method = this._httpMethod();
    var errorCallback = opts.error;
    opts.error = function (coll, resp) {
      if (previousStatus === STATUS.unavailable) {
        this._incrementRepeatedError();
      }

      if (resp.error) {
        this._onQueryRowsCollectionError(resp);
      }

      this.trigger('fail', coll, resp);
      this.statusModel.set('status', this.hasRepeatedErrors() ? STATUS.errored : STATUS.unavailable);
      errorCallback && errorCallback(coll, resp);
    }.bind(this);

    var successCallback = opts.success;
    opts.success = function (coll, resp, options) {
      if (resp.error) {
        return opts.error.apply(this, arguments);
      }

      this._resetRepeatedError();
      this.statusModel.set('status', STATUS.fetched);
      successCallback && successCallback(coll, resp);
    }.bind(this);

    // Needed to reset the whole collection when a fetch is done
    opts.reset = true;

    return Backbone.Collection.prototype.fetch.call(this, opts);
  },

  _onQueryRowsCollectionError: function (response) {
    var queryErrors = this._querySchemaModel.get('query_errors');
    if (queryErrors && queryErrors.length) {
      return;
    }

    this._querySchemaModel.set({
      query_errors: response.error,
      status: this._querySchemaModel.hasRepeatedErrors() ? STATUS.errored : STATUS.unavailable
    });
  },

  parse: function (r) {
    return this._parseWithID(r.rows);
  },

  reset: function (result, opts) {
    var items = [];

    if (result && result.rows) {
      // If reset comes from a fetch, we need to parse the rows
      items = result.rows;
    } else {
      // If it comes directly from a simple reset function
      items = result;
    }

    Backbone.Collection.prototype.reset.apply(this, [this._parseWithID(items)]);
  },

  _parseWithID: function (array) {
    return _.map(array, function (attrs) {
      attrs.__id = _.uniqueId();
      return attrs;
    });
  },

  addRow: function (opts) {
    opts = opts || {};
    this.create(
      {
        __id: _.uniqueId()
      },
      _.extend(
        opts,
        {
          wait: true,
          parse: true
        }
      )
    );
  },

  setTableName: function (name) {
    if (!name) return;

    if (this._tableName) {
      this._tableName = name;

      this.each(function (rowModel) {
        rowModel._tableName = name;
      });
    }
  }
});
<commit_msg>Error checking ✌<commit_after>var Backbone = require('backbone');
var QueryRowModel = require('./query-row-model');
var syncAbort = require('./backbone/sync-abort');
var _ = require('underscore');
var STATUS = require('./query-base-status');

var MAX_GET_LENGTH = 1024;
var WRAP_SQL_TEMPLATE = 'select <%= selectedColumns %> from (<%= sql %>) __wrapped';
var MAX_REPEATED_ERRORS = 3;

module.exports = Backbone.Collection.extend({
  defaults: {
    empty: true
  },

  DEFAULT_FETCH_OPTIONS: {
    rows_per_page: 40,
    sort_order: 'asc',
    page: 0
  },

  // Due to a problem how Backbone checks if there is a duplicated model
  // or not, we can't create the model with a function + its necessary options
  model: QueryRowModel,

  sync: syncAbort,

  url: function () {
    return this._configModel.getSqlApiUrl();
  },

  initialize: function (models, opts) {
    opts = opts || {};

    this._repeatedErrors = 0;
    this._tableName = opts.tableName;
    this._querySchemaModel = opts.querySchemaModel;
    this._configModel = opts.configModel;

    this.statusModel = new Backbone.Model({
      status: STATUS.initial
    });

    this._initBinds();
  },

  _initBinds: function () {
    this.listenTo(this._querySchemaModel, 'change:query', this._onQuerySchemaQueryChange);

    if (this._querySchemaModel && this._querySchemaModel.columnsCollection) {
      this.listenTo(this._querySchemaModel.columnsCollection, 'reset', this._onColumnsCollectionReset);
    }

    this.listenTo(this.statusModel, 'change:status', this._onStatusChanged);
  },

  _onColumnsCollectionReset: function () {
    this._onQuerySchemaQueryChange();

    if (this.shouldFetch()) {
      this.fetch();
    }
  },

  getStatusValue: function () {
    return this.statusModel.get('status');
  },

  isInInitialStatus: function () {
    return this.getStatusValue() === STATUS.initial;
  },

  isFetched: function () {
    return this.getStatusValue() === STATUS.fetched;
  },

  isErrored: function () {
    return this.getStatusValue() === STATUS.errored;
  },

  isFetching: function () {
    return this.getStatusValue() === STATUS.fetching;
  },

  isDone: function () {
    return this.isFetched() || this.isErrored();
  },

  isInFinalStatus: function () {
    var finalStatuses = [STATUS.unavailable, STATUS.fetched, STATUS.errored];
    return _.contains(finalStatuses, this.getStatusValue());
  },

  isUnavailable: function () {
    return this.getStatusValue() === STATUS.unavailable;
  },

  canFetch: function () {
    var hasQuery = !!this._querySchemaModel.get('query');
    var isReady = this._querySchemaModel.get('ready');
    var isFetched = this._querySchemaModel.isFetched();
    var isErrored = this._querySchemaModel.isErrored();

    return hasQuery && isReady && isFetched && !isErrored;
  },

  shouldFetch: function () {
    return !this.isFetched() && !this.isFetching() && this.canFetch() && !this.isErrored();
  },

  resetFetch: function () {
    this.statusModel.set('status', STATUS.unfetched);
  },

  isEmpty: function () {
    throw new Error('QueryRowsCollection.isEmpty() is an async operation. Use `.isEmptyAsync` instead.');
  },

  isEmptyAsync: function () {
    if (this.isInFinalStatus()) {
      return Promise.resolve(this.size() === 0);
    } else {
      return new Promise(function (resolve) {
        this.listenToOnce(this, 'inFinalStatus', function () {
          resolve(this.size() === 0);
        });
      }.bind(this));
    }
  },

  _onStatusChanged: function () {
    if (this.isInFinalStatus()) {
      this.trigger('inFinalStatus');
    }
  },

  _onQuerySchemaQueryChange: function () {
    this.statusModel.set('status', 'unfetched');
    this.reset([], { silent: true });
  },

  _geometryColumnSQL: function (column) {
    /* eslint-disable */
    return [
      "CASE",
      "WHEN GeometryType(" + column + ") = 'POINT' THEN",
        "ST_AsGeoJSON(" + column + ",8)",
      "WHEN (" + column + " IS NULL) THEN",
        "NULL",
      "ELSE",
        "GeometryType(" + column + ")",
      "END " + column
    ].join(' ');
    /* eslint-enable */
  },

  // return wrapped SQL removing the_geom and the_geom_webmercator
  // to avoid fetching those columns.
  // So for a sql like
  // select * from table the returned value is
  // select column1, column2, column3... from table
  _getWrappedSQL: function (excludeColumns) {
    var self = this;
    var schema = this._querySchemaModel.columnsCollection.toJSON();

    var selectedColumns = _
      .chain(schema)
      .omit(function (item) {
        return _.contains(excludeColumns, item.name);
      })
      .map(function (item, index) {
        if (item.type === 'geometry') {
          return self._geometryColumnSQL(item.name);
        }
        return '"' + item.name + '"';
      })
      .value()
      .join(',');

    return _.template(WRAP_SQL_TEMPLATE)({
      selectedColumns: selectedColumns,
      sql: this._querySchemaModel.get('query')
    });
  },

  _httpMethod: function () {
    return this._querySchemaModel.get('query').length > MAX_GET_LENGTH
      ? 'POST'
      : 'GET';
  },

  _incrementRepeatedError: function () {
    this._repeatedErrors++;
  },

  _resetRepeatedError: function () {
    this._repeatedErrors = 0;
  },

  hasRepeatedErrors: function () {
    return this._repeatedErrors >= MAX_REPEATED_ERRORS;
  },

  fetch: function (opts) {
    opts = opts || {};

    var previousStatus = this.getStatusValue();
    this.statusModel.set('status', STATUS.fetching);

    var excludeColumns = (opts.data && opts.data.exclude) || [];

    opts = opts || {};
    opts.data = _.extend(
      {},
      this.DEFAULT_FETCH_OPTIONS,
      opts.data && _.omit(opts.data, 'exclude') || {},
      {
        api_key: this._configModel.get('api_key'),
        q: this._getWrappedSQL(excludeColumns)
      }
    );

    opts.method = this._httpMethod();
    var errorCallback = opts.error;
    opts.error = function (coll, resp) {
      if (previousStatus === STATUS.unavailable) {
        this._incrementRepeatedError();
      }

      if (resp && resp.error) {
        this._onQueryRowsCollectionError(resp);
      }

      this.trigger('fail', coll, resp);
      this.statusModel.set('status', this.hasRepeatedErrors() ? STATUS.errored : STATUS.unavailable);
      errorCallback && errorCallback(coll, resp);
    }.bind(this);

    var successCallback = opts.success;
    opts.success = function (coll, resp, options) {
      if (resp && resp.error) {
        return opts.error.apply(this, arguments);
      }

      this._resetRepeatedError();
      this.statusModel.set('status', STATUS.fetched);
      successCallback && successCallback(coll, resp);
    }.bind(this);

    // Needed to reset the whole collection when a fetch is done
    opts.reset = true;

    return Backbone.Collection.prototype.fetch.call(this, opts);
  },

  _onQueryRowsCollectionError: function (response) {
    var queryErrors = this._querySchemaModel.get('query_errors');
    if (queryErrors && queryErrors.length) {
      return;
    }

    this._querySchemaModel.set({
      query_errors: response.error,
      status: this._querySchemaModel.hasRepeatedErrors() ? STATUS.errored : STATUS.unavailable
    });
  },

  parse: function (r) {
    return this._parseWithID(r.rows);
  },

  reset: function (result, opts) {
    var items = [];

    if (result && result.rows) {
      // If reset comes from a fetch, we need to parse the rows
      items = result.rows;
    } else {
      // If it comes directly from a simple reset function
      items = result;
    }

    Backbone.Collection.prototype.reset.apply(this, [this._parseWithID(items)]);
  },

  _parseWithID: function (array) {
    return _.map(array, function (attrs) {
      attrs.__id = _.uniqueId();
      return attrs;
    });
  },

  addRow: function (opts) {
    opts = opts || {};
    this.create(
      {
        __id: _.uniqueId()
      },
      _.extend(
        opts,
        {
          wait: true,
          parse: true
        }
      )
    );
  },

  setTableName: function (name) {
    if (!name) return;

    if (this._tableName) {
      this._tableName = name;

      this.each(function (rowModel) {
        rowModel._tableName = name;
      });
    }
  }
});
<|endoftext|>


<commit_before>import React from "react";
import {hyperscript as h} from "neutrine-utils";

import "siimple/scss/elements/_tip.scss";

//Tip class
export default class Tip extends React.Component {
    render() {
        let classList = ["siimple-tip"];
        //Add the tip color
        if (typeof this.props.color === "string") {
            classList.push("siimple-tip--" + this.props.color.toLowerCase().trim());
        }
        //Add the tip icon
        if (typeof this.props.icon === "string") {
            classList.push("siimple-tip--" + this.props.icon.toLowerCase().trim());
        }
        //Return the tip element
        return h("div", {className: classList, style: this.props.style}, this.props.children);
    }
}

//Initialize the tip element default props
Tip.defaultProps = {
    color: "blue",
    icon: null,
    style: null
};

<commit_msg>Changed default props. Minor changes<commit_after>import React from "react";
import {classNames, hyperscript as h} from "neutrine-utils";
import {omit} from "kofi";

import "siimple/scss/elements/_tip.scss";

//Tip class
export default class Tip extends React.Component {
    render() {
        let props = omit(this.props, ["children", "className", "color", "icon"]);
        let classList = ["siimple-tip"];
        //Add the tip color
        if (typeof this.props.color === "string") {
            classList.push("siimple-tip--" + this.props.color.toLowerCase().trim());
        }
        //Add the tip icon
        if (typeof this.props.icon === "string") {
            classList.push("siimple-tip--" + this.props.icon.toLowerCase().trim());
        }
        //Generate the class names
        props.className = classNames(classList, this.props.className);
        //Return the tip element
        return h("div", props, this.props.children);
    }
}

//Initialize the tip element default props
Tip.defaultProps = {
    color: "blue",
    icon: null
};

<|endoftext|>


<commit_before>'use strict';

var View = require('./view');
var Emitter = require("./module/emitter");
var bind = require('./module/bind');

var Element = require('./element');

//var Surface = require('./view/surface');
//var Collection = require('./view/collection');
//var Filter = require('./view/filter');
//var Select = require('./view/select');
//var Search = require('./list/search');

var defaults = require('./list/options');

/**
 * List view class
 * @class
 * @param {Object} options Default options for view
 * @extends {View}
 * @since 0.0.4
 * @author Jerome Vial
 *
 * @type {prime}
 */
class List extends View {

	/**
	 * [_initView description]
	 * @return {instance} Class instance
	 */
	init(options) {
		super.init(options);

		console.log(this.options.tag);

		Object.assign(this.options, [defaults, options].reduce(Object.assign, {}));

		this.name = this.options.name;

		this.filters = [];
		this.data = [];

		this.items = [];

		if (this.options.render) {
			this.render = this.options.render;
		}

		return this;
	}

	/**
	 * [_initList description]
	 * @param  {Object} options this class options
	 * @return {instance} The class instance
	 */
	build(options) {
		super.build();

		options = options || this.options;

		this.items = [];

		//this.element.addClass('type-'+this.tmpl._type);
		this.element.addClass('view-'+this.options.name);

		//this.content = this.c.body;

		//this._initSearch();

		var self = this;

		this.c.body.delegate('click', '.ui-button', function(event, item){
		   	//console.log(event, item);
		   	self.select(item, event);
		});

		//this.container.emit('resize');
		return this;
	}

	/**
	 * select
	 * @param  {Element} item  [description]
	 * @param  {event} event The caller event
	 * @return {instance}       [description]
	 */
	select(item, event) {

		this.item = item;

		this.emit('selected', item[0]);
	}

	/**
	 * Setter
	 * @param {string} prop
	 * @param {string} value
	 */
	set(prop, value, options) {

		switch(prop) {
			case 'list':
				this.setList(value, options);
				break;
			default:
				this.setList(value, options);
		}

		return this;
	}

	/**
	 * Set list
	 * @param {Array} list List of info object
	 * @return {instance} The class instance
	 */
	setList(list) {

		for (var i = 0; i < list.length; i++) {
			var item = this.render(list[i]);

			item.element.store('info', list[i]);

			this.addItem(item, i);
		}

		return this;
	}

	/**
	 * Insert info
	 * @param  {Object} info Info object
	 * @param  {integer} x    [description]
	 * @param  {integer} y    [description]
	 * @return {instance} The class instance
	 */
	insert(info, x, y) {

		if (this.list.indexOf(info._id) > -1)
			return;

		this.list.push(info._id);

		var item = this.addItem(info);

		return this;
	}

	/**
	 * [add description]
	 * @param {Object} item [description]
	 */
	addItem(item, index) {

		if (!item) {
			return;
		}

		var where = 'bottom';

		item.inject(this.c.body, where);
		this.items.push(item);

		//this._initDragItem(item);
		return item;
	}

   	/**
   	 * Reverse the list order
   	 * @return {Object} The class instance
   	 */
   	reverse() {
   		this.list.reverse();
   		this.update(this.list);

   		return this;
   	}
}

module.exports = List;
<commit_msg>remove console<commit_after>'use strict';

var View = require('./view');
var Emitter = require("./module/emitter");
var bind = require('./module/bind');

var Element = require('./element');

//var Surface = require('./view/surface');
//var Collection = require('./view/collection');
//var Filter = require('./view/filter');
//var Select = require('./view/select');
//var Search = require('./list/search');

var defaults = require('./list/options');

/**
 * List view class
 * @class
 * @param {Object} options Default options for view
 * @extends {View}
 * @since 0.0.4
 * @author Jerome Vial
 *
 * @type {prime}
 */
class List extends View {

	/**
	 * [_initView description]
	 * @return {instance} Class instance
	 */
	init(options) {
		super.init(options);

		Object.assign(this.options, [defaults, options].reduce(Object.assign, {}));

		this.name = this.options.name;

		this.filters = [];
		this.data = [];

		this.items = [];

		if (this.options.render) {
			this.render = this.options.render;
		}

		return this;
	}

	/**
	 * [_initList description]
	 * @param  {Object} options this class options
	 * @return {instance} The class instance
	 */
	build(options) {
		super.build();

		options = options || this.options;

		this.items = [];

		//this.element.addClass('type-'+this.tmpl._type);
		this.element.addClass('view-'+this.options.name);

		//this.content = this.c.body;

		//this._initSearch();

		var self = this;

		this.c.body.delegate('click', '.ui-button', function(event, item){
		   	//console.log(event, item);
		   	self.select(item, event);
		});

		//this.container.emit('resize');
		return this;
	}

	/**
	 * select
	 * @param  {Element} item  [description]
	 * @param  {event} event The caller event
	 * @return {instance}       [description]
	 */
	select(item, event) {

		this.item = item;

		this.emit('selected', item[0]);
	}

	/**
	 * Setter
	 * @param {string} prop
	 * @param {string} value
	 */
	set(prop, value, options) {

		switch(prop) {
			case 'list':
				this.setList(value, options);
				break;
			default:
				this.setList(value, options);
		}

		return this;
	}

	/**
	 * Set list
	 * @param {Array} list List of info object
	 * @return {instance} The class instance
	 */
	setList(list) {

		for (var i = 0; i < list.length; i++) {
			var item = this.render(list[i]);

			item.element.store('info', list[i]);

			this.addItem(item, i);
		}

		return this;
	}

	/**
	 * Insert info
	 * @param  {Object} info Info object
	 * @param  {integer} x    [description]
	 * @param  {integer} y    [description]
	 * @return {instance} The class instance
	 */
	insert(info, x, y) {

		if (this.list.indexOf(info._id) > -1)
			return;

		this.list.push(info._id);

		var item = this.addItem(info);

		return this;
	}

	/**
	 * [add description]
	 * @param {Object} item [description]
	 */
	addItem(item, index) {

		if (!item) {
			return;
		}

		var where = 'bottom';

		item.inject(this.c.body, where);
		this.items.push(item);

		//this._initDragItem(item);
		return item;
	}

   	/**
   	 * Reverse the list order
   	 * @return {Object} The class instance
   	 */
   	reverse() {
   		this.list.reverse();
   		this.update(this.list);

   		return this;
   	}
}

module.exports = List;
<|endoftext|>