<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import {autobind} from 'core-decorators';
import cx from 'classnames';
import {CompositeDisposable} from 'atom';

import StagingView from './staging-view';
import GitLogo from './git-logo';
import CommitController from '../controllers/commit-controller';
import RecentCommitsController from '../controllers/recent-commits-controller';
import EtchWrapper from './etch-wrapper';
import {isValidWorkdir} from '../helpers';
import {AuthorPropType} from '../prop-types';

export default class GitTabView extends React.Component {
  static focus = {
    ...StagingView.focus,
    ...CommitController.focus,
    ...RecentCommitsController.focus,
  };

  static propTypes = {
    repository: PropTypes.object.isRequired,
    isLoading: PropTypes.bool.isRequired,

    lastCommit: PropTypes.object.isRequired,
    currentBranch: PropTypes.object,
    recentCommits: PropTypes.arrayOf(PropTypes.object).isRequired,
    isMerging: PropTypes.bool,
    isRebasing: PropTypes.bool,
    hasUndoHistory: PropTypes.bool,
    unstagedChanges: PropTypes.arrayOf(PropTypes.object),
    stagedChanges: PropTypes.arrayOf(PropTypes.object),
    mergeConflicts: PropTypes.arrayOf(PropTypes.object),
    workingDirectoryPath: PropTypes.string,
    mergeMessage: PropTypes.string,
    mentionableUsers: PropTypes.arrayOf(AuthorPropType),
    selectedCoAuthors: PropTypes.arrayOf(AuthorPropType),
    updateSelectedCoAuthors: PropTypes.func.isRequired,

    workspace: PropTypes.object.isRequired,
    commandRegistry: PropTypes.object.isRequired,
    grammars: PropTypes.object.isRequired,
    resolutionProgress: PropTypes.object.isRequired,
    notificationManager: PropTypes.object.isRequired,
    config: PropTypes.object.isRequired,
    project: PropTypes.object.isRequired,
    tooltips: PropTypes.object.isRequired,

    initializeRepo: PropTypes.func.isRequired,
    abortMerge: PropTypes.func.isRequired,
    commit: PropTypes.func.isRequired,
    undoLastCommit: PropTypes.func.isRequired,
    prepareToCommit: PropTypes.func.isRequired,
    resolveAsOurs: PropTypes.func.isRequired,
    resolveAsTheirs: PropTypes.func.isRequired,
    undoLastDiscard: PropTypes.func.isRequired,
    attemptStageAllOperation: PropTypes.func.isRequired,
    attemptFileStageOperation: PropTypes.func.isRequired,
    discardWorkDirChangesForPaths: PropTypes.func.isRequired,
    openFiles: PropTypes.func.isRequired,
  };

  constructor(props, context) {
    super(props, context);

    this.subscriptions = new CompositeDisposable();

    this.refRoot = null;
    this.refStagingView = null;
    this.refCommitViewComponent = null;
  }

  componentDidMount() {
    this.subscriptions.add(
      this.props.commandRegistry.add(this.refRoot, {
        'tool-panel:unfocus': this.blur,
        'core:focus-next': this.advanceFocus,
        'core:focus-previous': this.retreatFocus,
      }),
    );
  }

  render() {
    if (this.props.repository.isTooLarge()) {
      return (

 { this.refRoot = c; }}>

              <GitLogo />

Too many changes

              The repository at {this.props.workingDirectoryPath} has too many changed files
              to display in Atom. Ensure that you have set up an appropriate .gitignore file.

      );
    } else if (this.props.repository.hasDirectory() &&
               !isValidWorkdir(this.props.repository.getWorkingDirectoryPath())) {
      return (

 { this.refRoot = c; }}>

              <GitLogo />

Unsupported directory

              Atom does not support managing Git repositories in your home or root directories.

      );
    } else if (this.props.repository.showGitTabInit()) {
      const inProgress = this.props.repository.showGitTabInitInProgress();
      const message = this.props.repository.hasDirectory() ?
        (
          Initialize {this.props.workingDirectoryPath} with a
          Git repository
        ) :
          Initialize a new project directory with a Git repository;

      return (

 { this.refRoot = c; }}>

              <GitLogo />

{message}

            <button onClick={this.initializeRepo} disabled={inProgress} className="btn btn-primary">
              {inProgress ? 'Creating repository...' : 'Create repository'}
            </button>

      );
    } else {
      const isLoading = this.props.isLoading || this.props.repository.showGitTabLoading();

      return (

 { this.refRoot = c; }}>
          <EtchWrapper className="github-PanelEtchWrapper" ref={c => { this.refStagingView = c; }}>
            <StagingView
              commandRegistry={this.props.commandRegistry}
              notificationManager={this.props.notificationManager}
              workspace={this.props.workspace}
              stagedChanges={this.props.stagedChanges}
              unstagedChanges={this.props.unstagedChanges}
              mergeConflicts={this.props.mergeConflicts}
              workingDirectoryPath={this.props.workingDirectoryPath}
              resolutionProgress={this.props.resolutionProgress}
              openFiles={this.props.openFiles}
              discardWorkDirChangesForPaths={this.props.discardWorkDirChangesForPaths}
              attemptFileStageOperation={this.props.attemptFileStageOperation}
              attemptStageAllOperation={this.props.attemptStageAllOperation}
              undoLastDiscard={this.props.undoLastDiscard}
              abortMerge={this.props.abortMerge}
              resolveAsOurs={this.props.resolveAsOurs}
              resolveAsTheirs={this.props.resolveAsTheirs}
              lastCommit={this.props.lastCommit}
              isLoading={this.props.isLoading}
              hasUndoHistory={this.props.hasUndoHistory}
              isMerging={this.props.isMerging}
            />
          </EtchWrapper>
          <CommitController
            ref={c => { this.refCommitController = c; }}
            tooltips={this.props.tooltips}
            config={this.props.config}
            stagedChangesExist={this.props.stagedChanges.length > 0}
            mergeConflictsExist={this.props.mergeConflicts.length > 0}
            prepareToCommit={this.props.prepareToCommit}
            commit={this.props.commit}
            abortMerge={this.props.abortMerge}
            currentBranch={this.props.currentBranch}
            workspace={this.props.workspace}
            commandRegistry={this.props.commandRegistry}
            notificationManager={this.props.notificationManager}
            grammars={this.props.grammars}
            mergeMessage={this.props.mergeMessage}
            isMerging={this.props.isMerging}
            isLoading={this.props.isLoading}
            lastCommit={this.props.lastCommit}
            repository={this.props.repository}
            mentionableUsers={this.props.mentionableUsers}
            selectedCoAuthors={this.props.selectedCoAuthors}
            updateSelectedCoAuthors={this.props.updateSelectedCoAuthors}
          />
          <RecentCommitsController
            ref={c => { this.refRecentCommitController = c; }}
            commits={this.props.recentCommits}
            isLoading={this.props.isLoading}
            undoLastCommit={this.props.undoLastCommit}
          />

      );
    }
  }

  componentWillUnmount() {
    this.subscriptions.dispose();
  }

  @autobind
  initializeRepo(event) {
    event.preventDefault();
    let initPath = null;
    const activeEditor = this.props.workspace.getActiveTextEditor();
    if (activeEditor) {
      const [projectPath] = this.props.project.relativizePath(activeEditor.getPath());
      if (projectPath) {
        initPath = projectPath;
      }
    }
    this.props.initializeRepo(initPath);
  }

  rememberFocus(event) {
    let currentFocus = null;

    if (this.refs.stagingView) {
      currentFocus = this.refStagingView.getWrappedComponent().rememberFocus(event);
    }

    if (!currentFocus && this.refCommitController) {
      currentFocus = this.refCommitController.rememberFocus(event);
    }

    return currentFocus;
  }

  setFocus(focus) {
    if (this.refStagingView) {
      if (this.refStagingView.getWrappedComponent().setFocus(focus)) {
        return true;
      }
    }

    if (this.refCommitController) {
      if (this.refCommitController.setFocus(focus)) {
        return true;
      }
    }

    return false;
  }

  @autobind
  blur() {
    this.props.workspace.getActivePane().activate();
  }

  @autobind
  advanceFocus(evt) {
    if (!this.refStagingView.getWrappedComponent().activateNextList()) {
      if (this.refCommitController.setFocus(GitTabView.focus.EDITOR)) {
        evt.stopPropagation();
      }
    } else {
      evt.stopPropagation();
    }
  }

  @autobind
  retreatFocus(evt) {
    const stagingView = this.refStagingView.getWrappedComponent();
    const commitController = this.refCommitController;

    if (commitController.hasFocus()) {
      if (stagingView.activateLastList()) {
        this.setFocus(GitTabView.focus.STAGING);
        evt.stopPropagation();
      }
    } else {
      stagingView.activatePreviousList();
      evt.stopPropagation();
    }
  }

  async focusAndSelectStagingItem(filePath, stagingStatus) {
    await this.refStagingView.getWrappedComponent().quietlySelectItem(filePath, stagingStatus);
    this.setFocus(GitTabView.focus.STAGING);
  }

  hasFocus() {
    return this.refRoot.contains(document.activeElement);
  }

  @autobind
  quietlySelectItem(filePath, stagingStatus) {
    return this.refStagingView.getWrappedComponent().quietlySelectItem(filePath, stagingStatus);
  }
}
<commit_msg>Don't focus commit editor when `tab`bing from co-author input<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import {autobind} from 'core-decorators';
import cx from 'classnames';
import {CompositeDisposable} from 'atom';

import StagingView from './staging-view';
import GitLogo from './git-logo';
import CommitController from '../controllers/commit-controller';
import RecentCommitsController from '../controllers/recent-commits-controller';
import EtchWrapper from './etch-wrapper';
import {isValidWorkdir} from '../helpers';
import {AuthorPropType} from '../prop-types';

export default class GitTabView extends React.Component {
  static focus = {
    ...StagingView.focus,
    ...CommitController.focus,
    ...RecentCommitsController.focus,
  };

  static propTypes = {
    repository: PropTypes.object.isRequired,
    isLoading: PropTypes.bool.isRequired,

    lastCommit: PropTypes.object.isRequired,
    currentBranch: PropTypes.object,
    recentCommits: PropTypes.arrayOf(PropTypes.object).isRequired,
    isMerging: PropTypes.bool,
    isRebasing: PropTypes.bool,
    hasUndoHistory: PropTypes.bool,
    unstagedChanges: PropTypes.arrayOf(PropTypes.object),
    stagedChanges: PropTypes.arrayOf(PropTypes.object),
    mergeConflicts: PropTypes.arrayOf(PropTypes.object),
    workingDirectoryPath: PropTypes.string,
    mergeMessage: PropTypes.string,
    mentionableUsers: PropTypes.arrayOf(AuthorPropType),
    selectedCoAuthors: PropTypes.arrayOf(AuthorPropType),
    updateSelectedCoAuthors: PropTypes.func.isRequired,

    workspace: PropTypes.object.isRequired,
    commandRegistry: PropTypes.object.isRequired,
    grammars: PropTypes.object.isRequired,
    resolutionProgress: PropTypes.object.isRequired,
    notificationManager: PropTypes.object.isRequired,
    config: PropTypes.object.isRequired,
    project: PropTypes.object.isRequired,
    tooltips: PropTypes.object.isRequired,

    initializeRepo: PropTypes.func.isRequired,
    abortMerge: PropTypes.func.isRequired,
    commit: PropTypes.func.isRequired,
    undoLastCommit: PropTypes.func.isRequired,
    prepareToCommit: PropTypes.func.isRequired,
    resolveAsOurs: PropTypes.func.isRequired,
    resolveAsTheirs: PropTypes.func.isRequired,
    undoLastDiscard: PropTypes.func.isRequired,
    attemptStageAllOperation: PropTypes.func.isRequired,
    attemptFileStageOperation: PropTypes.func.isRequired,
    discardWorkDirChangesForPaths: PropTypes.func.isRequired,
    openFiles: PropTypes.func.isRequired,
  };

  constructor(props, context) {
    super(props, context);

    this.subscriptions = new CompositeDisposable();

    this.refRoot = null;
    this.refStagingView = null;
    this.refCommitViewComponent = null;
  }

  componentDidMount() {
    this.subscriptions.add(
      this.props.commandRegistry.add(this.refRoot, {
        'tool-panel:unfocus': this.blur,
        'core:focus-next': this.advanceFocus,
        'core:focus-previous': this.retreatFocus,
      }),
    );
  }

  render() {
    if (this.props.repository.isTooLarge()) {
      return (

 { this.refRoot = c; }}>

              <GitLogo />

Too many changes

              The repository at {this.props.workingDirectoryPath} has too many changed files
              to display in Atom. Ensure that you have set up an appropriate .gitignore file.

      );
    } else if (this.props.repository.hasDirectory() &&
               !isValidWorkdir(this.props.repository.getWorkingDirectoryPath())) {
      return (

 { this.refRoot = c; }}>

              <GitLogo />

Unsupported directory

              Atom does not support managing Git repositories in your home or root directories.

      );
    } else if (this.props.repository.showGitTabInit()) {
      const inProgress = this.props.repository.showGitTabInitInProgress();
      const message = this.props.repository.hasDirectory() ?
        (
          Initialize {this.props.workingDirectoryPath} with a
          Git repository
        ) :
          Initialize a new project directory with a Git repository;

      return (

 { this.refRoot = c; }}>

              <GitLogo />

{message}

            <button onClick={this.initializeRepo} disabled={inProgress} className="btn btn-primary">
              {inProgress ? 'Creating repository...' : 'Create repository'}
            </button>

      );
    } else {
      const isLoading = this.props.isLoading || this.props.repository.showGitTabLoading();

      return (

 { this.refRoot = c; }}>
          <EtchWrapper className="github-PanelEtchWrapper" ref={c => { this.refStagingView = c; }}>
            <StagingView
              commandRegistry={this.props.commandRegistry}
              notificationManager={this.props.notificationManager}
              workspace={this.props.workspace}
              stagedChanges={this.props.stagedChanges}
              unstagedChanges={this.props.unstagedChanges}
              mergeConflicts={this.props.mergeConflicts}
              workingDirectoryPath={this.props.workingDirectoryPath}
              resolutionProgress={this.props.resolutionProgress}
              openFiles={this.props.openFiles}
              discardWorkDirChangesForPaths={this.props.discardWorkDirChangesForPaths}
              attemptFileStageOperation={this.props.attemptFileStageOperation}
              attemptStageAllOperation={this.props.attemptStageAllOperation}
              undoLastDiscard={this.props.undoLastDiscard}
              abortMerge={this.props.abortMerge}
              resolveAsOurs={this.props.resolveAsOurs}
              resolveAsTheirs={this.props.resolveAsTheirs}
              lastCommit={this.props.lastCommit}
              isLoading={this.props.isLoading}
              hasUndoHistory={this.props.hasUndoHistory}
              isMerging={this.props.isMerging}
            />
          </EtchWrapper>
          <CommitController
            ref={c => { this.refCommitController = c; }}
            tooltips={this.props.tooltips}
            config={this.props.config}
            stagedChangesExist={this.props.stagedChanges.length > 0}
            mergeConflictsExist={this.props.mergeConflicts.length > 0}
            prepareToCommit={this.props.prepareToCommit}
            commit={this.props.commit}
            abortMerge={this.props.abortMerge}
            currentBranch={this.props.currentBranch}
            workspace={this.props.workspace}
            commandRegistry={this.props.commandRegistry}
            notificationManager={this.props.notificationManager}
            grammars={this.props.grammars}
            mergeMessage={this.props.mergeMessage}
            isMerging={this.props.isMerging}
            isLoading={this.props.isLoading}
            lastCommit={this.props.lastCommit}
            repository={this.props.repository}
            mentionableUsers={this.props.mentionableUsers}
            selectedCoAuthors={this.props.selectedCoAuthors}
            updateSelectedCoAuthors={this.props.updateSelectedCoAuthors}
          />
          <RecentCommitsController
            ref={c => { this.refRecentCommitController = c; }}
            commits={this.props.recentCommits}
            isLoading={this.props.isLoading}
            undoLastCommit={this.props.undoLastCommit}
          />

      );
    }
  }

  componentWillUnmount() {
    this.subscriptions.dispose();
  }

  @autobind
  initializeRepo(event) {
    event.preventDefault();
    let initPath = null;
    const activeEditor = this.props.workspace.getActiveTextEditor();
    if (activeEditor) {
      const [projectPath] = this.props.project.relativizePath(activeEditor.getPath());
      if (projectPath) {
        initPath = projectPath;
      }
    }
    this.props.initializeRepo(initPath);
  }

  rememberFocus(event) {
    let currentFocus = null;

    if (this.refs.stagingView) {
      currentFocus = this.refStagingView.getWrappedComponent().rememberFocus(event);
    }

    if (!currentFocus && this.refCommitController) {
      currentFocus = this.refCommitController.rememberFocus(event);
    }

    return currentFocus;
  }

  setFocus(focus) {
    if (this.refStagingView) {
      if (this.refStagingView.getWrappedComponent().setFocus(focus)) {
        return true;
      }
    }

    if (this.refCommitController) {
      if (this.refCommitController.setFocus(focus)) {
        return true;
      }
    }

    return false;
  }

  @autobind
  blur() {
    this.props.workspace.getActivePane().activate();
  }

  @autobind
  advanceFocus(evt) {
    if (!evt.target.classList.contains('github-StagingView')) { return; }
    if (!this.refStagingView.getWrappedComponent().activateNextList()) {
      if (this.refCommitController.setFocus(GitTabView.focus.EDITOR)) {
        evt.stopPropagation();
      }
    } else {
      evt.stopPropagation();
    }
  }

  @autobind
  retreatFocus(evt) {
    const stagingView = this.refStagingView.getWrappedComponent();
    const commitController = this.refCommitController;

    if (commitController.hasFocus()) {
      if (stagingView.activateLastList()) {
        this.setFocus(GitTabView.focus.STAGING);
        evt.stopPropagation();
      }
    } else {
      stagingView.activatePreviousList();
      evt.stopPropagation();
    }
  }

  async focusAndSelectStagingItem(filePath, stagingStatus) {
    await this.refStagingView.getWrappedComponent().quietlySelectItem(filePath, stagingStatus);
    this.setFocus(GitTabView.focus.STAGING);
  }

  hasFocus() {
    return this.refRoot.contains(document.activeElement);
  }

  @autobind
  quietlySelectItem(filePath, stagingStatus) {
    return this.refStagingView.getWrappedComponent().quietlySelectItem(filePath, stagingStatus);
  }
}
<|endoftext|>


<commit_before>(function(window) {
  var numberOfJobs = 3;
  var path = '/jobs?include=company,company.company_images'
  var pageParam = '&page' + encodeURIComponent('[') + 'size' + encodeURIComponent(']') + '=' + numberOfJobs;
  var filterParam = '&filter' + encodeURIComponent('[') + 'hidden' + encodeURIComponent(']') + '=true';
  var filterParam = '';
  var sortParam = '&sort=-featured,filled,-job_date';
  var fieldsParam = [
    'fields' + encodeURIComponent('[') + 'company' + encodeURIComponent(']') + '=id,name,city',
    'fields' + encodeURIComponent('[') + 'jobs' + encodeURIComponent(']') + '=company,id,name,hours,city,short_description,description,translated_text,gross_amount_delimited'
  ].join('&');

  var baseURL = 'https://api.justarrived.se/api/v1';
  JOBS_ENDPOINT = baseURL + path + pageParam + filterParam + sortParam + fieldsParam;

  function getJobsURL(opts) {
    var pageOffset = opts.pageOffset || 1;
    var pageOffsetParam = '&page' + encodeURIComponent('[') + 'number' + encodeURIComponent(']') + '=' + pageOffset;

    return JOBS_ENDPOINT +  pageOffsetParam;
  }

  function getJobs(callback) {
  $.ajax({
      url: getJobsURL({}),
      type: 'GET',
      dataType: 'json',
      success: function(response) {
        callback(response.data, response.included);
      },
      error: function() {
        console.error('ja-jobs.js: API Request failed!');
      },
      beforeSend: function(xhr) {
        xhr.setRequestHeader('X-API-KEY-TRANSFORM', 'underscore');
        xhr.setRequestHeader('X-API-LOCALE', CURRENT_LOCALE);
        xhr.setRequestHeader('Content-Type', 'application/vnd.api+json');
      }
    });
  }

  function formatTemplate(template, name, value) {
    var regex = new RegExp(name, 'g');
    return template.replace(regex, value);
  }

  function getIncludedResource(type, id, includedData) {
    var attributes;
    includedData.forEach(function(resource) {
      if (resource.type === type && resource.id === id) {
        attributes = resource.attributes;
        attributes['relationships'] = resource.relationships;
      }
    });
    return attributes;
  }

  function getCompany(includedData, id) {
    return getIncludedResource('companies', id, includedData);
  }

  function getCompanyImage(includedData, id) {
    return getIncludedResource('company_images', id, includedData);
  }

  function relationId(type, data) {
    return data.relationships[type].data.id;
  }

  function lastRelationId(type, data) {
    var relationData = data.relationships[type].data;
    if (!relationData) return null;

    var lastRelation = data.relationships[type].data[relationData.length -1];
    if (!lastRelation) return null;
    var lastId = lastRelation.id;
    return lastId;
  }

  function formatJobTemplate(template, jobData, includedData) {
    var innerHTML = '';
    var jobAtrs = jobData.attributes;
    var jobID = jobData.id;

    var companyId = relationId('company', jobData);
    var company = getCompany(includedData, companyId);
    var lastImageId = lastRelationId('company_images', company)
    var companyImage;
    var companyImageURL;
    if (lastImageId) {
      companyImage  = getCompanyImage(includedData, lastImageId);
    }
    if (companyImage) {
      companyImageURL = companyImage.image_url_large;
    } else {
      companyImageURL = "/assets/images/apple-touch-icon.png"
    }

    var hours = jobAtrs.hours;
    var maxDescriptionLength = 140;
    var shortDesc = jobAtrs['translated_text']['short_description'] || jobAtrs['short_description'];
    var description = shortDesc || (jobAtrs['translated_text']['description'] || jobAtrs['description']);
    var name = jobAtrs['translated_text'].name || jobAtrs.name;
    description = truncate(description, maxDescriptionLength);

    innerHTML = formatTemplate(template, '%job_id%', jobID);
    innerHTML = formatTemplate(innerHTML, '%job_company%', company.name);
    innerHTML = formatTemplate(innerHTML, '%job_city%', jobAtrs.city);
    innerHTML = formatTemplate(innerHTML, '%job_name%', name);
    innerHTML = formatTemplate(innerHTML, '%job_company_image_url%', companyImageURL);
    return formatTemplate(innerHTML, '%job_description%', description);
  }

  function truncate(text, maxLength) {
    if (text.length > maxLength) {
      return text.substring(0, maxLength - 3) + '...';
    }
    return text;
  }

  function createCards(targetSelector, templateSelector) {
    var $target = $(targetSelector);
    var $template = $(templateSelector);

    if ($target.length === 0 || $template.length === 0) {
      return;
    }

    var template = $template.html().toString();
    var html = '';

    getJobs(function(jobsData, includedData) {
      jobsData.forEach(function(jobData) {
        var jobId = jobData.id;
        html += formatJobTemplate(template, jobData, includedData, jobId);
      });

      $target.append(html);
    });
  }

  window.JAJobs = {
    createCards: createCards
  };
})(window);
<commit_msg>Fix JustMatch job cards<commit_after>(function(window) {
  var numberOfJobs = 3;
  var path = '/jobs?include=company,company.company_images'
  var pageParam = '&page' + encodeURIComponent('[') + 'size' + encodeURIComponent(']') + '=' + numberOfJobs;
  var filterParam = '&filter' + encodeURIComponent('[') + 'hidden' + encodeURIComponent(']') + '=true';
  var filterParam = '';
  var sortParam = '&sort=-featured,filled,-job_date';
  var fieldsParam = [
    '&fields' + encodeURIComponent('[') + 'company' + encodeURIComponent(']') + '=id,name,city',
    'fields' + encodeURIComponent('[') + 'jobs' + encodeURIComponent(']') + '=company,id,name,hours,city,short_description,description,translated_text,gross_amount_delimited'
  ].join('&');

  var baseURL = 'https://api.justarrived.se/api/v1';
  JOBS_ENDPOINT = baseURL + path + pageParam + filterParam + sortParam + fieldsParam;

  function getJobsURL(opts) {
    var pageOffset = opts.pageOffset || 1;
    var pageOffsetParam = '&page' + encodeURIComponent('[') + 'number' + encodeURIComponent(']') + '=' + pageOffset;

    return JOBS_ENDPOINT +  pageOffsetParam;
  }

  function getJobs(callback) {
  $.ajax({
      url: getJobsURL({}),
      type: 'GET',
      dataType: 'json',
      success: function(response) {
        callback(response.data, response.included);
      },
      error: function() {
        console.error('ja-jobs.js: API Request failed!');
      },
      beforeSend: function(xhr) {
        xhr.setRequestHeader('X-API-KEY-TRANSFORM', 'underscore');
        xhr.setRequestHeader('X-API-LOCALE', CURRENT_LOCALE);
        xhr.setRequestHeader('Content-Type', 'application/vnd.api+json');
      }
    });
  }

  function formatTemplate(template, name, value) {
    var regex = new RegExp(name, 'g');
    return template.replace(regex, value);
  }

  function getIncludedResource(type, id, includedData) {
    var attributes;
    includedData.forEach(function(resource) {
      if (resource.type === type && resource.id === id) {
        attributes = resource.attributes;
        attributes['relationships'] = resource.relationships;
      }
    });
    return attributes;
  }

  function getCompany(includedData, id) {
    return getIncludedResource('companies', id, includedData);
  }

  function getCompanyImage(includedData, id) {
    return getIncludedResource('company_images', id, includedData);
  }

  function getRelation(type, data) {
    if (!data.relationships) return null;
    var relation = data.relationships[type]
    if (relation) return relation
    return null
  }

  function relationId(type, data) {
    return getRelation(type, data).data.id;
  }

  function lastRelationId(type, data) {
    var relation = getRelation(type, data)
    if (!relation) return null

    var relationData = relation.data;
    if (!relationData) return null;

    var lastRelation = relation.data[relationData.length -1];
    if (!lastRelation) return null;
    var lastId = lastRelation.id;
    return lastId;
  }

  function formatJobTemplate(template, jobData, includedData) {
    var innerHTML = '';
    var jobAtrs = jobData.attributes;
    var jobID = jobData.id;

    var companyId = relationId('company', jobData);
    var company = getCompany(includedData, companyId);
    var lastImageId = lastRelationId('company_images', company)
    var companyImage;
    var companyImageURL;
    if (lastImageId) {
      companyImage  = getCompanyImage(includedData, lastImageId);
    }
    if (companyImage) {
      companyImageURL = companyImage.image_url_large;
    } else {
      companyImageURL = "/assets/images/apple-touch-icon.png"
    }

    var hours = jobAtrs.hours;
    var maxDescriptionLength = 140;
    var shortDesc = jobAtrs['translated_text']['short_description'] || jobAtrs['short_description'];
    var description = shortDesc || (jobAtrs['translated_text']['description'] || jobAtrs['description']);
    var name = jobAtrs['translated_text'].name || jobAtrs.name;
    description = truncate(description, maxDescriptionLength);

    innerHTML = formatTemplate(template, '%job_id%', jobID);
    innerHTML = formatTemplate(innerHTML, '%job_company%', company.name);
    innerHTML = formatTemplate(innerHTML, '%job_city%', jobAtrs.city);
    innerHTML = formatTemplate(innerHTML, '%job_name%', name);
    innerHTML = formatTemplate(innerHTML, '%job_company_image_url%', companyImageURL);
    return formatTemplate(innerHTML, '%job_description%', description);
  }

  function truncate(text, maxLength) {
    if (text.length > maxLength) {
      return text.substring(0, maxLength - 3) + '...';
    }
    return text;
  }

  function createCards(targetSelector, templateSelector) {
    var $target = $(targetSelector);
    var $template = $(templateSelector);

    if ($target.length === 0 || $template.length === 0) {
      return;
    }

    var template = $template.html().toString();
    var html = '';

    getJobs(function(jobsData, includedData) {
      jobsData.forEach(function(jobData) {
        var jobId = jobData.id;
        html += formatJobTemplate(template, jobData, includedData, jobId);
      });

      $target.append(html);
    });
  }

  window.JAJobs = {
    createCards: createCards
  };
})(window);
<|endoftext|>


<commit_before>(function(){
	alert("Hello World");
})();<commit_msg>Fixing indentation.<commit_after>(function(){
  alert("Hello World");
})();<|endoftext|>


<commit_before>var teiTable;

/** Add XML files to local storage. */
function uploadFiles(files) {
    showLoading();
    var uniqueFilenames = $('#unique-fn').val() == 'True';
    var pending = files.length;

    for (var i = 0, f; f = files[i]; i++) {
        if (f.type !== 'text/xml') {
            showAlert(f.name + ' is not a valid XML file', 'warning');
            continue;
        }

        var reader = new FileReader();
            reader.onload = (function(theFile) {
                return function(e) {

                // Check for uniqueness
                var key = theFile.name;
                if (localStorage.getItem(theFile.name) && uniqueFilenames) {
                    showAlert('A file with the name ' + theFile.name + ' has \
                              already been uploaded.', 'warning');
                } else if (!uniqueFilenames) {
                    key += Date.now();
                }

                try {
                    //Remove XML declaration (for merging) and store
                    var xmlStr = e.target.result.replace(/<\?xml.*?\?>/g, "");
                    localStorage.setItem(key, xmlStr);
                } catch (e) {
                    hideLoading();
                    showAlert("Upload failed, local storage quota \
                              exceeded. The currently loaded files must be \
                              cleared before more can be uploaded.", 'danger');
                    throw new Error(e)
                }

                --pending
                if (pending == 0) {
                    refreshView();
                }
            };
        })(f);
        reader.readAsText(f);
    }
}

/** Show loading icon. */
function showLoading() {
    $('#files-uploaded').hide();
    $('#loading-icon').show();
}

/** Hide loading icon. */
function hideLoading() {
    $('#loading-icon').hide();
    $('#files-uploaded').show();
}

/** Hide column menu item clicked. */
$( "#hide-menu" ).on('click', '.hide-column', function(e) {
    var index = parseInt($(this).attr('data-index'));
    teiTable.hideColumn(index);
    refreshView();
    e.preventDefault();
});

/** Show column menu item clicked. */
$( "#show-menu" ).on('click', '.show-column', function(e) {
    var index = parseInt($(this).attr('data-index'));
    teiTable.showColumn(index);
    refreshView();
    e.preventDefault();
});

/** Hide borders menu item clicked. */
$( "#hide-borders" ).on('click', function(e) {
    teiTable.hideBorders();
    var settings = Cookies.getJSON('settings');
    settings.showBorders = false;
    Cookies.set('settings', settings);
    e.preventDefault();
});

/** Show borders menu item clicked. */
$( "#show-borders" ).on('click', function(e) {
    teiTable.showBorders();
    var settings = Cookies.getJSON('settings');
    settings.showBorders = true;
    Cookies.set('settings', settings);
    e.preventDefault();
});

/** Freeze header menu item clicked. */
$("#freeze-header").on('click', function(e) {
    $('#table-scroll').addClass('fixed');
    var settings = Cookies.getJSON('settings');
    settings.freezeHeader = true;
    Cookies.set('settings', settings);
    refreshView();
});

/** Unfreeze header menu item clicked. */
$("#unfreeze-header").on('click', function(e) {
    $('#table-scroll').removeClass('fixed');
    var settings = Cookies.getJSON('settings');
    settings.freezeHeader = false;
    Cookies.set('settings', settings);
    refreshView();
});

/** Refresh the main view. */
function refreshView() {
    showLoading();
    if (typeof(teiTable) !== 'undefined' && !teiTable.XSLTProcLoaded()) {
        showAlert('XSLT processor not loaded, please try again.', 'warning');
    } else if(localStorage.length > 0) {
        var mergedXML = mergeUploadedDocs();
        $('.upload-box').hide();
        $('#table-scroll').show();
        teiTable.populate(mergedXML);
        var settings = Cookies.getJSON('settings');
        if (settings.showBorders) {
            teiTable.showBorders();
        } else {
            teiTable.hideBorders();
        }
    } else {
        $('.upload-box').show();
        $('#table-scroll').hide();
    }
    $('#files-uploaded').html(localStorage.length + ' files uploaded');
    $('.upload-form').trigger("reset");
    enableSettings();
    hideLoading();
}

/** Enable or disable settings certain settings if local storage is empty. */
function enableSettings() {
    if (localStorage.length == 0){
        $('#unique-fn').attr('disabled', false);
        $('#reset-settings').attr('disabled', false);
        $('#disabled-settings-msg').hide();
    } else {
        $('#unique-fn').attr('disabled', true);
        $('#reset-settings').attr('disabled', true);
        $('#disabled-settings-msg').show();
    }
    $('#unique-fn').selectpicker('refresh');
}

/** Return all uploaded files merged into single XML document. */
function mergeUploadedDocs(){
    var xmlStr, values = [], keys = Object.keys(localStorage), i = keys.length;
    while ( i-- ) {
        values.push(localStorage.getItem(keys[i]));
    }
    xmlStr = '<MERGED-TEI>' + values.join("") + '</MERGED-TEI>';
    return loadXMLDoc(xmlStr);
}

/** Display a Bootstrap alert. */
function showAlert(msg, type) {
    var template = $("#alert-template").html();
        rendered = Mustache.render(template, {msg: msg, type: type});
    $( "#alerts" ).html(rendered);
}

/** Clear local storage and refresh views. */
$( "#clear-views" ).click(function() {
    showLoading();
    localStorage.clear();
    refreshView();
});

/** Refresh the current XSLT processors. */
function refreshXSLTProcessor() {
    showLoading();
    var tableXSLT = $('#select-xslt').val();
    var tablePromise = Promise.resolve($.ajax({
        url: "assets/xslt/" + tableXSLT
    })).then(function(data) {
        XSLTProc = new XSLTProcessor();
        XSLTProc.importStylesheet(data);
        teiTable = new TeiTable();
        teiTable.updateXSLTProc(XSLTProc)
    }).catch(function() {
        showAlert('XSLT file ' + tableXSLT + ' could not be loaded.',
                  'danger');
    }).then(function() {
        hideLoading();
        refreshView();
    });
}

/** Export the table to CSV. */
$( "#csv-export" ).click(function() {

    // Return an escaped CSV string
    function formatCSV(str) {
        return '"' + str.replace(/"/g, '""') + '"';
    }

    // Get table rows
    var rows = [];
    $('table tr').each(function() {
        var row = [];
        $(this).find('th,td').each(function () {
            var val = $(this)[0].innerText;
            row.push(formatCSV(val));
        });
        rows.push(row.join(','));
    });

    var csvString = rows.join("\n");
    var encodedUri = encodeURI('data:attachment/csv;charset=utf-8,\uFEFF' + csvString);
    var link = document.createElement("a");
    link.setAttribute("href", encodedUri);
    link.setAttribute("download", "tei_data.csv");
    link.click();
});

/** Load and return an XML document. */
function loadXMLDoc(text) {
    var parseXml;
    if (typeof window.DOMParser != "undefined") {
        parseXml = function(xmlStr) {
            return (new window.DOMParser()).parseFromString(xmlStr, "text/xml");
        };
    } else if (typeof window.ActiveXObject != "undefined" &&
        new window.ActiveXObject("Microsoft.XMLDOM")) {
        parseXml = function(xmlStr) {
            var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = "false";
            xmlDoc.loadXML(xmlStr);
            return xmlDoc;
        };
    } else {
        hideLoading();
        var msg = "No XML parser found";
        showAlert(msg, 'danger')
        throw new Error(msg);
    }
    return parseXml(text);
}

//Function to convert boolean to capitalized string
Boolean.prototype.toCapsString = function () {
    return this.toString().charAt(0).toUpperCase() + this.toString().slice(1);
}

/** Reset to default settings. */
$( "#reset-settings" ).click(function() {
    loadDefaultSettings();
    $('#settings-modal').modal('hide');
    showAlert('All settings have been reset to their defaults.', 'info');
    refreshView();
});

/** Handle change of XSLT setting. */
$( "#select-xslt" ).change(function() {
    showLoading();
    var settings = Cookies.getJSON('settings');
    var defaultXSLT = $('#select-xslt').val();
    $.each(settings.xslt, function(index, value) {
        if (value.label == defaultXSLT) {
            value.default = true;
        } else {
            value.default = false;
        }
    });
    Cookies.set('settings', settings);
    $('#settings-modal').modal('hide');
    refreshXSLTProcessor();
});

/** Handle change of unique filenames setting. */
$( "#unique-fn" ).change(function() {
    var settings = Cookies.getJSON('settings');
    var uniqueFn = $('#unique-fn').val() == 'True';
    settings.uniqueFilenames = uniqueFn;
    Cookies.set('settings', settings);
    $('#settings-modal').modal('hide');
});

/** Load and validate settings from cookie. */
function loadSettings(){
    showLoading();
    var settings = Cookies.getJSON('settings');

    $.getJSON("settings.json", function(defaultSettings) {
        var aKeys = Object.keys(defaultSettings).sort();
        var bKeys = Object.keys(settings).sort();
        if(JSON.stringify(aKeys) !== JSON.stringify(bKeys)) {
            Cookies.set('settings', defaultSettings);
            settings = defaultSettings;
            showAlert('Custom settings no longer valid, reverting to \
                      defaults.', 'info');
        }
    }).done(function() {

        // XSLT
        var template = $("#xslt-options-template").html(),
            rendered = Mustache.render(template, {options: settings.xslt});
        $('#select-xslt').html(rendered);

        // Unique filenames
        var uniqueFn = settings.uniqueFilenames.toCapsString()
        $('#unique-fn').val(uniqueFn);

        // Frozen table header
        if (settings.freezeHeader) {
            $('#table-scroll').addClass('fixed');
        }

        $('.selectpicker').selectpicker('refresh');
        refreshXSLTProcessor();
    }).fail(function(e) {
        showAlert('settings.json could not be loaded.', 'danger');
        throw e
    }).always(function() {
        hideLoading();
    });
}

/** Load default settings. */
function loadDefaultSettings() {
    showLoading();
    $.getJSON("settings.json", function( settings ) {
        Cookies.set('settings', settings);
        loadSettings();
    }).done(function() {
        refreshXSLTProcessor();
    }).fail(function(e) {
        showAlert('settings.json could not be loaded.', 'danger');
        throw e
    }).always(function() {
        hideLoading();
    });
}

/** Load README.md into the help modal. */
$("#help-modal").on("show.bs.modal", function() {
    var modalBody = $(this).find(".modal-body");
    $.get("README.md", function( readme ) {
        var converter = new showdown.Converter();
        var text = readme.replace(/[\s\S]+?(?=#)/, "");
        var html = converter.makeHtml(text);
        modalBody.html(html);
    });
});

/** Check for the required HTML5 features */
function checkHTML5() {
    var unsupportedFeatures = []
    if (typeof(localStorage) == 'undefined' ) {
        unsupportedFeatures.push('localStorage.');
    }
    if (typeof(FileReader) == 'undefined' || typeof(FileList) == 'undefined'
        || typeof(Blob) == 'undefined') {
        unsupportedFeatures.push('File APIs');
    }
    if (typeof(Promise) == 'undefined') {
        unsupportedFeatures.push('Promises');
    }
    var div = document.createElement('div');
    if (!('draggable' in div) || !('ondragstart' in div && 'ondrop' in div)) {
        unsupportedFeatures.push('Drag and Drop');
    }
    if (unsupportedFeatures.length > 0) {
        var uStr = unsupportedFeatures.pop();
        if (unsupportedFeatures.length > 0) {
            uStr = unsupportedFeatures.join(', ') + ' or ' + uStr;
        }
        showAlert('Your browser does not support HTML5 ' + uStr + '. \
                   Try upgrading (Firefox 45, Chrome 45 or Safari 9 \
                   recommended).', 'danger');
        throw new Error("HTML5 " + uStr + " not supported.");
    }
}

/** Handle add files event. */
$( ".add-files" ).change(function(evt) {
    var files = evt.target.files;
    uploadFiles(files);
});

/** Handle upload box drag and drop event. */
$('.upload-box').on('drag dragstart dragend dragover dragenter dragleave drop', function(e) {
    e.preventDefault();
    e.stopPropagation();
}).on('dragover dragenter', function() {
    $('.upload-box').addClass('is-dragover');
}).on('dragleave dragend drop', function() {
    $('.upload-box').removeClass('is-dragover');
}).on('drop', function(e) {
    var files = e.originalEvent.dataTransfer.files;
    uploadFiles(files);
});

/** Handle table scroll event. */
$("#table-scroll").scroll(function() {
    if (typeof(teiTable) !== 'undefined') {
        teiTable.fixFrozenTable();
    }
});

/** Handle window resize event. */
$(window).resize(function() {
    if (typeof(teiTable) !== 'undefined') {
        teiTable.fixFrozenTable();
    }
});

$(function() {
    $.ajaxSetup({ cache: false });
    checkHTML5();

    // Initialise settings
    if (typeof Cookies.get('settings') != "undefined") {
        loadSettings();
    } else {
        loadDefaultSettings();
    }
});<commit_msg>Update alert message<commit_after>var teiTable;

/** Add XML files to local storage. */
function uploadFiles(files) {
    showLoading();
    var uniqueFilenames = $('#unique-fn').val() == 'True';
    var pending = files.length;

    for (var i = 0, f; f = files[i]; i++) {
        if (f.type !== 'text/xml') {
            showAlert(f.name + ' is not a valid XML file', 'warning');
            continue;
        }

        var reader = new FileReader();
            reader.onload = (function(theFile) {
                return function(e) {

                // Check for uniqueness
                var key = theFile.name;
                if (localStorage.getItem(theFile.name) && uniqueFilenames) {
                    showAlert('A file with the name ' + theFile.name + ' has \
                              already been uploaded.', 'warning');
                } else if (!uniqueFilenames) {
                    key += Date.now();
                }

                try {
                    //Remove XML declaration (for merging) and store
                    var xmlStr = e.target.result.replace(/<\?xml.*?\?>/g, "");
                    localStorage.setItem(key, xmlStr);
                } catch (e) {
                    hideLoading();
                    showAlert("Upload failed, local storage quota \
                              exceeded. The currently loaded files must be \
                              cleared before more can be uploaded.", 'danger');
                    throw new Error(e)
                }

                --pending
                if (pending == 0) {
                    refreshView();
                }
            };
        })(f);
        reader.readAsText(f);
    }
}

/** Show loading icon. */
function showLoading() {
    $('#files-uploaded').hide();
    $('#loading-icon').show();
}

/** Hide loading icon. */
function hideLoading() {
    $('#loading-icon').hide();
    $('#files-uploaded').show();
}

/** Hide column menu item clicked. */
$( "#hide-menu" ).on('click', '.hide-column', function(e) {
    var index = parseInt($(this).attr('data-index'));
    teiTable.hideColumn(index);
    refreshView();
    e.preventDefault();
});

/** Show column menu item clicked. */
$( "#show-menu" ).on('click', '.show-column', function(e) {
    var index = parseInt($(this).attr('data-index'));
    teiTable.showColumn(index);
    refreshView();
    e.preventDefault();
});

/** Hide borders menu item clicked. */
$( "#hide-borders" ).on('click', function(e) {
    teiTable.hideBorders();
    var settings = Cookies.getJSON('settings');
    settings.showBorders = false;
    Cookies.set('settings', settings);
    e.preventDefault();
});

/** Show borders menu item clicked. */
$( "#show-borders" ).on('click', function(e) {
    teiTable.showBorders();
    var settings = Cookies.getJSON('settings');
    settings.showBorders = true;
    Cookies.set('settings', settings);
    e.preventDefault();
});

/** Freeze header menu item clicked. */
$("#freeze-header").on('click', function(e) {
    $('#table-scroll').addClass('fixed');
    var settings = Cookies.getJSON('settings');
    settings.freezeHeader = true;
    Cookies.set('settings', settings);
    refreshView();
});

/** Unfreeze header menu item clicked. */
$("#unfreeze-header").on('click', function(e) {
    $('#table-scroll').removeClass('fixed');
    var settings = Cookies.getJSON('settings');
    settings.freezeHeader = false;
    Cookies.set('settings', settings);
    refreshView();
});

/** Refresh the main view. */
function refreshView() {
    showLoading();
    if (typeof(teiTable) !== 'undefined' && !teiTable.XSLTProcLoaded()) {
        showAlert('XSLT processor not loaded, please try again.', 'warning');
    } else if(localStorage.length > 0) {
        var mergedXML = mergeUploadedDocs();
        $('.upload-box').hide();
        $('#table-scroll').show();
        teiTable.populate(mergedXML);
        var settings = Cookies.getJSON('settings');
        if (settings.showBorders) {
            teiTable.showBorders();
        } else {
            teiTable.hideBorders();
        }
    } else {
        $('.upload-box').show();
        $('#table-scroll').hide();
    }
    $('#files-uploaded').html(localStorage.length + ' files uploaded');
    $('.upload-form').trigger("reset");
    enableSettings();
    hideLoading();
}

/** Enable or disable settings certain settings if local storage is empty. */
function enableSettings() {
    if (localStorage.length == 0){
        $('#unique-fn').attr('disabled', false);
        $('#reset-settings').attr('disabled', false);
        $('#disabled-settings-msg').hide();
    } else {
        $('#unique-fn').attr('disabled', true);
        $('#reset-settings').attr('disabled', true);
        $('#disabled-settings-msg').show();
    }
    $('#unique-fn').selectpicker('refresh');
}

/** Return all uploaded files merged into single XML document. */
function mergeUploadedDocs(){
    var xmlStr, values = [], keys = Object.keys(localStorage), i = keys.length;
    while ( i-- ) {
        values.push(localStorage.getItem(keys[i]));
    }
    xmlStr = '<MERGED-TEI>' + values.join("") + '</MERGED-TEI>';
    return loadXMLDoc(xmlStr);
}

/** Display a Bootstrap alert. */
function showAlert(msg, type) {
    var template = $("#alert-template").html();
        rendered = Mustache.render(template, {msg: msg, type: type});
    $( "#alerts" ).html(rendered);
}

/** Clear local storage and refresh views. */
$( "#clear-views" ).click(function() {
    showLoading();
    localStorage.clear();
    refreshView();
});

/** Refresh the current XSLT processors. */
function refreshXSLTProcessor() {
    showLoading();
    var tableXSLT = $('#select-xslt').val();
    var tablePromise = Promise.resolve($.ajax({
        url: "assets/xslt/" + tableXSLT
    })).then(function(data) {
        XSLTProc = new XSLTProcessor();
        XSLTProc.importStylesheet(data);
        teiTable = new TeiTable();
        teiTable.updateXSLTProc(XSLTProc)
    }).catch(function() {
        showAlert('XSLT file ' + tableXSLT + ' could not be loaded, try \
                  reverting to default settings.', 'danger');
    }).then(function() {
        hideLoading();
        refreshView();
    });
}

/** Export the table to CSV. */
$( "#csv-export" ).click(function() {

    // Return an escaped CSV string
    function formatCSV(str) {
        return '"' + str.replace(/"/g, '""') + '"';
    }

    // Get table rows
    var rows = [];
    $('table tr').each(function() {
        var row = [];
        $(this).find('th,td').each(function () {
            var val = $(this)[0].innerText;
            row.push(formatCSV(val));
        });
        rows.push(row.join(','));
    });

    var csvString = rows.join("\n");
    var encodedUri = encodeURI('data:attachment/csv;charset=utf-8,\uFEFF' + csvString);
    var link = document.createElement("a");
    link.setAttribute("href", encodedUri);
    link.setAttribute("download", "tei_data.csv");
    link.click();
});

/** Load and return an XML document. */
function loadXMLDoc(text) {
    var parseXml;
    if (typeof window.DOMParser != "undefined") {
        parseXml = function(xmlStr) {
            return (new window.DOMParser()).parseFromString(xmlStr, "text/xml");
        };
    } else if (typeof window.ActiveXObject != "undefined" &&
        new window.ActiveXObject("Microsoft.XMLDOM")) {
        parseXml = function(xmlStr) {
            var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = "false";
            xmlDoc.loadXML(xmlStr);
            return xmlDoc;
        };
    } else {
        hideLoading();
        var msg = "No XML parser found";
        showAlert(msg, 'danger')
        throw new Error(msg);
    }
    return parseXml(text);
}

//Function to convert boolean to capitalized string
Boolean.prototype.toCapsString = function () {
    return this.toString().charAt(0).toUpperCase() + this.toString().slice(1);
}

/** Reset to default settings. */
$( "#reset-settings" ).click(function() {
    loadDefaultSettings();
    $('#settings-modal').modal('hide');
    showAlert('All settings have been reset to their defaults.', 'info');
    refreshView();
});

/** Handle change of XSLT setting. */
$( "#select-xslt" ).change(function() {
    showLoading();
    var settings = Cookies.getJSON('settings');
    var defaultXSLT = $('#select-xslt').val();
    $.each(settings.xslt, function(index, value) {
        if (value.label == defaultXSLT) {
            value.default = true;
        } else {
            value.default = false;
        }
    });
    Cookies.set('settings', settings);
    $('#settings-modal').modal('hide');
    refreshXSLTProcessor();
});

/** Handle change of unique filenames setting. */
$( "#unique-fn" ).change(function() {
    var settings = Cookies.getJSON('settings');
    var uniqueFn = $('#unique-fn').val() == 'True';
    settings.uniqueFilenames = uniqueFn;
    Cookies.set('settings', settings);
    $('#settings-modal').modal('hide');
});

/** Load and validate settings from cookie. */
function loadSettings(){
    showLoading();
    var settings = Cookies.getJSON('settings');

    $.getJSON("settings.json", function(defaultSettings) {
        var aKeys = Object.keys(defaultSettings).sort();
        var bKeys = Object.keys(settings).sort();
        if(JSON.stringify(aKeys) !== JSON.stringify(bKeys)) {
            Cookies.set('settings', defaultSettings);
            settings = defaultSettings;
            showAlert('Custom settings no longer valid, reverting to \
                      defaults.', 'info');
        }
    }).done(function() {

        // XSLT
        var template = $("#xslt-options-template").html(),
            rendered = Mustache.render(template, {options: settings.xslt});
        $('#select-xslt').html(rendered);

        // Unique filenames
        var uniqueFn = settings.uniqueFilenames.toCapsString()
        $('#unique-fn').val(uniqueFn);

        // Frozen table header
        if (settings.freezeHeader) {
            $('#table-scroll').addClass('fixed');
        }

        $('.selectpicker').selectpicker('refresh');
        refreshXSLTProcessor();
    }).fail(function(e) {
        showAlert('settings.json could not be loaded.', 'danger');
        throw e
    }).always(function() {
        hideLoading();
    });
}

/** Load default settings. */
function loadDefaultSettings() {
    showLoading();
    $.getJSON("settings.json", function( settings ) {
        Cookies.set('settings', settings);
        loadSettings();
    }).done(function() {
        refreshXSLTProcessor();
    }).fail(function(e) {
        showAlert('settings.json could not be loaded.', 'danger');
        throw e
    }).always(function() {
        hideLoading();
    });
}

/** Load README.md into the help modal. */
$("#help-modal").on("show.bs.modal", function() {
    var modalBody = $(this).find(".modal-body");
    $.get("README.md", function( readme ) {
        var converter = new showdown.Converter();
        var text = readme.replace(/[\s\S]+?(?=#)/, "");
        var html = converter.makeHtml(text);
        modalBody.html(html);
    });
});

/** Check for the required HTML5 features */
function checkHTML5() {
    var unsupportedFeatures = []
    if (typeof(localStorage) == 'undefined' ) {
        unsupportedFeatures.push('localStorage.');
    }
    if (typeof(FileReader) == 'undefined' || typeof(FileList) == 'undefined'
        || typeof(Blob) == 'undefined') {
        unsupportedFeatures.push('File APIs');
    }
    if (typeof(Promise) == 'undefined') {
        unsupportedFeatures.push('Promises');
    }
    var div = document.createElement('div');
    if (!('draggable' in div) || !('ondragstart' in div && 'ondrop' in div)) {
        unsupportedFeatures.push('Drag and Drop');
    }
    if (unsupportedFeatures.length > 0) {
        var uStr = unsupportedFeatures.pop();
        if (unsupportedFeatures.length > 0) {
            uStr = unsupportedFeatures.join(', ') + ' or ' + uStr;
        }
        showAlert('Your browser does not support HTML5 ' + uStr + '. \
                   Try upgrading (Firefox 45, Chrome 45 or Safari 9 \
                   recommended).', 'danger');
        throw new Error("HTML5 " + uStr + " not supported.");
    }
}

/** Handle add files event. */
$( ".add-files" ).change(function(evt) {
    var files = evt.target.files;
    uploadFiles(files);
});

/** Handle upload box drag and drop event. */
$('.upload-box').on('drag dragstart dragend dragover dragenter dragleave drop', function(e) {
    e.preventDefault();
    e.stopPropagation();
}).on('dragover dragenter', function() {
    $('.upload-box').addClass('is-dragover');
}).on('dragleave dragend drop', function() {
    $('.upload-box').removeClass('is-dragover');
}).on('drop', function(e) {
    var files = e.originalEvent.dataTransfer.files;
    uploadFiles(files);
});

/** Handle table scroll event. */
$("#table-scroll").scroll(function() {
    if (typeof(teiTable) !== 'undefined') {
        teiTable.fixFrozenTable();
    }
});

/** Handle window resize event. */
$(window).resize(function() {
    if (typeof(teiTable) !== 'undefined') {
        teiTable.fixFrozenTable();
    }
});

$(function() {
    $.ajaxSetup({ cache: false });
    checkHTML5();

    // Initialise settings
    if (typeof Cookies.get('settings') != "undefined") {
        loadSettings();
    } else {
        loadDefaultSettings();
    }
});<|endoftext|>


<commit_before>

var alarmDS = isc.RestDataSource.create({
  autoFetchData: false,
  dataFormat: 'custom',
  recordXPath: 'results',
  bypassCache: false,
  dataURL: "http://33.33.33.10:8001/api/v1/alarmsettings",
  fields:[
    {name: "id", title:"id", hidden: true},
    {name: "active_status", title: "actief", type: "boolean", width:35},
    {name: "name", title:"Naam"},
    {name: "object_id", title:"user_id", width: 50},
    {name: "frequency", title:"Frequentie", width: 60,
      valueMap: ['5 min', '10 min', '15 min', '30 min', '1 hr', '6 hr', '12 hr', '24 hr']
    },
    {name: "urgency", title:"Urgentie", width: 50, valueMap: ['High', 'Low']},
    {name: "message_type", title: "Notificatie", width: 80, valueMap: ['Email', 'SMS', 'Email and SMS']},
    {name: 'template', title: 'Template', hidden: true},
    {name: 'logical_check', title: 'Logische controle', valueMap: ['All', 'At least one'], hidden: true}
  ],
  transformRequest: function(dsRequest) {
    dsRequest.httpHeaders = {
      "Accept" : "application/json"
    }
  },
  transformResponse: function(dsResponse) {
    var json_data = isc.JSON.decode(dsResponse.data);
    dsResponse.totalRows = json_data.count;
    dsResponse.data = json_data.results;
  }
});

var alarmList = isc.ListGrid.create({
  //ID: "alarmList",
  width:700,
  alternateRecordStyles:true,
  autoFetchData: true,
  dataSource: alarmDS,
  rowClick: function(record) {
    RPCManager.sendRequest({
      actionURL: record.url,
      httpMethod: 'GET',
      callback: function(rpcResponse, data, rpcRequest) {
        data = isc.JSON.decode(data);
        alarmForm.setData(data);
        alarmItemList.setData(data.alarm_item_set);
      }
    });
  },
  canReorderFields: true
});

var alarmForm = isc.DynamicForm.create({
  //ID: "alarmForm",
  autoDraw: false,
  dataSource: alarmDS,
  width: 350,
  numCols: 2,
  colWidths: [100, 250],
  fields: [
    {type: 'header', defaultValue: "Alarm instellingen"},
    {name:"id", title:"id", canEdit: false},
    {name: "active_status", title: "actief", type: "boolean" , width: 300},
    {name:"name", width: "*"},
    {name:"frequency", width: "*"},
    {name:"urgency", width: "*"},
    {name: "message_type", width: "*"},
    {name: 'template', type: 'textArea', width: "*"},
    {type: 'header', defaultValue: "Regels"},
    {name: 'logical_check', width: "*"}
  ]
});

var alarmItemList = isc.ListGrid.create({
  //ID: "alarmItemList",
  width:700,
  autoFitMaxRecords: 5,
  autoFitData: "vertical",
  alternateRecordStyles: true,
  canEdit: true,
  editEvent: "click",
  fields:[
    {name: "alarm_type", title: "alarm type", type: "text", width:80, valueMap: ['timeseries', 'location', 'logical group']},
    {name: "object_id", title: "object_id", type: "text", width:50},
    {name: "id", title:"id", showIf: function() { return false; }},
    {name: "name", title:"Naam", showIf: function() { return false; }},
    {name: 'logical_check', title: 'wat', valueMap: ['All', 'At least one'], width: 50},
    {name: "value_type", title:"controle op", valueMap: ['a. Waarde', 'b. Status - Aantal metingen',
      'c. Status - Percentage betrouwbare waarden',
      'd. Status - Percentage twijfelachtige waarden', 'e. Status - Percentage onbetrouwbare waarden',
      'f. Status - Minimum meetwaarde', 'g. Status - Maximum meetwaarde', 'h. Status - Gemiddelde meetwaarde',
      'i. Status - Standaard deviatie', 'j. Status - Tijd sinds laatste meting',
      'k. Status - Procentuele afwijking van het aantal te verwachten metingen']
    },
    {name: 'comparision', title: 'vergelijking', valueMap: ['==', '!=', '>', '<'], width: 50},
    {name: "value_double", title:"decimaal", type: 'number', width: 50},
    {name: "value_int", title:"geheel getal", type: 'number', width: 50},
    {name: "value_text", title: "tekst", type: "text", width: 80},
    {name: "value_bool", title: "ja/nee", type: "boolean", width:50}
  ]
});

var saveAlarm = function(isNew) {
  //todo: validation

  var data = alarmForm.getData();
  data.alarm_item_set = alarmItemList.getData();

  if (isNew) {
    alarmForm.setValue('id', null);
    //todo: set alarmItem id's on null
    var method = 'POST';
    var url = "http://33.33.33.10:8001/api/v1/alarmsettings";
  } else {
    var method = 'PUT';
    var url = data.url;
  }

  RPCManager.sendRequest({
    actionURL: url,
    httpMethod: method,
    data: data,
    params: data,
    httpHeaders: {
      'X-CSRFToken': document.cookie.split('=')[1]
    },
    callback: function(rpcResponse, data, rpcRequest) {

      if (rpcResponse.httpResponseCode == 200) {
        console.log('opslaan gelukt');
        var data = isc.JSON.decode(data);
        alarmForm.setData(data);
        alarmItemList.setData(data.alarm_item_set);

      } else if (rpcResponse.httpResponseCode == 201) {
        console.log('aanmaken nieuw object gelukt');
        data = isc.JSON.decode(data);
        alarmForm.setData(data);
        alarmItemList.setData(data.alarm_item_set);

      } else if (rpcResponse.httpResponseCode == 400) {
        alarmForm.setErrors(isc.JSON.decode(rpcResponse.httpResponseText), true);
        alert('validatie mislukt');

      } else {
        alert('Opslaan mislukt. ' + data);
      }
    }
  });
}

alarmPage = isc.HLayout.create({
  autoDraw: false,
  members: [
    alarmList,
    isc.VLayout.create({
      padding: 10,
      members: [
        alarmForm,
        alarmItemList,
        isc.HLayout.create({
          members: [
            isc.IButton.create({
              title:"Regel toevoegen",
              click:"alarmItemList.startEditingNew()"
            }),
            isc.IButton.create({
              title:"Regel verwijderen",
              click: function() {
                if (alarmItemList.getSelectedRecord()) {
                  alarmItemList.data.remove(alarmItemList.getSelectedRecord());
                }
              }
            })
          ]
        }),
        isc.HLayout.create({
          members: [
            isc.IButton.create({
              title: 'Annuleren',
              click: function() {
                alarmForm.setData([]);
                alarmItemList.setData([]);
              }
            }),
            isc.IButton.create({
              title: 'Opslaan',
              click: function() {
                saveAlarm(false);
              }
            }),
            isc.IButton.create({
              title: 'Opslaan als nieuw alarm',
              width: 200,
              click: function() {
                saveAlarm(true);
              }
            }),
            isc.IButton.create({
              title: 'Verwijderen',
              click: function() {
                var id = alarmForm.getValue('id');
                debugger;
                if (id) {
                  RPCManager.sendRequest({
                    actionURL: alarmForm.getData()['url'],
                    httpMethod: 'DELETE',
                    httpHeaders: {
                      'X-CSRFToken': document.cookie.split('=')[1]
                    },
                    callback: function(rpcResponse, data, rpcRequest) {
                      console.log('verwijderen gelukt');
                      alarmForm.setData([]);
                      alarmItemList.setData([]);
                    }
                  });
                }
              }
            })
          ]
        })
      ]
    })
  ]
});<commit_msg>Some improvements to alarmen management page<commit_after>

var alarmDS = isc.RestDataSource.create({
  autoFetchData: false,
  dataFormat: 'custom',
  dataURL: "http://33.33.33.10:8001/api/v1/alarmsettings",
  fields:[
    {name: "id", title:"id", hidden: true},
    {name: "active_status", title: "actief", type: "boolean", width:35},
    {name: "name", title:"Naam"},
    {name: "object_id", title:"user_id", width: 50},
    {name: "frequency", title:"Frequentie", width: 60,
      valueMap: ['5 min', '10 min', '15 min', '30 min', '1 hr', '6 hr', '12 hr', '24 hr']
    },
    {name: "urgency", title:"Urgentie", width: 50, valueMap: ['High', 'Low']},
    {name: "message_type", title: "Notificatie", width: 80, valueMap: ['Email', 'SMS', 'Email and SMS']},
    {name: 'template', title: 'Template', hidden: true},
    {name: 'logical_check', title: 'Logische controle', valueMap: ['All', 'At least one'], hidden: true}
  ],
  transformRequest: function(dsRequest) {
    dsRequest.httpHeaders = {
      "Accept" : "application/json"
    }
    dsRequest.params = {
      page_size: 0
    }
  },
  transformResponse: function(dsResponse) {
    var json_data = isc.JSON.decode(dsResponse.data);
    dsResponse.totalRows = json_data.length;
    dsResponse.data = json_data;
  }
});

var alarmList = isc.ListGrid.create({
  //ID: "alarmList",
  width:700,
  alternateRecordStyles:true,
  autoFetchData: true,
  dataSource: alarmDS,
  rowClick: function(record) {
    RPCManager.sendRequest({
      actionURL: record.url,
      httpMethod: 'GET',
      callback: function(rpcResponse, data, rpcRequest) {
        data = isc.JSON.decode(data);
        alarmForm.setData(data);
        alarmForm.setErrors([]);
        alarmItemList.setData(data.alarm_item_set);
      }
    });
  },
  canReorderFields: true
});

var alarmForm = isc.DynamicForm.create({
  //ID: "alarmForm",
  autoDraw: false,
  dataSource: alarmDS,
  width: 350,
  numCols: 2,
  colWidths: [100, 250],
  fields: [
    {type: 'header', defaultValue: "Alarm instellingen"},
    {name:"id", title:"id", canEdit: false},
    {name: "active_status", title: "actief", type: "boolean" , width: 300},
    {name:"name", width: "*"},
    {name:"frequency", width: "*"},
    {name:"urgency", width: "*"},
    {name: "message_type", width: "*"},
    {name: 'template', type: 'textArea', width: "*"},
    {type: 'header', defaultValue: "Regels"},
    {name: 'logical_check', width: "*"}
  ]
});

var alarmItemList = isc.ListGrid.create({
  //ID: "alarmItemList",
  width:700,
  autoFitMaxRecords: 5,
  autoFitData: "vertical",
  alternateRecordStyles: true,
  canEdit: true,
  editEvent: "click",
  fields:[
    {name: "alarm_type", title: "alarm type", type: "text", width:80, valueMap: ['timeseries', 'location', 'logical group']},
    {name: "object_id", title: "object_id", type: "text", width:50},
    {name: "id", title:"id", showIf: function() { return false; }},
    {name: "name", title:"Naam", showIf: function() { return false; }},
    {name: 'logical_check', title: 'wat', valueMap: ['All', 'At least one'], width: 50},
    {name: "value_type", title:"controle op", valueMap: ['a. Waarde', 'b. Status - Aantal metingen',
      'c. Status - Percentage betrouwbare waarden',
      'd. Status - Percentage twijfelachtige waarden', 'e. Status - Percentage onbetrouwbare waarden',
      'f. Status - Minimum meetwaarde', 'g. Status - Maximum meetwaarde', 'h. Status - Gemiddelde meetwaarde',
      'i. Status - Standaard deviatie', 'j. Status - Tijd sinds laatste meting',
      'k. Status - Procentuele afwijking van het aantal te verwachten metingen']
    },
    {name: 'comparision', title: 'vergelijking', valueMap: ['==', '!=', '>', '<'], width: 50},
    {name: "value_double", title:"decimaal", type: 'number', width: 50},
    {name: "value_int", title:"geheel getal", type: 'number', width: 50},
    {name: "value_text", title: "tekst", type: "text", width: 80},
    {name: "value_bool", title: "ja/nee", type: "boolean", width:50}
  ]
});

var saveAlarm = function(saveAsNew) {
  //todo: validation

  var data = alarmForm.getData();
  data.alarm_item_set = alarmItemList.getData();

  if (saveAsNew || !data.id) {
    alarmForm.setValue('id', null);
    //todo: set alarmItem id's on null
    var method = 'POST';
    var url = "http://33.33.33.10:8001/api/v1/alarmsettings";
  } else {
    var method = 'PUT';
    var url = data.url;
  }
  alarmForm.setErrors([]);

  RPCManager.sendRequest({
    actionURL: url,
    httpMethod: method,
    data: data,
    params: data,
    httpHeaders: {
      'X-CSRFToken': document.cookie.split('=')[1]
    },
    callback: function(rpcResponse, data, rpcRequest) {

      if (rpcResponse.httpResponseCode == 200 || rpcResponse.httpResponseCode == 201) {
        console.log('Gelukt');
        var data = isc.JSON.decode(data);
        alarmForm.setData(data);
        alarmItemList.setData(data.alarm_item_set);
        alarmList.fetchData({test: timestamp()}); //force new fetch with timestamp
        if (rpcResponse.httpResponseCode == 201) {
          //in case of create, the list serializer is used for the return. do extra fetch to get details
          RPCManager.sendRequest({
            actionURL: data.url,
            httpMethod: 'GET',
            callback: function(rpcResponse, data, rpcRequest) {
              data = isc.JSON.decode(data);
              alarmForm.setData(data);
              alarmItemList.setData(data.alarm_item_set);
            }
          });
        }

      } else if (rpcResponse.httpResponseCode == 400) {
        alarmForm.setErrors(isc.JSON.decode(rpcResponse.httpResponseText), true);
        alert('validatie mislukt');

      } else {
        alert('Opslaan mislukt. ' + data);
      }
    }
  });
}

alarmPage = isc.HLayout.create({
  autoDraw: false,
  members: [
    alarmList,
    isc.VLayout.create({
      padding: 10,
      members: [
        alarmForm,
        alarmItemList,
        isc.HLayout.create({
          members: [
            isc.IButton.create({
              title:"Regel toevoegen",
              click:"alarmItemList.startEditingNew()"
            }),
            isc.IButton.create({
              title:"Regel verwijderen",
              click: function() {
                if (alarmItemList.getSelectedRecord()) {
                  alarmItemList.data.remove(alarmItemList.getSelectedRecord());
                }
              }
            })
          ]
        }),
        isc.HLayout.create({
          members: [
            isc.IButton.create({
              title: 'Annuleren',
              click: function() {
                alarmForm.setData([]);
                alarmForm.setErrors([]);
                alarmItemList.setData([]);
              }
            }),
            isc.IButton.create({
              title: 'Nieuw',
              click: function() {
                alarmForm.setData([]);
                alarmForm.setErrors([]);
                alarmItemList.setData([]);
              }
            }),
            isc.IButton.create({
              title: 'Opslaan',
              click: function() {
                saveAlarm(false);
              }
            }),
            isc.IButton.create({
              title: 'Opslaan als nieuw alarm',
              width: 200,
              click: function() {
                saveAlarm(true);
              }
            }),
            isc.IButton.create({
              title: 'Verwijderen',
              click: function() {
                var id = alarmForm.getValue('id');
                if (id) {
                  RPCManager.sendRequest({
                    actionURL: alarmForm.getData()['url'],
                    httpMethod: 'DELETE',
                    httpHeaders: {
                      'X-CSRFToken': document.cookie.split('=')[1]
                    },
                    callback: function(rpcResponse, data, rpcRequest) {
                      console.log('verwijderen gelukt');
                      alarmForm.setData([]);
                      alarmForm.setErrors([]);
                      alarmItemList.setData([]);
                      alarmList.fetchData({test: timestamp()}); //force new fetch with timestamp
                    }
                  });
                }
              }
            })
          ]
        })
      ]
    })
  ]
});<|endoftext|>


<commit_before>

"use strict";
var
  OS = require('os'),
  Net = require('net'),
  CPP = require('childprocess-promise'),
  Debug = require('debug')('happy-db:errors');
class Main{
  constructor(Port){
    this.Port = Number(Port);
    this.Server = null;
    this.Children = [];
    this.Database = new Map();
  }
  Run(){
    let NumCPUs = OS.cpus().length;
    let SupportedEvents = [];

    for(let Name in Main){
      if (typeof Main[Name] === 'function' && Name.substr(0, 6) === 'Action')
        SupportedEvents.push(Name.substr(6));
    }
    for(var i = 0; i < NumCPUs; ++i){
      let Child = new CPP(__dirname + '/../Main.js');
      SupportedEvents.forEach(function(Child, Event){
        Child.on(Event, function(Request, Message){
          try {
            Message.Result = Main['Action' + Event].call(this, Request, Child, Message);
          } catch(error){
            Debug(error.stack);
            Message.Result = {Type: 'Error', Message: error.message};
          }
          Child.Finished(Message);
        }.bind(this));
      }.bind(this, Child));
      Child.Send('SupportedEvents', SupportedEvents);
      this.Children.push(Child);
    }
    let Server = this.Server = Net.createServer();
    this.Server.listen(this.Port, this.Children.forEach.bind(this.Children, function(Child){
      Child.Target.send('Server', Server);
    }));
  }

  static NormalizeType(Value){
    let ValueInt = parseInt(Value);
    if(!isNaN(ValueInt) && ValueInt.toString() === Value){
      return ValueInt;
    }
    return Value;
  }
  static Validate(Type, Action, Value){
    if(Type === Main.VAL_NUMERIC){
      if(typeof Value !== 'number')
        throw new Error(`Cant ${Action} Non-Numeric Item`);
    } else if(Type === Main.VAL_STRINGISH){
      if(typeof Value !== 'string' && typeof Value !== 'number')
        throw new Error(`Cant ${Action} Non-Stringish Item`);
    } else if(Type === Main.VAL_HASH){
      if(typeof Value !== 'object' || !Value.constructor || !Value.constructor.name === 'Map')
        throw new Error(`Cant ${Action} Non-Hash Item`);
    } else if(Type === Main.VAL_LIST){
      if(typeof Value !== 'object' || !Value.constructor || !Value.constructor.name === 'Set')
        throw new Error(`Cant ${Action} Non-List Item`);
    }
    return Value;
  }
  static ValidateArguments(TypeOrLength, Length){
    if(typeof TypeOrLength === 'string'){
      let IsOdd = Length % 2;
      if(TypeOrLength === Main.ARGS_EVEN && IsOdd)
        throw new Error(Main.MSG_ARGS_INVALID + '; Expected Even');
      else if(TypeOrLength === Main.ARGS_ODD && !IsOdd){
        throw new Error(Main.MSG_ARGS_INVALID + '; Expected Odd');
      }
    } else{
      if(TypeOrLength > Length){
        throw new Error(Main.MSG_ARGS_MORE);
      } else if(TypeOrLength < Length){
        throw new Error(Main.MSG_ARGS_LESS);
      }
    }
  }
}

Main.VAL_NUMERIC = 'VAL_NUMERIC';
Main.VAL_STRINGISH = 'VAL_STRING';
Main.VAL_HASH = 'VAL_HASH';
Main.VAL_LIST = 'VAL_LIST';

Main.MSG_ARGS_MORE = 'Too Many Arguments';
Main.MSG_ARGS_LESS = 'Too less Arguments';
Main.MSG_ARGS_INVALID = 'Invalid Number of Arguments';

Main.ARGS_EVEN = 'EVEN';
Main.ARGS_ODD = 'ODD';

Main.prototype.Timeouts = {};

module.exports = Main;

// Load the functions
require('./Methods_Basic');
require('./Methods_Hash');<commit_msg>:art: Log Function calls with Debug<commit_after>

"use strict";
var
  OS = require('os'),
  Net = require('net'),
  CPP = require('childprocess-promise'),
  DebugErrors = require('debug')('happy-db:errors'),
  Debug = require('debug')('happy-db:calls');
class Main{
  constructor(Port){
    this.Port = Number(Port);
    this.Server = null;
    this.Children = [];
    this.Database = new Map();
  }
  Run(){
    let NumCPUs = OS.cpus().length;
    let SupportedEvents = [];

    for(let Name in Main){
      if (typeof Main[Name] === 'function' && Name.substr(0, 6) === 'Action')
        SupportedEvents.push(Name.substr(6));
    }
    for(var i = 0; i < NumCPUs; ++i){
      let Child = new CPP(__dirname + '/../Main.js');
      SupportedEvents.forEach(function(Child, Event){
        Child.on(Event, function(Request, Message){
          try {
            Debug(Event);
            Message.Result = Main['Action' + Event].call(this, Request, Child, Message);
          } catch(error){
            DebugErrors(error.stack);
            Message.Result = {Type: 'Error', Message: error.message};
          }
          Child.Finished(Message);
        }.bind(this));
      }.bind(this, Child));
      Child.Send('SupportedEvents', SupportedEvents);
      this.Children.push(Child);
    }
    let Server = this.Server = Net.createServer();
    this.Server.listen(this.Port, this.Children.forEach.bind(this.Children, function(Child){
      Child.Target.send('Server', Server);
    }));
  }

  static NormalizeType(Value){
    let ValueInt = parseInt(Value);
    if(!isNaN(ValueInt) && ValueInt.toString() === Value){
      return ValueInt;
    }
    return Value;
  }
  static Validate(Type, Action, Value){
    if(Type === Main.VAL_NUMERIC){
      if(typeof Value !== 'number')
        throw new Error(`Cant ${Action} Non-Numeric Item`);
    } else if(Type === Main.VAL_STRINGISH){
      if(typeof Value !== 'string' && typeof Value !== 'number')
        throw new Error(`Cant ${Action} Non-Stringish Item`);
    } else if(Type === Main.VAL_HASH){
      if(typeof Value !== 'object' || !Value.constructor || !Value.constructor.name === 'Map')
        throw new Error(`Cant ${Action} Non-Hash Item`);
    } else if(Type === Main.VAL_LIST){
      if(typeof Value !== 'object' || !Value.constructor || !Value.constructor.name === 'Set')
        throw new Error(`Cant ${Action} Non-List Item`);
    }
    return Value;
  }
  static ValidateArguments(TypeOrLength, Length){
    if(typeof TypeOrLength === 'string'){
      let IsOdd = Length % 2;
      if(TypeOrLength === Main.ARGS_EVEN && IsOdd)
        throw new Error(Main.MSG_ARGS_INVALID + '; Expected Even');
      else if(TypeOrLength === Main.ARGS_ODD && !IsOdd){
        throw new Error(Main.MSG_ARGS_INVALID + '; Expected Odd');
      }
    } else{
      if(TypeOrLength > Length){
        throw new Error(Main.MSG_ARGS_MORE);
      } else if(TypeOrLength < Length){
        throw new Error(Main.MSG_ARGS_LESS);
      }
    }
  }
}

Main.VAL_NUMERIC = 'VAL_NUMERIC';
Main.VAL_STRINGISH = 'VAL_STRING';
Main.VAL_HASH = 'VAL_HASH';
Main.VAL_LIST = 'VAL_LIST';

Main.MSG_ARGS_MORE = 'Too Many Arguments';
Main.MSG_ARGS_LESS = 'Too less Arguments';
Main.MSG_ARGS_INVALID = 'Invalid Number of Arguments';

Main.ARGS_EVEN = 'EVEN';
Main.ARGS_ODD = 'ODD';

Main.prototype.Timeouts = {};

module.exports = Main;

// Load the functions
require('./Methods_Basic');
require('./Methods_Hash');<|endoftext|>


<commit_before>"use strict"
let Chart = {
  a: 'array',                                 // Done
  b: 'boolean',                               // Done
  C: 'object-serializable',
  d: 'double',                                // Done
  i: 'integer',                               // Done
  N: 'null',                                  // Done
  o: 'deprecated way to encode objects',
  O: 'object + class',                        // Done
  r: 'reference',
  R: 'pointer reference',
  s: 'string'                                 // Done
}
let Assert = require('assert')
let Regex = {
  i: /i:(.*?);/,
  d: /d:(.*?);/,
  O: /O:\d+:".*?":(\d+):\{(.*)\}/,
  a: /a:(\d+):\{(.*)\}/
}
class Serialize{
  static serialize(){

  }
  static unserialize(Item, Scope){
    if(typeof Scope !== 'object') Scope = {}
    Assert.equal(typeof Item, 'string', "Serialize.unserialize expects parameter one to be string")
    return Serialize.__unserializeItem(Item, Scope)
  }
  // Note: Trailing semi-colons are removed by the indexes
  static __unserializeItem(Item, Scope){
    let Type = Item.substr(0, 1)
    let Length
    let Value
    if(Type === 'i'){
      Value = Regex.i.exec(Item)
      Assert(Value, "Syntax Error")
      return {
        Index: Value.index + Value[0].length,
        Value: parseInt(Value[1])
      }
    } else if(Type === 's'){
      Length = parseInt(Item.substr(2, 1))
      Assert(Length === Length, "Syntax Error") // NaN !== NaN
      Item = Item.substr(4, Length + 2)
      return {
        Index: Length + Length.toString().length + 6,
        Value: Item.substr(1, Item.length - 2).replace(/\\"/g, '"') // 2 quotes
      }
    } else if(Type === 'b'){
      return {
        Value: Boolean(Item.substr(2, 1)),
        Index: 4
      }
    } else if(Type === 'N'){
      return {
        Value: null,
        Index: 2
      }
    } else if(Type === 'd'){
      Value = Regex.d.exec(Item)
      Assert(Value, "Syntax Error")
      return {
        Index: Value.index + Value[0].length,
        Value: parseFloat(Value[1])
      }
    } else if(Type === 'O'){
      let RegexVal = Regex.O.exec(Item)
      Assert(RegexVal, "Syntax Error")
      Length = parseInt(RegexVal[1]) * 2
      Value = RegexVal[2]
      return {
        Value: Serialize.__unserializeObject(Length, Value, {}),
        Index: RegexVal.index + RegexVal[0].length
      }
    } else if(Type === 'a'){
      let RegexVal = Regex.a.exec(Item)
      Assert(RegexVal, "Syntax Error")
      Length = parseInt(RegexVal[1]) * 2
      Value = RegexVal[2]
      return {
        Value: Serialize.__unserializeObject(Length, Value, []),
        Index: RegexVal.index + RegexVal[0].length
      }
    }
    return Type
  }
  static __unserializeObject(Length, Value, Container){
    let Temp = {Key: "", Value: ""}
    for(let I = 0; I < Length; ++I){
      let Entry = Serialize.__unserializeItem(Value, Scope)
      if(Temp.Key){
        Temp.Value = Entry.Value
        Container[Temp.Key] = Temp.Value
        Temp = {Key: "", Value: ""}
      } else Temp.Key = Entry.Value
      Value = Value.substr(Entry.Index)
    }
    return Container
  }
}
<commit_msg>:new: Support serializable object unserialize<commit_after>"use strict"
let Chart = {
  a: 'array',                                 // Done
  b: 'boolean',                               // Done
  C: 'object-serializable',
  d: 'double',                                // Done
  i: 'integer',                               // Done
  N: 'null',                                  // Done
  o: 'deprecated way to encode objects',
  O: 'object + class',                        // Done
  r: 'reference',
  R: 'pointer reference',
  s: 'string'                                 // Done
}
let Assert = require('assert')
let Regex = {
  i: /i:(.*?);/,
  d: /d:(.*?);/,
  O: /O:\d+:".*?":(\d+):\{(.*)\}/,
  a: /a:(\d+):\{(.*)\}/,
  C: /C:\d+:"(.*?)":1:{(.*?)}/
}
class Serialize{
  static serialize(){

  }
  static unserialize(Item, Scope){
    if(typeof Scope !== 'object') Scope = {}
    Assert.equal(typeof Item, 'string', "Serialize.unserialize expects parameter one to be string")
    return Serialize.__unserializeItem(Item, Scope)
  }
  // Note: Trailing semi-colons are removed by the indexes
  static __unserializeItem(Item, Scope){
    let Type = Item.substr(0, 1)
    let Length
    let Value
    if(Type === 'i'){
      Value = Regex.i.exec(Item)
      Assert(Value, "Syntax Error")
      return {
        Index: Value.index + Value[0].length,
        Value: parseInt(Value[1])
      }
    } else if(Type === 's'){
      Length = parseInt(Item.substr(2, 1))
      Assert(Length === Length, "Syntax Error") // NaN !== NaN
      Item = Item.substr(4, Length + 2)
      return {
        Index: Length + Length.toString().length + 6,
        Value: Item.substr(1, Item.length - 2).replace(/\\"/g, '"') // 2 quotes
      }
    } else if(Type === 'b'){
      return {
        Value: Boolean(Item.substr(2, 1)),
        Index: 4
      }
    } else if(Type === 'N'){
      return {
        Value: null,
        Index: 2
      }
    } else if(Type === 'd'){
      Value = Regex.d.exec(Item)
      Assert(Value, "Syntax Error")
      return {
        Index: Value.index + Value[0].length,
        Value: parseFloat(Value[1])
      }
    } else if(Type === 'O'){
      let RegexVal = Regex.O.exec(Item)
      Assert(RegexVal, "Syntax Error")
      Length = parseInt(RegexVal[1]) * 2
      Value = RegexVal[2]
      return {
        Value: Serialize.__unserializeObject(Length, Value, {}),
        Index: RegexVal.index + RegexVal[0].length
      }
    } else if(Type === 'a'){
      let RegexVal = Regex.a.exec(Item)
      Assert(RegexVal, "Syntax Error")
      Length = parseInt(RegexVal[1]) * 2
      Value = RegexVal[2]
      return {
        Value: Serialize.__unserializeObject(Length, Value, []),
        Index: RegexVal.index + RegexVal[0].length
      }
    } else if(Type === 'C'){
      Value = Regex.C.exec(Item)
      Assert(Value, "Syntax Error")
      Assert.notEqual(typeof Scope[Value[1]], 'undefined', `Can't find \`${Value[1]}\` in given scope`)
      Assert.equal(typeof Scope[Value[1]].unserialize, 'function', `Can't find unserialize function on \`${Value[1]}\``)
      let Container = {}
      Scope[Value[1]].unserialize.call(Container, Value[2])
      return {
        Index: Value.index + Value[0].length,
        Value: Container
      }
    }
    return Type
  }
  static __unserializeObject(Length, Value, Container){
    let Temp = {Key: "", Value: ""}
    for(let I = 0; I < Length; ++I){
      let Entry = Serialize.__unserializeItem(Value, Scope)
      if(Temp.Key){
        Temp.Value = Entry.Value
        Container[Temp.Key] = Temp.Value
        Temp = {Key: "", Value: ""}
      } else Temp.Key = Entry.Value
      Value = Value.substr(Entry.Index)
    }
    return Container
  }
}

<|endoftext|>


<commit_before>
/*
 just an example of configuration useful to redirect all the request on the same endpoint */

$.jStorage.set('profile', {
    // parametri di connessione agli endpoint
    'connection' : {
        'http://FITEAGLE,http://localhost,http://federation.av.tu-berlin.de,file:///opt,http://demo.fiteagle.org/resource' : {
            description : {
                en : 'DEMO FITeagle'
            },
            useForInverseSameAs : true,
            //endpoint : 'http://demo.fiteagle.org:8080/openrdf-sesame/repositories/fiteagle',
            endpoint : '/openrdf-sesame/repositories/fiteagle',
            endpointType : 'sesame',
            examples : [{
                label : 'MotorGarage-1',
                uri : 'http://localhost/resource/MotorGarage-1'
            }]
        },
    },
    arrows : {
        'http://www.w3.org/2002/07/owl#sameAs' : 'isSameAs',
        'http://purl.org/dc/terms/isPartOf' : 'isPartOf',
        'http://purl.org/dc/elements/1.1/type' : 'isType',
        'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : 'isType'
    },
    uriSubstitutor : [{
        findStr : 'mpii.de/yago/resource/',
        replaceStr : 'yago-knowledge.org/resource/'
    }],

    // configurazione standard per la rappresentazione di un documento
    // utilizzata nel caso manchi una specifica configurazione per la classe
    'default' : {
        sparql : {
            allClasses : 'SELECT DISTINCT ?object WHERE {[] a ?object}',
            findSubject : 'SELECT DISTINCT ?subject WHERE { {?subject a <{CLASS}>;<http://purl.org/dc/elements/1.1/title> ?object. FILTER(regex(str(?object),\'{VALUE}\',\'i\'))} UNION {?subject a <{CLASS}>;<http://www.w3.org/2000/01/rdf-schema#label> ?object. FILTER(regex(str(?object),\'{VALUE}\',\'i\'))} UNION {?subject a <{CLASS}>;<http://www.w3.org/2004/02/skos/core#prefLabel> ?object. FILTER(regex(str(?object),\'{VALUE}\',\'i\'))} }  LIMIT 1  ',
            documentUri : 'SELECT DISTINCT * WHERE {<{URI}> ?property ?object} ORDER BY ?property',
            document : 'SELECT DISTINCT * WHERE {<{URI}> ?property ?object}',
            bnode : 'SELECT DISTINCT *  WHERE {<{URI}> ?property ?object}',
            inverse : 'SELECT DISTINCT * WHERE {?object ?property <{URI}>.} LIMIT 100',
            inverseSameAs : 'SELECT DISTINCT * WHERE {{?object <http://www.w3.org/2002/07/owl#sameAs> <{URI}> } UNION { ?object <http://www.w3.org/2004/02/skos/core#exactMatch> <{URI}>}}'
        },
        endpoint : 'http://labs.regesta.com/resourceProxy/',
        document : {
            className : 'standard',
            titleProperties : ['http://dati.senato.it/osr/titolo', 'http://www.w3.org/2004/02/skos/core#notation', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', 'http://www.geonames.org/ontology#name', 'http://purl.org/dc/elements/1.1/title', 'http://purl.org/dc/terms/title', 'http://www.w3.org/2000/01/rdf-schema#label', 'http://www.w3.org/2004/02/skos/core#prefLabel', 'http://logd.tw.rpi.edu/source/visualizing-org/dataset/2010-global-agenda-council-interlinkage-survey/vocab/enhancement/1/how_councils_interlink', 'http://rdf.freebase.com/ns/type.object.name', 'http://spcdata.digitpa.gov.it/nome_cognome', 'http://xmlns.com/foaf/0.1/firstName', 'http://xmlns.com/foaf/0.1/lastName', 'http://xmlns.com/foaf/0.1/surname', 'http://xmlns.com/foaf/0.1/name', 'http://purl.org/dc/terms/description', 'http://www.geonames.org/ontology/officialName']
        }, // http://www.w3.org/2000/01/rdf-schema#label
        images : {
            properties : ['http://www.w3.org/2006/vcard/ns#photo', 'http://xmlns.com/foaf/0.1/depiction', 'http://dbpedia.org/ontology/thumbnail', 'http://dbpedia.org/property/logo', 'http://linkedgeodata.org/ontology/schemaIcon']
        },
        maps : {
            longs : ['http://www.w3.org/2003/01/geo/wgs84_pos#long'],
            lats : ['http://www.w3.org/2003/01/geo/wgs84_pos#lat'],
            points : ['http://www.georss.org/georss/point']
        },
        weblinks : {
            properties : ['http://www.w3.org/ns/dcat#accessURL', 'http://xmlns.com/foaf/0.1/mbox', 'http://rdfs.org/sioc/ns#links_to', 'http://it.dbpedia.org/property/url', 'http://data.nytimes.com/elements/search_api_query', 'http://www.w3.org/2000/01/rdf-schema#isDefinedBy', 'http://xmlns.com/foaf/0.1/page', 'http://xmlns.com/foaf/0.1/homepage', 'http://purl.org/dc/terms/isReferencedBy', 'http://purl.org/dc/elements/1.1/relation', 'http://dbpedia.org/ontology/wikiPageExternalLink', 'http://data.nytimes.com/elements/topicPage']
        }
    },

    'http://www.w3.org/2002/07/owl#Class' : {
        document : {
            className : 'Class'/*,
             titleProperties : ['http://purl.org/dc/elements/1.1/title', 'http://www.w3.org/2000/01/rdf-schema#label']*/
        }
    },
    'http://www.w3.org/2002/07/owl#ObjectProperty' : {
        document : {
            className : 'ObjectProperty'
        }
    },
    'http://www.w3.org/2002/07/owl#Restriction' : {
        document : {
            className : 'DatatypeProperty'
        }
    },
    'http://www.w3.org/2002/07/owl#DatatypeProperty' : {
        document : {
            className : 'DatatypeProperty'
        }
    },
    'http://www.w3.org/2002/07/owl#Property' : {
        document : {
            className : 'Property'
        }
    },
    'http://www.w3.org/ns/locn#Address' : {
        document : {
            titleProperties : ['http://www.w3.org/ns/locn#fullAddress']
        }
    }

});
if (!document.lodliveVars) {
    document.lodliveVars = {};
}

$.jStorage.set('boxTemplate', '

');
$.jStorage.set('relationsLimit', 25);
$.jStorage.set('doStats', $.jStorage.get('doStats', true));
$.jStorage.set('doInverse', $.jStorage.get('doAutoExpand', true));
$.jStorage.set('doAutoExpand', $.jStorage.get('doAutoExpand', true));
$.jStorage.set('doAutoSameas', $.jStorage.get('doAutoSameas', true));
$.jStorage.set('doCollectImages', $.jStorage.get('doCollectImages', true));
$.jStorage.set('doDrawMap', $.jStorage.get('doDrawMap', true));
$.jStorage.set('showInfoConsole', $.jStorage.get('showInfoConsole', true));

$.jStorage.set('endpoints', {
    all : 'output=json&format=application/json&timeout=0',
    arcSparql : 'output=json&jsonp=lodlive',
    sesame : 'Accept=application/sparql-results%2Bjson'
});
<commit_msg>look also for omn<commit_after>
/*
 just an example of configuration useful to redirect all the request on the same endpoint */

$.jStorage.set('profile', {
    // parametri di connessione agli endpoint
    'connection' : {
        'http://fiteagle,http://localhost,http://federation.av.tu-berlin.de,file:///opt,http://demo.fiteagle.org/resource,http://open-multinet.info' : {
            description : {
                en : 'FITeagle Database'
            },
            useForInverseSameAs : true,
            endpoint : '/openrdf-sesame/repositories/fiteagle',
            endpointType : 'sesame',
            examples : [{
                label : 'MotorGarage-1',
                uri : 'http://localhost/resource/MotorGarage-1'
            }]
        },
    },
    arrows : {
        'http://www.w3.org/2002/07/owl#sameAs' : 'isSameAs',
        'http://purl.org/dc/terms/isPartOf' : 'isPartOf',
        'http://purl.org/dc/elements/1.1/type' : 'isType',
        'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' : 'isType'
    },
    uriSubstitutor : [{
        findStr : 'mpii.de/yago/resource/',
        replaceStr : 'yago-knowledge.org/resource/'
    }],

    // configurazione standard per la rappresentazione di un documento
    // utilizzata nel caso manchi una specifica configurazione per la classe
    'default' : {
        sparql : {
            allClasses : 'SELECT DISTINCT ?object WHERE {[] a ?object}',
            findSubject : 'SELECT DISTINCT ?subject WHERE { {?subject a <{CLASS}>;<http://purl.org/dc/elements/1.1/title> ?object. FILTER(regex(str(?object),\'{VALUE}\',\'i\'))} UNION {?subject a <{CLASS}>;<http://www.w3.org/2000/01/rdf-schema#label> ?object. FILTER(regex(str(?object),\'{VALUE}\',\'i\'))} UNION {?subject a <{CLASS}>;<http://www.w3.org/2004/02/skos/core#prefLabel> ?object. FILTER(regex(str(?object),\'{VALUE}\',\'i\'))} }  LIMIT 1  ',
            documentUri : 'SELECT DISTINCT * WHERE {<{URI}> ?property ?object} ORDER BY ?property',
            document : 'SELECT DISTINCT * WHERE {<{URI}> ?property ?object}',
            bnode : 'SELECT DISTINCT *  WHERE {<{URI}> ?property ?object}',
            inverse : 'SELECT DISTINCT * WHERE {?object ?property <{URI}>.} LIMIT 100',
            inverseSameAs : 'SELECT DISTINCT * WHERE {{?object <http://www.w3.org/2002/07/owl#sameAs> <{URI}> } UNION { ?object <http://www.w3.org/2004/02/skos/core#exactMatch> <{URI}>}}'
        },
        endpoint : 'http://labs.regesta.com/resourceProxy/',
        document : {
            className : 'standard',
            titleProperties : ['http://dati.senato.it/osr/titolo', 'http://www.w3.org/2004/02/skos/core#notation', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', 'http://www.geonames.org/ontology#name', 'http://purl.org/dc/elements/1.1/title', 'http://purl.org/dc/terms/title', 'http://www.w3.org/2000/01/rdf-schema#label', 'http://www.w3.org/2004/02/skos/core#prefLabel', 'http://logd.tw.rpi.edu/source/visualizing-org/dataset/2010-global-agenda-council-interlinkage-survey/vocab/enhancement/1/how_councils_interlink', 'http://rdf.freebase.com/ns/type.object.name', 'http://spcdata.digitpa.gov.it/nome_cognome', 'http://xmlns.com/foaf/0.1/firstName', 'http://xmlns.com/foaf/0.1/lastName', 'http://xmlns.com/foaf/0.1/surname', 'http://xmlns.com/foaf/0.1/name', 'http://purl.org/dc/terms/description', 'http://www.geonames.org/ontology/officialName']
        }, // http://www.w3.org/2000/01/rdf-schema#label
        images : {
            properties : ['http://www.w3.org/2006/vcard/ns#photo', 'http://xmlns.com/foaf/0.1/depiction', 'http://dbpedia.org/ontology/thumbnail', 'http://dbpedia.org/property/logo', 'http://linkedgeodata.org/ontology/schemaIcon']
        },
        maps : {
            longs : ['http://www.w3.org/2003/01/geo/wgs84_pos#long'],
            lats : ['http://www.w3.org/2003/01/geo/wgs84_pos#lat'],
            points : ['http://www.georss.org/georss/point']
        },
        weblinks : {
            properties : ['http://www.w3.org/ns/dcat#accessURL', 'http://xmlns.com/foaf/0.1/mbox', 'http://rdfs.org/sioc/ns#links_to', 'http://it.dbpedia.org/property/url', 'http://data.nytimes.com/elements/search_api_query', 'http://www.w3.org/2000/01/rdf-schema#isDefinedBy', 'http://xmlns.com/foaf/0.1/page', 'http://xmlns.com/foaf/0.1/homepage', 'http://purl.org/dc/terms/isReferencedBy', 'http://purl.org/dc/elements/1.1/relation', 'http://dbpedia.org/ontology/wikiPageExternalLink', 'http://data.nytimes.com/elements/topicPage']
        }
    },

    'http://www.w3.org/2002/07/owl#Class' : {
        document : {
            className : 'Class'/*,
             titleProperties : ['http://purl.org/dc/elements/1.1/title', 'http://www.w3.org/2000/01/rdf-schema#label']*/
        }
    },
    'http://www.w3.org/2002/07/owl#ObjectProperty' : {
        document : {
            className : 'ObjectProperty'
        }
    },
    'http://www.w3.org/2002/07/owl#Restriction' : {
        document : {
            className : 'DatatypeProperty'
        }
    },
    'http://www.w3.org/2002/07/owl#DatatypeProperty' : {
        document : {
            className : 'DatatypeProperty'
        }
    },
    'http://www.w3.org/2002/07/owl#Property' : {
        document : {
            className : 'Property'
        }
    },
    'http://www.w3.org/ns/locn#Address' : {
        document : {
            titleProperties : ['http://www.w3.org/ns/locn#fullAddress']
        }
    }

});
if (!document.lodliveVars) {
    document.lodliveVars = {};
}

$.jStorage.set('boxTemplate', '

');
$.jStorage.set('relationsLimit', 25);
$.jStorage.set('doStats', $.jStorage.get('doStats', true));
$.jStorage.set('doInverse', $.jStorage.get('doAutoExpand', true));
$.jStorage.set('doAutoExpand', $.jStorage.get('doAutoExpand', true));
$.jStorage.set('doAutoSameas', $.jStorage.get('doAutoSameas', true));
$.jStorage.set('doCollectImages', $.jStorage.get('doCollectImages', true));
$.jStorage.set('doDrawMap', $.jStorage.get('doDrawMap', true));
$.jStorage.set('showInfoConsole', $.jStorage.get('showInfoConsole', true));

$.jStorage.set('endpoints', {
    all : 'output=json&format=application/json&timeout=0',
    arcSparql : 'output=json&jsonp=lodlive',
    sesame : 'Accept=application/sparql-results%2Bjson'
});
<|endoftext|>