<commit_before>var Snap = {
    snap: undefined,
    video: undefined,
    videoSelect: undefined,
    canvas: undefined,
    wait: undefined,
    imageCapture: null,

    gotStream: function() {
        const constraints = {
            video: {
                deviceId: Snap.videoSelect.value,
                width: { ideal: 4096 },
                height: { ideal: 4096 }
            }
        };

        if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
            navigator.mediaDevices.getUserMedia(constraints)
                .then(stream => {
                    snap.classList = 'shoot';

                    Snap.video.srcObject = stream;
                    Snap.video.play();

                    // We try to use ImageCapture
                    if (typeof(ImageCapture) != 'undefined') {
                        const track = stream.getVideoTracks()[0];
                        Snap.imageCapture = new ImageCapture(track);
                    }

                    // If we cancel after the authorization was given
                    if (Snap.snap.classList == '') {
                        Snap.close();
                    };
                });
        }
    },
    gotDevices: function(deviceInfos) {
        Snap.videoSelect.innerText = '';

        const ids = [];

        for (let i = 0; i !== deviceInfos.length; ++i) {
            const deviceInfo = deviceInfos[i];

            if (deviceInfo.kind === 'videoinput' && !ids.includes(deviceInfo.deviceId)) {
                const option = document.createElement('option');
                option.value = deviceInfo.deviceId;
                option.text = deviceInfo.label;
                Snap.videoSelect.add(option);
                ids.push(deviceInfo.deviceId);
            }
        }

        if (ids.length >= 2) {
            document.querySelector("#snap #snapswitch").classList.add('enabled');
        }

        Snap.videoSelect.addEventListener('change', () => Snap.gotStream());
        Snap.gotStream();
    },
    shoot: function() {
        if (Snap.imageCapture) {
            Snap.imageCapture.takePhoto()
                .then(blob => createImageBitmap(blob))
                .then(imageBitmap => {
                    Snap.canvas.width = imageBitmap.width;
                    Snap.canvas.height = imageBitmap.height;
                    var context = Snap.canvas.getContext('2d');
                    context.drawImage(imageBitmap, 0, 0, imageBitmap.width, imageBitmap.height);

                    Snap.compress();
                })
                .catch(error => console.log(error));

        } else {
            Snap.canvas.width = Snap.video.videoWidth;
            Snap.canvas.height = Snap.video.videoHeight;
            var context = Snap.canvas.getContext('2d');
            context.drawImage(Snap.video, 0, 0, Snap.video.videoWidth, Snap.video.videoHeight);
            Snap.video.pause();

            Snap.compress();
        }
    },
    compress: function() {
        Snap.canvas.toBlob(
            function (blob) {
                Upload.prepare(blob);
            },
            'image/jpeg',
            0.85
        );

        Upload.name = 'snapshot.jpg';
        Snap.snap.classList = 'upload';
    },
    clear: function() {
        Snap.video.play();
        var context = Snap.canvas.getContext('2d');
        context.clearRect(0, 0, Snap.canvas.width, Snap.canvas.height);
    },
    close: function() {
        if (!Snap.video) return;

        let stream = Snap.video.srcObject;

        if (stream) {
            stream.getTracks().forEach(function(track) {
                track.stop();
            });
        }

        Snap.video.srcObject = null;
    },
    end: function() {
        Snap.snap.classList = '';
        Snap.wait.style.backgroundImage = '';
        Snap.close();
    },
    init : function() {
        Snap.snap = document.querySelector('#snap');
        Snap.canvas = document.querySelector('#snap canvas');
        Snap.wait = document.querySelector("#snap #snapwait");

        Snap.video = document.querySelector('#snap video');
        Snap.videoSelect = document.querySelector('#snap select#snapsource');

        Snap.close(); // Just in case

        navigator.mediaDevices.enumerateDevices().then(devices => Snap.gotDevices(devices));

        Snap.video.play();

        document.querySelector("#snap #snapshoot").onclick = () => {
            Snap.shoot();
        };

        document.querySelector("#snap #snapswitch").onclick = () => {
            Snap.snap.classList = 'init';

            Snap.videoSelect.selectedIndex++;

            // No empty selection
            if (Snap.videoSelect.selectedIndex == -1) {
                Snap.videoSelect.selectedIndex++;
            }

            Snap.close();
            Snap.gotStream();
        };

        Snap.snap.classList = 'init';

        document.querySelector("#snap #snapupload").onclick = () => {
            Snap.snap.classList = 'wait';
            Upload.init();
        };

        document.querySelector("#snap #snapdraw").onclick = () => {
            Snap.snap.classList = '';
            Snap.close();

            Draw.init(Snap.canvas);
        };

        document.querySelector("#snap #snapback").onclick = () => {
            Snap.snap.classList = '';
            Snap.close();
        };

        document.querySelector("#snap #snapclose").onclick = () => {
            Snap.snap.classList = 'shoot';
            Snap.video.play();
            Upload.abort();
        };
    }
}

Upload.attach((file) => {
    const page = MovimUtils.urlParts().page;

    if (Snap.snap) Snap.end();
});

Upload.progress((percent) => {
    if (Snap.wait) {
        Snap.wait.style.backgroundImage = 'linear-gradient(to top, rgba(0, 0, 0, 0.5) ' + percent + '%, transparent ' + percent + '%)';
    }
});

Upload.fail(() => {
    if (Snap.snap) {
        Snap.snap.classList = 'upload'; Snap.wait.style.backgroundImage = '';
    }
});
<commit_msg>Fix Snap widget camera switch, cleanup code<commit_after>var Snap = {
    snap: undefined,
    video: undefined,
    videoSelect: undefined,
    canvas: undefined,
    wait: undefined,
    imageCapture: null,

    init: function() {
        Snap.snap = document.querySelector('#snap');
        Snap.canvas = document.querySelector('#snap canvas');
        Snap.wait = document.querySelector("#snap #snapwait");

        Snap.video = document.querySelector('#snap video');
        Snap.videoSelect = document.querySelector('#snap select#snapsource');

        Snap.close();

        Snap.getStream().then(Snap.getDevices).then(Snap.gotDevices);

        document.querySelector("#snap #snapshoot").onclick = () => {
            Snap.shoot();
        };

        document.querySelector("#snap #snapswitch").onclick = () => {
            Snap.snap.classList = 'init';

            Snap.videoSelect.selectedIndex++;

            // No empty selection
            if (Snap.videoSelect.selectedIndex == -1) {
                Snap.videoSelect.selectedIndex++;
            }

            Snap.getStream();
        };

        Snap.snap.classList = 'init';

        document.querySelector("#snap #snapupload").onclick = () => {
            Snap.snap.classList = 'wait';
            Upload.init();
        };

        document.querySelector("#snap #snapdraw").onclick = () => {
            Snap.snap.classList = '';
            Snap.close();
            Draw.init(Snap.canvas);
        };

        document.querySelector("#snap #snapback").onclick = () => {
            Snap.snap.classList = '';
            Snap.close();
        };

        document.querySelector("#snap #snapclose").onclick = () => {
            Snap.snap.classList = 'shoot';
            Snap.video.play();
            Upload.abort();
        };
    },

    close: function() {
        if (!Snap.video) return;

        let stream = Snap.video.srcObject;

        if (stream) {
            stream.getTracks().forEach(function(track) {
                track.stop();
            });
        }

        Snap.video.srcObject = null;
    },

    getStream: function() {
        Snap.snap.classList = 'wait';

        if (Snap.video.srcObject) {
            Snap.video.srcObject.getTracks().forEach(track => track.stop());
        }

        const videoSource = Snap.videoSelect.value;
        const constraints = {
            video: {deviceId: videoSource ? {exact: videoSource} : undefined}
        };

        return navigator.mediaDevices.getUserMedia(constraints)
            .then(Snap.gotStream);
    },

    gotStream: function(stream) {
        Snap.snap.classList = 'shoot';

        Snap.videoSelect.selectedIndex = [...Snap.videoSelect.options].
            findIndex(option => option.text === stream.getVideoTracks()[0].label);
        Snap.video.srcObject = stream;

        // We try to use ImageCapture
        if (typeof(ImageCapture) != 'undefined') {
            const track = stream.getVideoTracks()[0];
            Snap.imageCapture = new ImageCapture(track);
        }

        // If we cancel after the authorization was given
        if (Snap.snap.classList == '') {
            Snap.close();
        };
    },

    getDevices: function() {
        return navigator.mediaDevices.enumerateDevices();
    },

    gotDevices: function(deviceInfos) {
        Snap.videoSelect.innerHTML = '';

        console.log('Available input and output devices:', deviceInfos);
        for (const deviceInfo of deviceInfos) {
            const option = document.createElement('option');
            option.value = deviceInfo.deviceId;

            if (deviceInfo.kind === 'videoinput') {
                option.text = deviceInfo.label || `Camera ${videoSelect.length + 1}`;
                Snap.videoSelect.appendChild(option);
            }

            if (Snap.videoSelect.options.length >= 2) {
                document.querySelector("#snap #snapswitch").classList.add('enabled');
            }
        }
    },
    shoot: function() {
        if (Snap.imageCapture) {
            Snap.imageCapture.takePhoto()
                .then(blob => createImageBitmap(blob))
                .then(imageBitmap => {
                    Snap.canvas.width = imageBitmap.width;
                    Snap.canvas.height = imageBitmap.height;
                    var context = Snap.canvas.getContext('2d');
                    context.drawImage(imageBitmap, 0, 0, imageBitmap.width, imageBitmap.height);

                    Snap.compress();
                })
                .catch(error => console.log(error));

        } else {
            Snap.canvas.width = Snap.video.videoWidth;
            Snap.canvas.height = Snap.video.videoHeight;
            var context = Snap.canvas.getContext('2d');
            context.drawImage(Snap.video, 0, 0, Snap.video.videoWidth, Snap.video.videoHeight);
            Snap.video.pause();

            Snap.compress();
        }
    },
    compress: function() {
        Snap.canvas.toBlob(
            function (blob) {
                Upload.prepare(blob);
            },
            'image/jpeg',
            0.85
        );

        Upload.name = 'snapshot.jpg';
        Snap.snap.classList = 'upload';
    },
    clear: function() {
        Snap.video.play();
        var context = Snap.canvas.getContext('2d');
        context.clearRect(0, 0, Snap.canvas.width, Snap.canvas.height);
    },
    end: function() {
        Snap.snap.classList = '';
        Snap.wait.style.backgroundImage = '';
        Snap.close();
    }
}

Upload.attach((file) => {
    const page = MovimUtils.urlParts().page;
    if (Snap.snap) Snap.end();
});

Upload.progress((percent) => {
    if (Snap.wait) {
        Snap.wait.style.backgroundImage = 'linear-gradient(to top, rgba(0, 0, 0, 0.5) ' + percent + '%, transparent ' + percent + '%)';
    }
});

Upload.fail(() => {
    if (Snap.snap) {
        Snap.snap.classList = 'upload'; Snap.wait.style.backgroundImage = '';
    }
});
<|endoftext|>


<commit_before>import glslify from 'rollup-plugin-glslify';
import resolve from '@rollup/plugin-node-resolve';
import builtins from 'rollup-plugin-node-builtins';
import scss from 'rollup-plugin-scss';
import commonjs from '@rollup/plugin-commonjs';
import copy from 'rollup-plugin-copy';
import alias from '@rollup/plugin-alias';
import replace from '@rollup/plugin-replace';
import json from '@rollup/plugin-json';

export default {
  input: 'src/main.js',
  external: [ 'gl-matrix', 'axios', 'jpeg-js', 'fast-png'],
  output: [
    {
      name: 'SampleViewerApp',
      file: 'dist/GltfSVApp.umd.js',
      format: 'umd',
      sourcemap: true,
      globals: {
        'gl-matrix': 'glMatrix',
        'axios': 'axios',
        'jpeg-js': 'jpeg',
        'fast-png': 'png'
      },
    }
  ],
  plugins: [
    json(),
    commonjs({

    }),
    glslify({
        include: ['../source/Renderer/shaders/*', '../source/shaders/*'],
        compress: false
    }),
    resolve({
        browser: true,
        preferBuiltins: true
    }),
    builtins(),
    scss(),
    copy({
        targets: [
            { src: ["index.html"], dest: "dist/"},
            { src: ["../assets/models/2.0", "!../asset/models/.git"], dest: "dist/assets/models"},
            { src: ["../assets/environments/*.hdr", "../assets/environments/*.jpg", "!../asset/environments/.git"], dest: "dist/assets/environments"},
            { src: ["../assets/images"], dest: "dist/assets"},
            { src: ["../assets/ui"], dest: "dist/assets"},
            { src: ["../source/libs/*", "!../source/libs/hdrpng.js"], dest: "dist/libs"}
        ],
        copyOnce: true,
        verbose: true
    }),
    replace({
      'process.env.NODE_ENV': JSON.stringify( 'production' ),
      preventAssignment: true,
    }),
    alias({
      'vue': 'vue/dist/vue.esm.js'
    }),
  ]
};
<commit_msg>Format code<commit_after>import glslify from 'rollup-plugin-glslify';
import resolve from '@rollup/plugin-node-resolve';
import builtins from 'rollup-plugin-node-builtins';
import scss from 'rollup-plugin-scss';
import commonjs from '@rollup/plugin-commonjs';
import copy from 'rollup-plugin-copy';
import alias from '@rollup/plugin-alias';
import replace from '@rollup/plugin-replace';
import json from '@rollup/plugin-json';

export default {
    input: 'src/main.js',
    external: ['gl-matrix', 'axios', 'jpeg-js', 'fast-png'],
    output: [
        {
            name: 'SampleViewerApp',
            file: 'dist/GltfSVApp.umd.js',
            format: 'umd',
            sourcemap: true,
            globals: {
                'gl-matrix': 'glMatrix',
                'axios': 'axios',
                'jpeg-js': 'jpeg',
                'fast-png': 'png'
            },
        }
    ],
    plugins: [
        json(),
        commonjs(),
        glslify({
            include: ['../source/Renderer/shaders/*', '../source/shaders/*'],
            compress: false
        }),
        resolve({
            browser: true,
            preferBuiltins: true
        }),
        builtins(),
        scss(),
        copy({
            targets: [
                { src: ["index.html"], dest: "dist/" },
                { src: ["../assets/models/2.0", "!../asset/models/.git"], dest: "dist/assets/models" },
                { src: ["../assets/environments/*.hdr", "../assets/environments/*.jpg", "!../asset/environments/.git"], dest: "dist/assets/environments" },
                { src: ["../assets/images"], dest: "dist/assets" },
                { src: ["../assets/ui"], dest: "dist/assets" },
                { src: ["../source/libs/*", "!../source/libs/hdrpng.js"], dest: "dist/libs" }
            ],
            copyOnce: true,
            verbose: true
        }),
        replace({
            'process.env.NODE_ENV': JSON.stringify('production'),
            preventAssignment: true,
        }),
        alias({
            'vue': 'vue/dist/vue.esm.js'
        }),
    ]
};
<|endoftext|>


<commit_before>var builder = require('focus').component.builder;
var React = require('react');
var type = require('focus').component.types;

var barMixin = {
  /** @inheriteddoc */
  getDefaultProps: function getMenuDefaultProps() {
    return {
      open: true,
      scrollTargetSelector: undefined,
      style: {},
      size: 'tall',
      sizeMap: {
        'small': {
          'visibility': 0.5
        },
        'medium': {
          'visibility': 0.7
        },
        'tall': {
          'visibility': 1
        }
      }
    };
  },
  /** @inheritdoc */
  propTypes: {
    open: type('bool'),
    size: type('string'),
    scrollTargetSelector: type('string')
  },
  getInitialState: function getMenuDefaultState() {
  /** @inheriteddoc */
    return {
      open: this.props.open,
      visibility: this.props.sizeMap[this.props.size].visibility,
      size: this.props.size
    };
  },
  _processSizes: function processSizes(){
    var sizes = [];
    for(var sz in this.props.sizeMap){

    }
    this.sizes = sizes;
  },
  /** @inheriteddoc */
  componentWillMount: function barWillMount() {
      this._processSizes();
      this.scrollTargetNode = (this.props.scrollTargetSelector && this.props.scrollTargetSelector !== '') ? document.querySelector(this.props.scrollTargetSelector) : window;
  },
  /** @inheriteddoc */
  componentDidMount: function barDidMount(){
    this.attachScrollListener();
  },
  /** @inheriteddoc */
  componentWillUnMount: function barWillUnMount(){
    this.detachScrollListener();
  },
  /**
   * Toggle the state of the menu.
   */
  toggle: function toggleOpenMenu() {
    this.setState({open: !this.state.open});
  },
  _processElementSize: function processElementSize(){
    return React.findDOMNode(this).offsetHeight;
  },
  _getScrollPosition: function getScrollPosition(){
    return this.scrollTargetNode.scrollTop;
  },
  _isChangeSize: function isChangeSize(){
     return (this._getScrollPosition() / this._processElementSize()) < this.state.visibility;
  },
  _changeSize: function changeSize(){

  },
  handleScroll: function(event){

    console.log('scroll', event);
  //React.findDOMNode
  },

  /**
   * Attach scroll listener on the component.
   */
  attachScrollListener: function attachScrollListener() {
    this.scrollTargetNode.addEventListener('scroll', this.handleScroll);
    this.scrollTargetNode.addEventListener('resize', this.handleScroll);
  },

  /**
   * Detach scroll handler on the component
   */
  detachScrollListener: function detachScrollListener() {
    this.scrollTargetNode.removeEventListener('scroll', this.handleScroll);
    this.scrollTargetNode.removeEventListener('resize', this.handleScroll);
  },
  /** @inheriteddoc */
  render: function renderBar() {
    var className = `bar bar-${this.state.open ? 'open' : ''} ${this.props.style.className}`;
    return (
      <nav className={className}>
        {this.state.open ? this._renderLargeContent() : this._renderMinimalContent()}
      </nav>
    );
  }
};

module.exports = builder(barMixin);
<commit_msg>[bar] update<commit_after>var builder = require('focus').component.builder;
var React = require('react');
var type = require('focus').component.types;
var {pluck, sortBy} = require('lodash/collection');

var barMixin = {
  /** @inheriteddoc */
  getDefaultProps: function getMenuDefaultProps() {
    return {
      open: true,
      scrollTargetSelector: undefined,
      style: {},
      size: 'tall',
      sizeMap: {
        'small': {
          'visibility': 0.5
        },
        'medium': {
          'visibility': 0.7
        },
        'tall': {
          'visibility': 1
        }
      }
    };
  },
  /** @inheritdoc */
  propTypes: {
    open: type('bool'),
    size: type('string'),
    scrollTargetSelector: type('string')
  },
  getInitialState: function getMenuDefaultState() {
  /** @inheriteddoc */
    return {
      open: this.props.open,
      visibility: this.props.sizeMap[this.props.size].visibility,
      size: this.props.size
    };
  },
  _processSizes: function processSizes(){
    var sizes = [];
    for(var sz in this.props.sizeMap){
     sizes.push({name: sz, visibility: this.props.sizeMap[sz].visibility});
    }
    this.sizes = pluck(sortBy(sizes, 'visibility'), 'name');
  },
  /** @inheriteddoc */
  componentWillMount: function barWillMount() {
      this._processSizes();
      this.scrollTargetNode = (this.props.scrollTargetSelector && this.props.scrollTargetSelector !== '') ? document.querySelector(this.props.scrollTargetSelector) : window;
  },
  /** @inheriteddoc */
  componentDidMount: function barDidMount(){
    this.attachScrollListener();
  },
  /** @inheriteddoc */
  componentWillUnMount: function barWillUnMount(){
    this.detachScrollListener();
  },
  /**
   * Toggle the state of the menu.
   */
  toggle: function toggleOpenMenu() {
    this.setState({open: !this.state.open});
  },
  _processElementSize: function processElementSize(){
    return React.findDOMNode(this).offsetHeight;
  },
  _getScrollPosition: function getScrollPosition(){
    return this.scrollTargetNode.scrollTop;
  },
  _isChangeSize: function isChangeSize(){
     return (this._getScrollPosition() / this._processElementSize()) < this.state.visibility;
  },
  _changeSize: function changeSize(){

  },
  handleScroll: function(event){

    console.log('scroll', event);
  //React.findDOMNode
  },

  /**
   * Attach scroll listener on the component.
   */
  attachScrollListener: function attachScrollListener() {
    this.scrollTargetNode.addEventListener('scroll', this.handleScroll);
    this.scrollTargetNode.addEventListener('resize', this.handleScroll);
  },

  /**
   * Detach scroll handler on the component
   */
  detachScrollListener: function detachScrollListener() {
    this.scrollTargetNode.removeEventListener('scroll', this.handleScroll);
    this.scrollTargetNode.removeEventListener('resize', this.handleScroll);
  },
  /** @inheriteddoc */
  render: function renderBar() {
    var className = `bar bar-${this.state.open ? 'open' : ''} ${this.props.style.className}`;
    return (
      <nav className={className}>
        {this.state.open ? this._renderLargeContent() : this._renderMinimalContent()}
      </nav>
    );
  }
};

module.exports = builder(barMixin);
<|endoftext|>


<commit_before>import {
  acyclicEqualsU,
  assocPartialU,
  curry2,
  curry3,
  curry4,
  dissocPartialU,
  id,
  isArray,
  isObject,
  mapPartialU,
  values,
  zipObjPartialU
} from "infestines"

//

const apply = (x2y, x) => x2y(x)
const always = x => _ => x
const snd = (_, c) => c

//

const Ident = {
  map: apply,
  of: id,
  ap: apply
}

const Const = {
  map: snd,
  of: id
}

const ConstOf = Monoid => ({
  map: snd,
  of: always(Monoid.empty()),
  ap: (x2yA, xA) => Monoid.concat(xA, x2yA)
})

const PartialList = {
  of: x => x !== undefined ? [x, null] : null,
  empty: () => null,
  cons: (h, t) => h !== undefined ? [h, t] : t,
  revConcat(xs, ys) {
    while (xs) {
      ys = [xs[0], ys]
      xs = xs[1]
    }
    return ys
  },
  reverse: xs => PartialList.revConcat(xs, null),
  concat: (xs, ys) => PartialList.revConcat(PartialList.reverse(xs), ys),
  toArray(xs) {
    const ys = []
    while (xs) {
      ys.push(xs[0])
      xs = xs[1]
    }
    return ys
  }
}

const Collect = ConstOf(PartialList)

const csnoc = t => h => PartialList.cons(h, t)

const PartialArray = {
  traverse(A, x2yA, xs) {
    let s = A.of(PartialList.empty())
    let i = xs.length
    while (i)
      s = A.ap(A.map(csnoc, s), x2yA(xs[--i]))
    return A.map(PartialList.toArray, s)
  }
}

//

const warn = process.env.NODE_ENV === "production" ? () => {} : (() => {
  const warned = {}

  return message => {
    if (!(message in warned)) {
      warned[message] = message
      console.warn("partial.lenses:", message)
    }
  }
})()

//

const unArray = x => isArray(x) ? x : undefined

const mkArray = x => isArray(x) ? x : emptyArray

//

const check = (expected, predicate) => x => {
  if (predicate(x))
    return x
  else
    throw new Error(`Expected ${expected}, but got ${x}.`)
}

const assert = process.env.NODE_ENV === "production" ? () => id : check

//

const emptyArrayToUndefined = xs => xs.length ? xs : undefined

//

const emptyArray = []
const emptyObject = {}

//

const toPartial = transform => x => x !== undefined ? transform(x) : x

//

const seemsLens = x => typeof x === "function" && x.length === 3

const lifted = assert("a lens", seemsLens)

const close = (l, A, i) => x => l(A, i, x)

function composed(ls) {
  switch (ls.length) {
    case 0:  return identity
    case 1:  return lift(ls[0])
    default: return (F, i, t) => {
      let n = ls.length
      i = close(lift(ls[--n]), F, i)
      while (1 < n)
        i = close(lift(ls[--n]), F, i)
      return lift(ls[0])(F, i, t)
    }
  }
}

function lift(l) {
  switch (typeof l) {
    case "string":   return liftProp(l)
    case "number":   return liftIndex(l)
    case "function": return lifted(l)
    default:         return composed(l)
  }
}

export function compose(...lenses) {
  switch (lenses.length) {
    case 0:  return identity
    case 1:  return lenses[0]
    default: return lenses
  }
}

function setI(l, x, s) {
  switch (typeof l) {
    case "string":   return setProp(l, x, s)
    case "number":   return setIndex(l, x, s)
    case "function": return lifted(l)(Ident, () => x, s)
    default:         return modifyComposedI(l, () => x, s)
  }
}

function getComposedI(ls, s0)  {
  let s = s0
  for (let i=0, n=ls.length; i<n; ++i)
    s = getI(ls[i], s)
  return s
}

function getI(l, s) {
  switch (typeof l) {
    case "string":   return getProp(l, s)
    case "number":   return getIndex(l, s)
    case "function": return lifted(l)(Const, Const.of, s)
    default:         return getComposedI(l, s)
  }
}

const getInverseI = (l, x) => setI(l, x, undefined)

function modifyComposedI(ls, x2x, s0) {
  let n = ls.length

  let r = s0
  const ss = []

  for (let i=0; i<n; ++i) {
    ss.push(r)
    const l = ls[i]
    switch (typeof l) {
      case "string":
        r = getProp(l, r)
        break
      case "number":
        r = getIndex(l, r)
        break
      default:
        r = composed(ls.slice(i))(Ident, x2x, r)
        n = i
        break
    }
  }

  if (n === ls.length)
    r = x2x(r)

  while (0 <= --n) {
    const l = ls[n]
    switch (typeof l) {
      case "string": r = setProp(l, r, ss[n]); break
      case "number": r = setIndex(l, r, ss[n]); break
    }
  }

  return r
}

function modifyI(l, x2x, s) {
  switch (typeof l) {
    case "string":   return setProp(l, x2x(getProp(l, s)), s)
    case "number":   return setIndex(l, x2x(getIndex(l, s)), s)
    case "function": return lifted(l)(Ident, x2x, s)
    default:         return modifyComposedI(l, x2x, s)
  }
}

const lensI = (getter, setter) => (F, inner, target) =>
  F.map(focus => setter(focus, target), inner(getter(target)))
const collectI = (l, s) =>
  PartialList.toArray(lift(l)(Collect, PartialList.of, s))

export const remove = curry2((l, s) => setI(l, undefined, s))
export const lens = curry2(lensI)
export const modify = curry3(modifyI)
export const set = curry3(setI)
export const get = curry2(getI)
export const getInverse = curry2(getInverseI)
export const collect = curry2(collectI)

export const foldMapOf = curry4((m, l, to, s) => {
  const Const = ConstOf(m)
  return lift(l)(Const, to, s)
})

export const inverse = iso => (F, inner, x) =>
  F.map(x => getI(iso, x), inner(getInverseI(iso, x)))

export const chain = curry2((x2yL, xL) =>
  [xL, choose(xO => xO !== undefined ? x2yL(xO) : nothing)])

export const just = x => lensI(always(x), snd)

export const choose = x2yL => (F, inner, target) =>
  lift(x2yL(target))(F, inner, target)

export const nothing = lensI(snd, snd)

export const orElse =
  curry2((d, l) => choose(x => getI(l, x) !== undefined ? l : d))

export const choice = (...ls) => choose(x => {
  const i = ls.findIndex(l => getI(l, x) !== undefined)
  return 0 <= i ? ls[i] : nothing
})

const replacer = (inn, out) => x => acyclicEqualsU(x, inn) ? out : x
const normalizer = fn => (F, inner, x) => F.map(fn, inner(fn(x)))

export const replace = curry2((inn, out) => (F, inner, x) =>
  F.map(replacer(out, inn), inner(replacer(inn, out)(x))))

export const defaults = out => (F, inner, x) =>
  F.map(replacer(out, undefined), inner(x !== undefined ? x : out))
export const required = inn => replace(inn, undefined)
export const define = v => normalizer(x => x !== undefined ? x : v)

export const valueOr = v => (_F, inner, x) =>
  inner(x !== undefined && x !== null ? x : v)

export const normalize = transform => normalizer(toPartial(transform))

const isProp = x => typeof x === "string"

export const prop = assert("a string", isProp)

const getProp = (k, o) => isObject(o) ? o[k] : undefined
const setProp = (k, v, o) =>
  v !== undefined ? assocPartialU(k, v, o) : dissocPartialU(k, o)

const liftProp = k => (F, inner, o) =>
  F.map(v => setProp(k, v, o), inner(getProp(k, o)))

export const find = predicate => choose(xs => {
  if (isArray(xs)) {
    const i = xs.findIndex(predicate)
    return i < 0 ? append : i
  } else {
    return append
  }
})

export function findWith(...ls) {
  const lls = compose(...ls)
  return [find(x => getI(lls, x) !== undefined), lls]
}

const isIndex = x => Number.isInteger(x) && 0 <= x

export const index = assert("a non-negative integer", isIndex)

const nulls = n => Array(n).fill(null)

const getIndex = (i, xs) => isArray(xs) ? xs[i] : undefined
function setIndex(i, x, xs) {
  if (x !== undefined) {
    if (!isArray(xs))
      return i < 0 ? undefined : nulls(i).concat([x])
    const n = xs.length
    if (n <= i)
      return xs.concat(nulls(i - n), [x])
    if (i < 0)
      return !n ? undefined : xs
    const ys = Array(n)
    for (let j=0; j<n; ++j)
      ys[j] = xs[j]
    ys[i] = x
    return ys
  } else {
    if (!isArray(xs))
      return undefined
    const n = xs.length
    if (!n)
      return undefined
    if (i < 0 || n <= i)
      return xs
    if (n === 1)
      return undefined
    const ys = Array(n-1)
    for (let j=0; j<i; ++j)
      ys[j] = xs[j]
    for (let j=i+1; j<n; ++j)
      ys[j-1] = xs[j]
    return ys
  }
}
const liftIndex = i => (F, inner, xs) =>
  F.map(x => setIndex(i, x, xs), inner(getIndex(i, xs)))

export const append = lensI(snd, (x, xs) =>
  x !== undefined ? isArray(xs) ? xs.concat([x]) : [x] : unArray(xs))

export const filter = p => lensI(xs => unArray(xs) && xs.filter(p), (ys, xs) =>
  emptyArrayToUndefined(mkArray(ys).concat(mkArray(xs).filter(x => !p(x)))))

export const augment = template => lensI(
  x => {
    if (isObject(x)) {
      const z = {...x}
      for (const k in template)
        z[k] = template[k](z)
      return z
    } else {
      return undefined
    }
  },
  (y, cIn) => {
    if (isObject(y)) {
      const c = isObject(cIn) ? cIn : emptyObject
      let z
      const set = (k, v) => {
        if (!z)
          z = {}
        z[k] = v
      }
      for (const k in y) {
        if (!(k in template))
          set(k, y[k])
        else
          if (k in c)
            set(k, c[k])
      }
      return z
    } else {
      return undefined
    }
  })

function getPick(template, target) {
  let r
  for (const k in template) {
    const v = getI(template[k], target)
    if (v !== undefined) {
      if (!r)
        r = {}
      r[k] = v
    }
  }
  return r
}
const setPick = (template, target) => value => {
  const o = value || emptyObject
  let c = target
  for (const k in template)
    c = setI(template[k], o[k], c)
  return c
}
export const pick = template => (F, inner, target) =>
  F.map(setPick(template, target), inner(getPick(template, target)))

export const identity = (_F, inner, t) => inner(t)

export const props = (...ks) => pick(zipObjPartialU(ks, ks))

const show = (labels, dir) => x => console.log(...labels, dir, x) || x

export const log = (...labels) =>
  lensI(show(labels, "get"), show(labels, "set"))

export const sequence = (A, inner, target) =>
  A === Ident
  ? emptyArrayToUndefined(mapPartialU(inner, mkArray(target)))
  : A.map(emptyArrayToUndefined, PartialArray.traverse(A, inner, mkArray(target)))

export const optional = (A, inner, target) =>
  target !== undefined ? inner(target) : A.of(undefined)

export const fromArrayBy = id =>
  warn("`fromArrayBy` is experimental and might be removed, renamed or changed semantically before next major release") ||
  lensI(xs => {
    if (isArray(xs)) {
      const o = {}
      for (let i=0, n=xs.length; i<n; ++i) {
        const x = xs[i]
        o[x[id]] = x
      }
      return o
    }
  },
  o => isObject(o) ? values(o) : undefined)

export default compose
<commit_msg>Prefer const<commit_after>import {
  acyclicEqualsU,
  assocPartialU,
  curry2,
  curry3,
  curry4,
  dissocPartialU,
  id,
  isArray,
  isObject,
  mapPartialU,
  values,
  zipObjPartialU
} from "infestines"

//

const apply = (x2y, x) => x2y(x)
const always = x => _ => x
const snd = (_, c) => c

//

const Ident = {
  map: apply,
  of: id,
  ap: apply
}

const Const = {
  map: snd,
  of: id
}

const ConstOf = Monoid => ({
  map: snd,
  of: always(Monoid.empty()),
  ap: (x2yA, xA) => Monoid.concat(xA, x2yA)
})

const PartialList = {
  of: x => x !== undefined ? [x, null] : null,
  empty: () => null,
  cons: (h, t) => h !== undefined ? [h, t] : t,
  revConcat(xs, ys) {
    while (xs) {
      ys = [xs[0], ys]
      xs = xs[1]
    }
    return ys
  },
  reverse: xs => PartialList.revConcat(xs, null),
  concat: (xs, ys) => PartialList.revConcat(PartialList.reverse(xs), ys),
  toArray(xs) {
    const ys = []
    while (xs) {
      ys.push(xs[0])
      xs = xs[1]
    }
    return ys
  }
}

const Collect = ConstOf(PartialList)

const csnoc = t => h => PartialList.cons(h, t)

const PartialArray = {
  traverse(A, x2yA, xs) {
    let s = A.of(PartialList.empty())
    let i = xs.length
    while (i)
      s = A.ap(A.map(csnoc, s), x2yA(xs[--i]))
    return A.map(PartialList.toArray, s)
  }
}

//

const warn = process.env.NODE_ENV === "production" ? () => {} : (() => {
  const warned = {}

  return message => {
    if (!(message in warned)) {
      warned[message] = message
      console.warn("partial.lenses:", message)
    }
  }
})()

//

const unArray = x => isArray(x) ? x : undefined

const mkArray = x => isArray(x) ? x : emptyArray

//

const check = (expected, predicate) => x => {
  if (predicate(x))
    return x
  else
    throw new Error(`Expected ${expected}, but got ${x}.`)
}

const assert = process.env.NODE_ENV === "production" ? () => id : check

//

const emptyArrayToUndefined = xs => xs.length ? xs : undefined

//

const emptyArray = []
const emptyObject = {}

//

const toPartial = transform => x => x !== undefined ? transform(x) : x

//

const seemsLens = x => typeof x === "function" && x.length === 3

const lifted = assert("a lens", seemsLens)

const close = (l, A, i) => x => l(A, i, x)

function composed(ls) {
  switch (ls.length) {
    case 0:  return identity
    case 1:  return lift(ls[0])
    default: return (F, i, t) => {
      let n = ls.length
      i = close(lift(ls[--n]), F, i)
      while (1 < n)
        i = close(lift(ls[--n]), F, i)
      return lift(ls[0])(F, i, t)
    }
  }
}

function lift(l) {
  switch (typeof l) {
    case "string":   return liftProp(l)
    case "number":   return liftIndex(l)
    case "function": return lifted(l)
    default:         return composed(l)
  }
}

export function compose(...lenses) {
  switch (lenses.length) {
    case 0:  return identity
    case 1:  return lenses[0]
    default: return lenses
  }
}

function setI(l, x, s) {
  switch (typeof l) {
    case "string":   return setProp(l, x, s)
    case "number":   return setIndex(l, x, s)
    case "function": return lifted(l)(Ident, () => x, s)
    default:         return modifyComposedI(l, () => x, s)
  }
}

function getComposedI(ls, s0)  {
  let s = s0
  for (let i=0, n=ls.length; i<n; ++i)
    s = getI(ls[i], s)
  return s
}

function getI(l, s) {
  switch (typeof l) {
    case "string":   return getProp(l, s)
    case "number":   return getIndex(l, s)
    case "function": return lifted(l)(Const, Const.of, s)
    default:         return getComposedI(l, s)
  }
}

const getInverseI = (l, x) => setI(l, x, undefined)

function modifyComposedI(ls, x2x, s0) {
  let n = ls.length

  let r = s0
  const ss = []

  for (let i=0; i<n; ++i) {
    ss.push(r)
    const l = ls[i]
    switch (typeof l) {
      case "string":
        r = getProp(l, r)
        break
      case "number":
        r = getIndex(l, r)
        break
      default:
        r = composed(ls.slice(i))(Ident, x2x, r)
        n = i
        break
    }
  }

  if (n === ls.length)
    r = x2x(r)

  while (0 <= --n) {
    const l = ls[n]
    switch (typeof l) {
      case "string": r = setProp(l, r, ss[n]); break
      case "number": r = setIndex(l, r, ss[n]); break
    }
  }

  return r
}

function modifyI(l, x2x, s) {
  switch (typeof l) {
    case "string":   return setProp(l, x2x(getProp(l, s)), s)
    case "number":   return setIndex(l, x2x(getIndex(l, s)), s)
    case "function": return lifted(l)(Ident, x2x, s)
    default:         return modifyComposedI(l, x2x, s)
  }
}

const lensI = (getter, setter) => (F, inner, target) =>
  F.map(focus => setter(focus, target), inner(getter(target)))
const collectI = (l, s) =>
  PartialList.toArray(lift(l)(Collect, PartialList.of, s))

export const remove = curry2((l, s) => setI(l, undefined, s))
export const lens = curry2(lensI)
export const modify = curry3(modifyI)
export const set = curry3(setI)
export const get = curry2(getI)
export const getInverse = curry2(getInverseI)
export const collect = curry2(collectI)

export const foldMapOf = curry4((m, l, to, s) => {
  const Const = ConstOf(m)
  return lift(l)(Const, to, s)
})

export const inverse = iso => (F, inner, x) =>
  F.map(x => getI(iso, x), inner(getInverseI(iso, x)))

export const chain = curry2((x2yL, xL) =>
  [xL, choose(xO => xO !== undefined ? x2yL(xO) : nothing)])

export const just = x => lensI(always(x), snd)

export const choose = x2yL => (F, inner, target) =>
  lift(x2yL(target))(F, inner, target)

export const nothing = lensI(snd, snd)

export const orElse =
  curry2((d, l) => choose(x => getI(l, x) !== undefined ? l : d))

export const choice = (...ls) => choose(x => {
  const i = ls.findIndex(l => getI(l, x) !== undefined)
  return 0 <= i ? ls[i] : nothing
})

const replacer = (inn, out) => x => acyclicEqualsU(x, inn) ? out : x
const normalizer = fn => (F, inner, x) => F.map(fn, inner(fn(x)))

export const replace = curry2((inn, out) => (F, inner, x) =>
  F.map(replacer(out, inn), inner(replacer(inn, out)(x))))

export const defaults = out => (F, inner, x) =>
  F.map(replacer(out, undefined), inner(x !== undefined ? x : out))
export const required = inn => replace(inn, undefined)
export const define = v => normalizer(x => x !== undefined ? x : v)

export const valueOr = v => (_F, inner, x) =>
  inner(x !== undefined && x !== null ? x : v)

export const normalize = transform => normalizer(toPartial(transform))

const isProp = x => typeof x === "string"

export const prop = assert("a string", isProp)

const getProp = (k, o) => isObject(o) ? o[k] : undefined
const setProp = (k, v, o) =>
  v !== undefined ? assocPartialU(k, v, o) : dissocPartialU(k, o)

const liftProp = k => (F, inner, o) =>
  F.map(v => setProp(k, v, o), inner(getProp(k, o)))

export const find = predicate => choose(xs => {
  if (isArray(xs)) {
    const i = xs.findIndex(predicate)
    return i < 0 ? append : i
  } else {
    return append
  }
})

export function findWith(...ls) {
  const lls = compose(...ls)
  return [find(x => getI(lls, x) !== undefined), lls]
}

const isIndex = x => Number.isInteger(x) && 0 <= x

export const index = assert("a non-negative integer", isIndex)

const nulls = n => Array(n).fill(null)

const getIndex = (i, xs) => isArray(xs) ? xs[i] : undefined
function setIndex(i, x, xs) {
  if (x !== undefined) {
    if (!isArray(xs))
      return i < 0 ? undefined : nulls(i).concat([x])
    const n = xs.length
    if (n <= i)
      return xs.concat(nulls(i - n), [x])
    if (i < 0)
      return !n ? undefined : xs
    const ys = Array(n)
    for (let j=0; j<n; ++j)
      ys[j] = xs[j]
    ys[i] = x
    return ys
  } else {
    if (!isArray(xs))
      return undefined
    const n = xs.length
    if (!n)
      return undefined
    if (i < 0 || n <= i)
      return xs
    if (n === 1)
      return undefined
    const ys = Array(n-1)
    for (let j=0; j<i; ++j)
      ys[j] = xs[j]
    for (let j=i+1; j<n; ++j)
      ys[j-1] = xs[j]
    return ys
  }
}
const liftIndex = i => (F, inner, xs) =>
  F.map(x => setIndex(i, x, xs), inner(getIndex(i, xs)))

export const append = lensI(snd, (x, xs) =>
  x !== undefined ? isArray(xs) ? xs.concat([x]) : [x] : unArray(xs))

export const filter = p => lensI(xs => unArray(xs) && xs.filter(p), (ys, xs) =>
  emptyArrayToUndefined(mkArray(ys).concat(mkArray(xs).filter(x => !p(x)))))

export const augment = template => lensI(
  x => {
    if (isObject(x)) {
      const z = {...x}
      for (const k in template)
        z[k] = template[k](z)
      return z
    } else {
      return undefined
    }
  },
  (y, cIn) => {
    if (isObject(y)) {
      const c = isObject(cIn) ? cIn : emptyObject
      let z
      const set = (k, v) => {
        if (!z)
          z = {}
        z[k] = v
      }
      for (const k in y) {
        if (!(k in template))
          set(k, y[k])
        else
          if (k in c)
            set(k, c[k])
      }
      return z
    } else {
      return undefined
    }
  })

function getPick(template, target) {
  let r
  for (const k in template) {
    const v = getI(template[k], target)
    if (v !== undefined) {
      if (!r)
        r = {}
      r[k] = v
    }
  }
  return r
}
const setPick = (template, target) => value => {
  const o = value || emptyObject
  let c = target
  for (const k in template)
    c = setI(template[k], o[k], c)
  return c
}
export const pick = template => (F, inner, target) =>
  F.map(setPick(template, target), inner(getPick(template, target)))

export const identity = (_F, inner, t) => inner(t)

export const props = (...ks) => pick(zipObjPartialU(ks, ks))

const show = (labels, dir) => x => console.log(...labels, dir, x) || x

export const log = (...labels) =>
  lensI(show(labels, "get"), show(labels, "set"))

export const sequence = (A, inner, target) =>
  A === Ident
  ? emptyArrayToUndefined(mapPartialU(inner, mkArray(target)))
  : A.map(emptyArrayToUndefined, PartialArray.traverse(A, inner, mkArray(target)))

export const optional = (A, inner, target) =>
  target !== undefined ? inner(target) : A.of(undefined)

export const fromArrayBy = id =>
  warn("`fromArrayBy` is experimental and might be removed, renamed or changed semantically before next major release") ||
  lensI(xs => {
    if (isArray(xs)) {
      const o = {}, n=xs.length
      for (let i=0; i<n; ++i) {
        const x = xs[i]
        o[x[id]] = x
      }
      return o
    }
  },
  o => isObject(o) ? values(o) : undefined)

export default compose
<|endoftext|>


<commit_before>console.log('Rebuilding development vendor bundle, please wait...');

const exec = require('child_process').execSync;
const output = exec('npm run build:dev');

console.log();
console.log(output);

<commit_msg>updated jspm postinstall behaviour<commit_after>const devBundleCommand = 'npm run dev:bundle';

// console.log('Rebuilding development vendor bundle, please wait...\n');
// const exec = require('child_process').execSync;
// const output = exec(devBundleCommand);
// console.log(output);

console.log(`
     After installing dependencies consider rebuilding dev vendor bundle with "${devBundleCommand}" command.
`
);
<|endoftext|>


<commit_before>

if(process.env.NODE_ENV === "production")
{
    const exec = require('child_process').execSync;

    exec("heroku config:set NPM_CONFIG_PRODUCTION=false");
}<commit_msg>testing heroku<commit_after>

if(process.env.NODE_ENV === "production")
{
    const exec = require('child_process').execSync;

    exec("sudo ln -s /usr/local/heroku/bin/heroku /usr/bin/heroku");
    exec("heroku config:set NPM_CONFIG_PRODUCTION=false");
}<|endoftext|>


<commit_before>// registerapp.js
//
// Make a new app key and secret
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var _ = require("underscore"),
    postArgs = require("./common").postArgs;

var argv = require("optimist")
        .usage("Usage: $0 -t title -e email [-w|-n]")
        .demand(["t"])
        .alias("t", "title")
        .alias("e", "email")
        .alias("w", "web")
        .alias("n", "native")
        .alias("s", "server")
        .alias("P", "port")
        .describe("t", "Title of the app")
        .describe("e", "Contact email")
        .describe("w", "Web application")
        .describe("n", "Native application")
        .describe("s", "Server name")
        .describe("P", "Port")
        .default("P", 8001)
        .default("s", "localhost")
        .argv;

var server = argv.server,
    port = argv.port;

var args = {
    type: "client_associate",
    application_name: argv.title
};

if (argv.web) {
    args.application_type = "web";
} else if (argv["native"]) {
    args.application_type = "native";
}

if (argv.email) {
    args.contacts = argv.email;
};

postArgs("http://"+server+":"+port+"/api/client/register", args, function(err, res, body) {
    if (err) {
        console.error(err);
    } else {
        console.log(body);
    }
});
<commit_msg>setClientCred() when registering app<commit_after>// registerapp.js
//
// Make a new app key and secret
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var _ = require("underscore"),
    Step = require("step"),
    url = require("url"),
    common = require("./common"),
    postArgs = common.postArgs,
    setClientCred = common.setClientCred;

var argv = require("optimist")
        .usage("Usage: $0 -t title -e email [-w|-n]")
        .demand(["t"])
        .alias("t", "title")
        .alias("e", "email")
        .alias("w", "web")
        .alias("n", "native")
        .alias("s", "server")
        .alias("P", "port")
        .describe("t", "Title of the app")
        .describe("e", "Contact email")
        .describe("w", "Web application")
        .describe("n", "Native application")
        .describe("s", "Server name")
        .describe("P", "Port")
        .default("P", 80)
        .default("s", "localhost")
        .argv;

var server = argv.server,
    port = argv.port;

var args = {
    type: "client_associate",
    application_name: argv.title
};

if (argv.web) {
    args.application_type = "web";
} else if (argv["native"]) {
    args.application_type = "native";
}

if (argv.email) {
    args.contacts = argv.email;
};

Step(
    function() {
        var endpoint = url.format({
            protocol: "http",
            host: ((port == 80) ? server : server + ":" + port),
            pathname: "/api/client/register"
        });
        console.log(endpoint);
        postArgs(endpoint, args, this);
    },
    function(err, res, body) {
        if (err) throw err;
        var cred = JSON.parse(body);
        setClientCred(server, cred, this);
    },
    function(err) {
        if (err) {
            console.error(err);
        } else {
            console.log("OK");
        }
    }
);
<|endoftext|>


<commit_before>// var remoteUrl = "https://api.carpoolvote.com/live";
var remoteUrl = "http://localhost:8000";

var driverLoggedIn = false;
var riderLoggedIn = false;

// Create a data object containing all URL query string data:
var data = tinyQuery.getAll();

if (data.uuid_driver) {
  data.uuid = data.uuid || data.uuid_driver;
  data.type = data.type || 'driver';
}
if (data.uuid_rider) {
  data.uuid = data.uuid || data.uuid_rider;
  data.type = data.type || 'rider';
}

// Cache jQuery selectors:
var $login = $('#login'),
  $manage = $('#manage'),
  $manageLogin = $('#manageLogin'),
  $info = $manage.find('#info'),
  $infoLogin = $manageLogin.find('#info')
  ;

if (data.uuid) {
  $login.find('#enter-uuid').remove();
}
if (data.type) {
  $login.find('#enter-type').remove();
}

$login.validator().on('submit', function(e) {
  if (e.isDefaultPrevented()) {
    return;
  }
  data.uuid = data.uuid || $(this).find('#inputUUID').val();
  data.type = data.type || $(this).find('#enter-type').find('input:checked').val();
  data.phone = $(this).find('#inputPhoneNumber').val();

  if (data.type === "driver") {
    driverExists();
  }
  else {
    riderExists();
  }

  // done in driver exists
  //
  // $(this).slideUp(300).attr('aria-hidden','true');
  // $manage.slideDown(300).attr('aria-hidden','false');
  // updateUI();
  e.preventDefault();
});

function updateUI(uuid, type, phone) {
  $manage.find('#btnCancelDriveOffer').toggle(data.type === 'driver');
  $manage.find('#btnCancelDriverMatch').toggle(data.type === 'driver' && data.score !== 'undefined');
  $manage.find('#btnPauseDriverMatch').toggle(data.type === 'driver' && data.score !== 'undefined');

  $manage.find('#btnCancelRideRequest').toggle(data.type === 'rider');
  $manage.find('#btnCancelRiderMatch').toggle(data.type === 'rider' && data.score !== 'undefined');

  $manage.find('#btnAcceptDriverMatch').toggle(data.type === 'driver' && data.score !== 'undefined');
}

$manage
  .on('click', '#btnCancelRideRequest', cancelRideRequest)
  .on('click', '#btnCancelRiderMatch', cancelRiderMatch)
  .on('click', '#btnCancelDriveOffer', cancelDriveOffer)
  .on('click', '#btnCancelDriverMatch', cancelDriverMatch)
  .on('click', '#btnPauseDriverMatch', pauseDriverMatch)
  .on('click', '#btnAcceptDriverMatch', acceptDriverMatch)
  .on('click', '#logout', logout);

function cancelRideRequest() {
  if (!window.confirm('This will cancel your ride request. Are you sure you want to proceed?')) {
    return;
  }
  sendAjaxRequest(
    {
      uuid: data.uuid,
      RiderPhone: data.phone
    },
    '/cancel-ride-request'
  );
}

function cancelRiderMatch() {
  if (!window.confirm('This will cancel your ride match. Are you sure you want to proceed?')) {
    return;
  }
  sendAjaxRequest(
    {
      UUID_driver: data.uuid_driver,
      UUID_rider: data.uuid,
      Score: data.score,
      RiderPhone: data.phone
    },
    '/cancel-rider-match'
  );
}

function cancelDriveOffer() {
  if (!window.confirm('This will cancel your ride offer. Are you sure you want to proceed?')) {
    return;
  }
  sendAjaxRequest(
    {
      uuid: data.uuid,
      DriverPhone: data.phone
    },
    '/cancel-drive-offer'
  );
}

function cancelDriverMatch() {
  if (!window.confirm('This will cancel your ride match. Are you sure you want to proceed?')) {
    return;
  }
  sendAjaxRequest(
    {
      UUID_driver: data.uuid_driver,
      UUID_rider: data.uuid,
      Score: data.score,
      RiderPhone: data.phone
    },
    '/cancel-driver-match'
  );
}

function acceptDriverMatch() {
  sendAjaxRequest(
    {
      UUID_driver: data.uuid,
      UUID_rider: data.uuid_rider,
      Score: data.score,
      DriverPhone: data.phone
    },
    '/accept-driver-match'
  );
}

function pauseDriverMatch() {
  sendAjaxRequest(
    {
      uuid: data.uuid,
      DriverPhone: data.phone
    },
    '/pause-driver-match'
  );
}

function logout() {
  window.location.search = tinyQuery.remove(['type','uuid','uuid_driver','uuid_rider']);
}

function sendAjaxRequest(ajaxData, ajaxPath) {
  var url = tinyQuery.set(ajaxData, remoteUrl + ajaxPath);

  $info.html('⏳ Loading…');

  $.getJSON(url, function(dbInfo) {
    var keys = Object.keys(dbInfo);
    if (keys) {
      info = dbInfo[keys[0]].toString();
      $info.text('ℹ ' + info);
    }
  })
  .fail(function(err) {
    $info.text('⚠ ' + err.statusText);
  });
}

function driverExists () {
//http://localhost:8000/driver-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&DriverPhone=Test

  var url =
    remoteUrl + '/driver-exists?' +
    'UUID=' + data.uuid +
    '&DriverPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      var keys = Object.keys(resp);
      if (keys) {
        info = resp[keys[0]].toString();
        // $info.text(info);
        $infoLogin.text(info);

        if (keys[0] == "driver_exists" && info === "") {
          driverLoggedIn = true;

          $(this).slideUp(300).attr('aria-hidden','true');
          $manage.slideDown(300).attr('aria-hidden','false');
          updateUI();

          driverInfo();
          driverProposedMatches();
          driverConfirmedMatches();

        }
      }
    }
  };
}

function driverInfo () {
//http://localhost:8000/driver-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&DriverPhone=Test

  var url =
    remoteUrl + '/driver-info?' +
    'UUID=' + data.uuid +
    '&DriverPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      var keys = Object.keys(resp);
      if (keys) {

        if (keys[0] == "driver_info" ) {

          var driverInfo = resp[keys[0]];
          var i = 0;

$("#driverInfo ul").append('
' + driverInfo.DriverFirstName + '
');
$("#driverInfo ul").append('
' + driverInfo.DriverLastName + '
');
$("#driverInfo ul").append('
' + driverInfo.UUID + '
');
$("#driverInfo ul").append('
' + driverInfo.DriverCollectionZIP + '
');
$("#driverInfo ul").append('
' + driverInfo.DriverEmail + '
');
$("#driverInfo ul").append('
' + driverInfo.DriverPhone + '
');
$("#driverInfo ul").append('
' + driverInfo.DriverLicenseNumber + '
');

        }
      }
    }
  };
}

function driverProposedMatches () {
//http://localhost:8000/driver-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&DriverPhone=Test

  var url =
    remoteUrl + '/driver-proposed-matches?' +
    'UUID=' + data.uuid +
    '&DriverPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      resp.forEach(val => {

          $("#driverProposedMatches ul").append('
 UUID_driver - ' + val.driver_proposed_matches.uuid_driver + '
');
  $("#driverProposedMatches ul").append('
  UUID_rider - ' + val.driver_proposed_matches.uuid_rider + '
');
  $("#driverProposedMatches ul").append('
 Score - ' + val.driver_proposed_matches.score + '
');

      });

    }
  };
}

function driverConfirmedMatches () {
//http://localhost:8000/driver-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&DriverPhone=Test

  var url =
    remoteUrl + '/driver-confirmed-matches?' +
    'UUID=' + data.uuid +
    '&DriverPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      resp.forEach(val => {

          $("#driverConfirmedMatches ul").append('
 UUID_driver - ' + val.driver_confirmed_matches.uuid_driver + '
');
  $("#driverConfirmedMatches ul").append('
  UUID_rider - ' + val.driver_confirmed_matches.uuid_rider + '
');
  $("#driverConfirmedMatches ul").append('
 Score - ' + val.driver_confirmed_matches.score + '
');

      });

    }
  };
}

function riderExists () {
//http://localhost:8000/rider-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&RiderPhone=Test

  var url =
    remoteUrl + '/rider-exists?' +
    'UUID=' + data.uuid +
    '&RiderPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      var keys = Object.keys(resp);
      if (keys) {
        info = resp[keys[0]].toString();
        // $info.text(info);
        $infoLogin.text(info);

        if (keys[0] == "rider_exists" && info === "") {
          riderLoggedIn = true;

          $(this).slideUp(300).attr('aria-hidden','true');
          $manage.slideDown(300).attr('aria-hidden','false');
          updateUI();

          riderInfo();
          riderConfirmedMatch();
        }
      }
    }
  };
}

function riderInfo () {
//http://localhost:8000/rider-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&RiderPhone=Test

  var url =
    remoteUrl + '/rider-info?' +
    'UUID=' + data.uuid +
    '&RiderPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      var keys = Object.keys(resp);
      if (keys) {

        if (keys[0] == "rider_info" ) {

          var riderInfo = resp[keys[0]];
          var i = 0;

$("#riderInfo ul").append('
' + riderInfo.RiderFirstName + '
');
$("#riderInfo ul").append('
' + riderInfo.RiderLastName + '
');
$("#riderInfo ul").append('
' + riderInfo.UUID + '
');
$("#riderInfo ul").append('
' + riderInfo.RiderCollectionZIP + '
');
$("#riderInfo ul").append('
' + riderInfo.RiderEmail + '
');
$("#riderInfo ul").append('
' + riderInfo.RiderPhone + '
');

        }
      }
    }
  };
}

function riderConfirmedMatch () {
//http://localhost:8000/rider-confirmed-match?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&DriverPhone=Test

  var url =
    remoteUrl + '/rider-confirmed-match?' +
    'UUID=' + data.uuid +
    '&RiderPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      if (resp.rider_confirmed_match.uuid_driver !== null) {
        $("#riderConfirmedMatch ul").append('
 UUID_driver - ' + resp.rider_confirmed_match.uuid_driver + '
');
        $("#riderConfirmedMatch ul").append('
  UUID_rider - ' + resp.rider_confirmed_match.uuid_rider + '
');
        $("#riderConfirmedMatch ul").append('
 Score - ' + resp.rider_confirmed_match.score + '
');
      }
    }
  };
}

<commit_msg>accept button<commit_after>// var remoteUrl = "https://api.carpoolvote.com/live";
var remoteUrl = "http://localhost:8000";

var driverLoggedIn = false;
var riderLoggedIn = false;

// Create a data object containing all URL query string data:
var data = tinyQuery.getAll();

if (data.uuid_driver) {
  data.uuid = data.uuid || data.uuid_driver;
  data.type = data.type || 'driver';
}
if (data.uuid_rider) {
  data.uuid = data.uuid || data.uuid_rider;
  data.type = data.type || 'rider';
}

// Cache jQuery selectors:
var $login = $('#login'),
  $manage = $('#manage'),
  $manageLogin = $('#manageLogin'),
  $info = $manage.find('#info'),
  $infoLogin = $manageLogin.find('#info')
  ;

if (data.uuid) {
  $login.find('#enter-uuid').remove();
}
if (data.type) {
  $login.find('#enter-type').remove();
}

$login.validator().on('submit', function(e) {
  if (e.isDefaultPrevented()) {
    return;
  }
  data.uuid = data.uuid || $(this).find('#inputUUID').val();
  data.type = data.type || $(this).find('#enter-type').find('input:checked').val();
  data.phone = $(this).find('#inputPhoneNumber').val();

  if (data.type === "driver") {
    driverExists();
  }
  else {
    riderExists();
  }

  // done in driver exists
  //
  // $(this).slideUp(300).attr('aria-hidden','true');
  // $manage.slideDown(300).attr('aria-hidden','false');
  // updateUI();
  e.preventDefault();
});

function updateUI(uuid, type, phone) {
  $manage.find('#btnCancelDriveOffer').toggle(data.type === 'driver');
  $manage.find('#btnCancelDriverMatch').toggle(data.type === 'driver' && data.score !== 'undefined');
  $manage.find('#btnPauseDriverMatch').toggle(data.type === 'driver' && data.score !== 'undefined');

  $manage.find('#btnCancelRideRequest').toggle(data.type === 'rider');
  $manage.find('#btnCancelRiderMatch').toggle(data.type === 'rider' && data.score !== 'undefined');

  $manage.find('#btnAcceptDriverMatch').toggle(data.type === 'driver' && data.score !== 'undefined');
}

$manage
  .on('click', '#btnCancelRideRequest', cancelRideRequest)
  .on('click', '#btnCancelRiderMatch', cancelRiderMatch)
  .on('click', '#btnCancelDriveOffer', cancelDriveOffer)
  .on('click', '#btnCancelDriverMatch', cancelDriverMatch)
  .on('click', '#btnPauseDriverMatch', pauseDriverMatch)
  .on('click', '#btnAcceptDriverMatch', acceptDriverMatch)
  .on('click', '#logout', logout);

function cancelRideRequest() {
  if (!window.confirm('This will cancel your ride request. Are you sure you want to proceed?')) {
    return;
  }
  sendAjaxRequest(
    {
      uuid: data.uuid,
      RiderPhone: data.phone
    },
    '/cancel-ride-request'
  );
}

function cancelRiderMatch() {
  if (!window.confirm('This will cancel your ride match. Are you sure you want to proceed?')) {
    return;
  }
  sendAjaxRequest(
    {
      UUID_driver: data.uuid_driver,
      UUID_rider: data.uuid,
      Score: data.score,
      RiderPhone: data.phone
    },
    '/cancel-rider-match'
  );
}

function cancelDriveOffer() {
  if (!window.confirm('This will cancel your ride offer. Are you sure you want to proceed?')) {
    return;
  }
  sendAjaxRequest(
    {
      uuid: data.uuid,
      DriverPhone: data.phone
    },
    '/cancel-drive-offer'
  );
}

function cancelDriverMatch() {
  if (!window.confirm('This will cancel your ride match. Are you sure you want to proceed?')) {
    return;
  }
  sendAjaxRequest(
    {
      UUID_driver: data.uuid_driver,
      UUID_rider: data.uuid,
      Score: data.score,
      RiderPhone: data.phone
    },
    '/cancel-driver-match'
  );
}

function acceptDriverMatch() {
  sendAjaxRequest(
    {
      UUID_driver: data.uuid,
      UUID_rider: data.uuid_rider,
      Score: data.score,
      DriverPhone: data.phone
    },
    '/accept-driver-match'
  );
}

function pauseDriverMatch() {
  sendAjaxRequest(
    {
      uuid: data.uuid,
      DriverPhone: data.phone
    },
    '/pause-driver-match'
  );
}

function logout() {
  window.location.search = tinyQuery.remove(['type','uuid','uuid_driver','uuid_rider']);
}

function sendAjaxRequest(ajaxData, ajaxPath) {
  var url = tinyQuery.set(ajaxData, remoteUrl + ajaxPath);

  $info.html('⏳ Loading…');

  $.getJSON(url, function(dbInfo) {
    var keys = Object.keys(dbInfo);
    if (keys) {
      info = dbInfo[keys[0]].toString();
      $info.text('ℹ ' + info);
    }
  })
  .fail(function(err) {
    $info.text('⚠ ' + err.statusText);
  });
}

function driverExists () {
//http://localhost:8000/driver-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&DriverPhone=Test

  var url =
    remoteUrl + '/driver-exists?' +
    'UUID=' + data.uuid +
    '&DriverPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      var keys = Object.keys(resp);
      if (keys) {
        info = resp[keys[0]].toString();
        // $info.text(info);
        $infoLogin.text(info);

        if (keys[0] == "driver_exists" && info === "") {
          driverLoggedIn = true;

          $(this).slideUp(300).attr('aria-hidden','true');
          $manage.slideDown(300).attr('aria-hidden','false');
          updateUI();

          driverInfo();
          driverProposedMatches();
          driverConfirmedMatches();

        }
      }
    }
  };
}

function driverInfo () {
//http://localhost:8000/driver-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&DriverPhone=Test

  var url =
    remoteUrl + '/driver-info?' +
    'UUID=' + data.uuid +
    '&DriverPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      var keys = Object.keys(resp);
      if (keys) {

        if (keys[0] == "driver_info" ) {

          var driverInfo = resp[keys[0]];
          var i = 0;

$("#driverInfo ul").append('
' + driverInfo.DriverFirstName + '
');
$("#driverInfo ul").append('
' + driverInfo.DriverLastName + '
');
$("#driverInfo ul").append('
' + driverInfo.UUID + '
');
$("#driverInfo ul").append('
' + driverInfo.DriverCollectionZIP + '
');
$("#driverInfo ul").append('
' + driverInfo.DriverEmail + '
');
$("#driverInfo ul").append('
' + driverInfo.DriverPhone + '
');
$("#driverInfo ul").append('
' + driverInfo.DriverLicenseNumber + '
');

        }
      }
    }
  };
}

function acceptDriverMatch(UUID_driver, UUID_rider, Score, DriverPhone) {

  var acceptUrl = remoteUrl + '/accept-driver-match?UUID_driver=' + UUID_driver +
                            '&UUID_rider=' + UUID_rider +
                            '&Score=' + Score +
                            '&DriverPhone=' + DriverPhone;

  var request = new XMLHttpRequest();

  request.open("GET", acceptUrl);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      var keys = Object.keys(resp);
      if (keys) {
        info = resp[keys[0]].toString();
        // $info.text(info);
        $infoLogin.text(info);

        if (keys[0] == "driver_accept_match" && info === "") {
          // driverLoggedIn = true;

          // $(this).slideUp(300).attr('aria-hidden','true');
          // $manage.slideDown(300).attr('aria-hidden','false');
          // updateUI();

          // driverInfo();
          driverProposedMatches();
          driverConfirmedMatches();
        }
      }
    }
  };

}

function driverProposedMatches () {
//http://localhost:8000/driver-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&DriverPhone=Test

  var url =
    remoteUrl + '/driver-proposed-matches?' +
    'UUID=' + data.uuid +
    '&DriverPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      resp.forEach(val => {
// var acceptUrl = remoteUrl + '/accept-driver-match?UUID_driver=' + val.driver_proposed_matches.uuid_driver +
//                             '&UUID_rider=' + val.driver_proposed_matches.uuid_rider +
//                             '&Score=' + val.driver_proposed_matches.score +
//                             '&DriverPhone=' + data.phone;
var btnFn = "acceptDriverMatch(" +
  val.driver_proposed_matches.uuid_driver + ', ' +
  val.driver_proposed_matches.uuid_rider  + ', ' +
  val.driver_proposed_matches.score       + ', ' +
  data.phone + ")";

var buttonInList =
  '<button class="button" onclick="' +
  btnFn +
  '">Accept</button>';

          $("#driverProposedMatches ul").append('
 UUID_driver - ' + val.driver_proposed_matches.uuid_driver + '
');
  $("#driverProposedMatches ul").append('
  UUID_rider - ' + val.driver_proposed_matches.uuid_rider + '
');
  $("#driverProposedMatches ul").append('
 Score - ' + val.driver_proposed_matches.score + '
');
  // $("#driverProposedMatches ul").append('
 Accept - Accept
');
  $("#driverProposedMatches ul").append('
' + buttonInList + '
');
  $("#driverProposedMatches ul").append('

');

// https://api.carpoolvote.com/v2.0/accept-driver-match?UUID_driver=1e6e274d-ad33-4127-9f02-f35b48a07897&UUID_rider=1e6e274d-ad33-4127-9f02-f35b48a07897&Score=123&DriverPhone=123

      });

    }
  };
}

function driverConfirmedMatches () {
//http://localhost:8000/driver-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&DriverPhone=Test

  var url =
    remoteUrl + '/driver-confirmed-matches?' +
    'UUID=' + data.uuid +
    '&DriverPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      resp.forEach(val => {

          $("#driverConfirmedMatches ul").append('
 UUID_driver - ' + val.driver_confirmed_matches.uuid_driver + '
');
  $("#driverConfirmedMatches ul").append('
  UUID_rider - ' + val.driver_confirmed_matches.uuid_rider + '
');
  $("#driverConfirmedMatches ul").append('
 Score - ' + val.driver_confirmed_matches.score + '
');

      });

    }
  };
}

function riderExists () {
//http://localhost:8000/rider-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&RiderPhone=Test

  var url =
    remoteUrl + '/rider-exists?' +
    'UUID=' + data.uuid +
    '&RiderPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      var keys = Object.keys(resp);
      if (keys) {
        info = resp[keys[0]].toString();
        // $info.text(info);
        $infoLogin.text(info);

        if (keys[0] == "rider_exists" && info === "") {
          riderLoggedIn = true;

          $(this).slideUp(300).attr('aria-hidden','true');
          $manage.slideDown(300).attr('aria-hidden','false');
          updateUI();

          riderInfo();
          riderConfirmedMatch();
        }
      }
    }
  };
}

function riderInfo () {
//http://localhost:8000/rider-exists?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&RiderPhone=Test

  var url =
    remoteUrl + '/rider-info?' +
    'UUID=' + data.uuid +
    '&RiderPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      var keys = Object.keys(resp);
      if (keys) {

        if (keys[0] == "rider_info" ) {

          var riderInfo = resp[keys[0]];
          var i = 0;

$("#riderInfo ul").append('
' + riderInfo.RiderFirstName + '
');
$("#riderInfo ul").append('
' + riderInfo.RiderLastName + '
');
$("#riderInfo ul").append('
' + riderInfo.UUID + '
');
$("#riderInfo ul").append('
' + riderInfo.RiderCollectionZIP + '
');
$("#riderInfo ul").append('
' + riderInfo.RiderEmail + '
');
$("#riderInfo ul").append('
' + riderInfo.RiderPhone + '
');

        }
      }
    }
  };
}

function riderConfirmedMatch () {
//http://localhost:8000/rider-confirmed-match?UUID=32e5cbd4-1342-4e1e-9076-0147e779a796&DriverPhone=Test

  var url =
    remoteUrl + '/rider-confirmed-match?' +
    'UUID=' + data.uuid +
    '&RiderPhone=' + data.phone;

  var request = new XMLHttpRequest();

  request.open("GET", url);
  request.send();

  request.onreadystatechange = function () {
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
      console.log(request.responseText);

      var resp = JSON.parse(request.responseText);

      if (resp.rider_confirmed_match.uuid_driver !== null) {
        $("#riderConfirmedMatch ul").append('
 UUID_driver - ' + resp.rider_confirmed_match.uuid_driver + '
');
        $("#riderConfirmedMatch ul").append('
  UUID_rider - ' + resp.rider_confirmed_match.uuid_rider + '
');
        $("#riderConfirmedMatch ul").append('
 Score - ' + resp.rider_confirmed_match.score + '
');
      }
    }
  };
}

<|endoftext|>


<commit_before>QUnit.module( "ItemView" );

/**
 * Test initialization logic. It should not be possible to initialize an
 * ItemView without a model, or with an invalid model.
 */
QUnit.test( "initialize", function( assert ) {
  assert.throws(
    function() {
      var view = new ArchibaldCurriculum.ItemView();
    },
    "Initializing a view without any model throws an error."
  );

  assert.throws(
    function() {
      var item = new ArchibaldCurriculum.ItemModel(),
          view = new ArchibaldCurriculum.ItemView({ model: item });
    },
    "Initializing a view with an invalid model throws an error."
  );
});

/**
 * Test model event binding. ItemViews should react on several model events.
 */
QUnit.test( "model events", function( assert ) {
  assert.expect( 4 );

  var doneChangeEvent = assert.async(),
      item1 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ] }),
      view1 = new ArchibaldCurriculum.ItemView({ model: item1 });
  view1.on( 'render', function() {
    assert.ok( true, "The view re-renders itself on updating its model." );
    doneChangeEvent();
  });
  item1.set( 'name', [ "Some new name" ] );

  var doneDestroyEvent = assert.async( 2 ),
      item2 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ] }),
      view2 = new ArchibaldCurriculum.ItemView({ model: item2 });
  view2.render().$el.appendTo( '#qunit-fixture' );
  assert.ok( view2.$el.parent()[0], "The view was correctly rendered and added to the DOM." );
  view2.on( 'model:destroy', function() {
    assert.ok( true, "The view triggers a model:destroy event on destroying its model." );
    doneDestroyEvent();
  });
  item2.destroy();
  assert.notOk( view2.$el.parent()[0], "The view was correctly removed from the DOM." );
  doneDestroyEvent();
});

/**
 * Test ItemView rendering. ItemViews render differently based on passed
 * arguments.
 */
QUnit.test( "rendering", function( assert ) {
  var item1 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ] }),
      view1 = new ArchibaldCurriculum.ItemView({ model: item1, editable: true }),
      view2 = new ArchibaldCurriculum.ItemView({ model: item1, editable: false }),
      view3 = new ArchibaldCurriculum.ItemView({ model: item1 });

  view1.render();
  view2.render();
  view3.render();

  assert.ok( view1.$el.find( 'input' ).length, "An editable view has an input." );
  assert.notOk( view2.$el.find( 'input' ).length, "A non-editable (explicit) view has no input." );
  assert.notOk( view3.$el.find( 'input' ).length, "A non-editable (implicit) view has no input." );
});

/**
 * Test ItemView events. ItemViews trigger several events, as well as react to
 * multiple DOM events.
 */
QUnit.test( "view events", function( assert ) {
  assert.expect( 11 );

  var doneCheckboxEvent = assert.async( 2 ),
      checked = false,
      item1 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ], active: checked }),
      view1 = new ArchibaldCurriculum.ItemView({ model: item1, editable: true });
  view1.on( 'model:change', function( itemModel, itemView, e ) {
    // The active (checked) state should have changed.
    checked != checked;
    assert.ok( true, "The view triggers a model:change event on checking the checkbox." );
    assert.equal( itemModel.get( 'active'), checked, "The model active state correctly changed." );
    doneCheckboxEvent();
  });
  // (Un)check on the checkbox, twice.
  view1.render();
  view1.$el.find('input').change();
  view1.$el.find('input').change();

  var doneClickEvent = assert.async(),
      item2 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ] }),
      view2 = new ArchibaldCurriculum.ItemView({ model: item2, editable: true });
  view2.on( 'select', function() {
    assert.ok( true, "The view triggers a select event on being clicked." );
    doneClickEvent();
  });
  // Click on the element.
  view2.render();
  view2.$el.click();
  // A click on the checkbox should not bubble up.
  view2.$el.find('input').click();

  var doneDblClickEvent = assert.async( 2 ),
      item3 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ], active: false }),
      view3 = new ArchibaldCurriculum.ItemView({ model: item3, editable: true });
  view3.on( 'active', function( state, itemModel, itemView ) {
    assert.ok( true, "The view triggers a active event on being double-clicked." );
    assert.equal( state, true, "The passed state is correct." );
    assert.equal( itemModel.get( 'active'), true, "The model active state correctly changed." );
    doneDblClickEvent();
  });
  view3.on( 'unactive', function( state, itemModel, itemView ) {
    assert.ok( true, "The view triggers an unactive event on being double-clicked." );
    assert.equal( state, false, "The passed state is correct." );
    assert.equal( itemModel.get( 'active'), false, "The model active state correctly changed." );
    doneDblClickEvent();
  });
  view3.on( 'select', function( state, itemModel, itemView ) {
    assert.ok( false, "The view should not trigger a click event when double-clicked." );
  });
  // Double-click on the element, twice.
  view3.render();
  view3.$el.dblclick();
  view3.$el.dblclick();
});

QUnit.module( "ItemListView" );

/**
 * Test initialization logic. It should not be possible to initialize an
 * ItemListView without a collection.
 */
QUnit.test( "initialize", function( assert ) {
  assert.throws(
    function() {
      var view = new ArchibaldCurriculum.ItemListView();
    },
    "Initializing a view without any collection throws an error."
  );
});

/**
 * Test collection event binding. ItemListViews should react on several
 * collection events.
 */
QUnit.test( "collection events", function( assert ) {
  assert.expect( 6 );

  var doneAddRemoveEvent = assert.async( 2 ),
      doneRenderEvent = assert.async( 2 ),
      collection1 = new ArchibaldCurriculum.ItemCollection([ { name: [ "First item " ] }]),
      view1 = new ArchibaldCurriculum.ItemListView({ collection: collection1 }),
      addedItem = new ArchibaldCurriculum.ItemModel({ name: [ "Some name" ] });
  // Render it a first time BEFORE attaching event listeners. This will allow us
  // to cover the childViews[] array.
  view1.render();
  view1.on( 'collection:add', function( item, collection, view ) {
    assert.ok( true, "The view triggers a collection:add event on adding a model." );
    assert.equal( item, addedItem, "The view passes the added item to the event handler." );
    doneAddRemoveEvent();
  });
  view1.on( 'collection:remove', function( item, collection, view ) {
    assert.ok( true, "The view triggers a collection:remove event on removing a model." );
    assert.equal( item, addedItem, "The view passes the removed item to the event handler." );
    doneAddRemoveEvent();
  });
  view1.on( 'render', function() {
    assert.ok( true, "The view is re-rendered whenever an item is removed or added to the collection." );
    doneRenderEvent();
  });
  collection1.add( addedItem );
  collection1.remove( addedItem );
});

/**
 * Test child ItemView event binding. ItemListViews should react on several
 * child view events.
 */
QUnit.test( "child view events", function( assert ) {
  assert.expect();

  var doneSelectEvent = assert.async(),
      item1 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ] }),
      collection1 = new ArchibaldCurriculum.ItemCollection([ item1 ]),
      view1 = new ArchibaldCurriculum.ItemListView({ collection: collection1 });
  view1.on( 'item:select', function() {
    assert.ok( true, "The view triggers a item:select event on clicking on a child view." );
    doneSelectEvent();
  });
  view1.render();
  item1.set( 'name', [ "Some new name" ] );
  view1.$el.find('li').click();
});

/**
 * Test ItemListView events. ItemListViews trigger several events, as well as
 * react to multiple DOM events.
 */
QUnit.test( "view events", function( assert ) {
  assert.expect( 6 );

  var doneCollapseExpandEvent = assert.async( 2 ),
      collection1 = new ArchibaldCurriculum.ItemCollection(),
      view1 = new ArchibaldCurriculum.ItemListView({ collection: collection1 });
  view1.on( 'column:collapse', function() {
    assert.ok( true, "The view triggers a column:collapse event on being collapsed." );
    assert.ok( view1.isCollapsed(), "The view gives correct information about being collapsed." );
    doneCollapseExpandEvent();
  });
  view1.on( 'column:expand', function() {
    assert.ok( true, "The view triggers a column:expand event on being collapsed." );
    assert.ok( view1.isExpanded(), "The view gives correct information about being expanded." );
    doneCollapseExpandEvent();
  });
  view1.collapse().expand();

  var doneGoBackEvent = assert.async(),
      doneGoToRootEvent = assert.async(),
      collection2 = new ArchibaldCurriculum.ItemCollection(),
      view2 = new ArchibaldCurriculum.ItemListView({ collection: collection2 });
  view2.on( 'column:go-back', function() {
    assert.ok( true, "The view triggers a column:go-back event on clicking on the Go Back button." );
    doneGoBackEvent();
  });
  view2.on( 'column:go-to-root', function() {
    assert.ok( true, "The view triggers a column:go-to-root event on clicking on the Go Back button." );
    doneGoToRootEvent();
  });
  view2.render();
  view2.$el.find('.archibald-column__button--show-parent').click();
  view2.$el.find('.archibald-column__button--show-root').click();
});

QUnit.module( "ItemInfoView" );

/**
 * Test initialization logic. It should not be possible to initialize an
 * ItemInfoView with an invalid model.
 */
QUnit.test( "initialize", function( assert ) {
  assert.throws(
    function() {
      var item = new ArchibaldCurriculum.ItemModel(),
          view = new ArchibaldCurriculum.ItemInfoView({ model: item });
    },
    "Initializing a view with an invalid model throws an error."
  );
});

/**
 * Test view events. ItemInfoViews trigger several events.
 */
QUnit.test( "view events", function( assert ) {
  assert.expect( 3 );

  var doneRenderEvent = assert.async(),
      doneCollapseExpandEvent = assert.async( 2 ),
      model1 = new ArchibaldCurriculum.ItemModel({ name: [ "Some name" ] }),
      view1 = new ArchibaldCurriculum.ItemInfoView({ model: model1 });

  view1.on( 'render', function() {
    assert.ok( true, "The view triggers a render event when rendered." );
    doneRenderEvent();
  });
  view1.render();

  view1.on( 'collapse', function() {
    assert.ok( true, "The view triggers a collapse event when collapsed." );
    doneCollapseExpandEvent();
  });
  view1.on( 'expand', function() {
    assert.ok( true, "The view triggers a expand event when expanded." );
    doneCollapseExpandEvent();
  });
  view1.$el.find( '.archibald-curriculum-ui-item-info__label' ).click().click();
});

QUnit.module( "SummaryTreeView" );

/**
 * Test initialization logic. It should not be possible to initialize a
 * SummaryTreeView without a collection.
 */
QUnit.test( "initialize", function( assert ) {
  assert.throws(
    function() {
      var view = new ArchibaldCurriculum.SummaryTreeView();
    },
    "Initializing a view without any model throws an error."
  );
});

/**
 * Test collection event binding. SummaryTreeViews should react on several
 * collection events.
 */
QUnit.test( "collection events", function( assert ) {
  assert.expect( 3 );

  var doneRenderEvent = assert.async( 3 ),
      collection = new ArchibaldCurriculum.ItemCollection(),
      view = new ArchibaldCurriculum.SummaryTreeView({ collection: collection }),
      addedItem1 = new ArchibaldCurriculum.ItemModel({ name: [ "Some name" ] }),
      addedItem2 = new ArchibaldCurriculum.ItemModel({ name: [ "Some name" ] });
  view.on( 'render', function() {
    assert.ok( true, "The view is re-rendered whenever an item is changed, removed or added to the collection." );
    doneRenderEvent();
  });
  collection.add( addedItem1 );
  // SummaryTreeViews have a protection mechanism against too many render calls.
  // In order for our second and third events to actually trigger a re-rendering
  // we must wait a little. However, if we trigger some in quick succession on
  // purpose, we should not have more render calls than we expect.
  collection.add( addedItem2 );
  addedItem2.set({ 'name': [ "Some new name" ] });
  setTimeout(function() {
    addedItem1.set({ 'name': [ "Some new name" ] });
    setTimeout(function() {
      collection.remove( addedItem1 );
    }, 100);
  }, 100);
});
<commit_msg>Set ID for test models, add test for data classes<commit_after>QUnit.module( "ItemView" );

/**
 * Test initialization logic. It should not be possible to initialize an
 * ItemView without a model, or with an invalid model.
 */
QUnit.test( "initialize", function( assert ) {
  assert.throws(
    function() {
      var view = new ArchibaldCurriculum.ItemView();
    },
    "Initializing a view without any model throws an error."
  );

  assert.throws(
    function() {
      var item = new ArchibaldCurriculum.ItemModel(),
          view = new ArchibaldCurriculum.ItemView({ model: item });
    },
    "Initializing a view with an invalid model throws an error."
  );
});

/**
 * Test model event binding. ItemViews should react on several model events.
 */
QUnit.test( "model events", function( assert ) {
  assert.expect( 4 );

  var doneChangeEvent = assert.async(),
      item1 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ] }),
      view1 = new ArchibaldCurriculum.ItemView({ model: item1 });
  view1.on( 'render', function() {
    assert.ok( true, "The view re-renders itself on updating its model." );
    doneChangeEvent();
  });
  item1.set( 'name', [ "Some new name" ] );

  var doneDestroyEvent = assert.async( 2 ),
      item2 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ] }),
      view2 = new ArchibaldCurriculum.ItemView({ model: item2 });
  view2.render().$el.appendTo( '#qunit-fixture' );
  assert.ok( view2.$el.parent()[0], "The view was correctly rendered and added to the DOM." );
  view2.on( 'model:destroy', function() {
    assert.ok( true, "The view triggers a model:destroy event on destroying its model." );
    doneDestroyEvent();
  });
  item2.destroy();
  assert.notOk( view2.$el.parent()[0], "The view was correctly removed from the DOM." );
  doneDestroyEvent();
});

/**
 * Test ItemView rendering. ItemViews render differently based on passed
 * arguments.
 */
QUnit.test( "rendering", function( assert ) {
  var item1 = new ArchibaldCurriculum.ItemModel({
        name: [ "Model name" ],
        id:   1,
        data: { boolKey: true, otherBoolKey: false }
      }),
      view1 = new ArchibaldCurriculum.ItemView({ model: item1, editable: true }),
      view2 = new ArchibaldCurriculum.ItemView({ model: item1, editable: false }),
      view3 = new ArchibaldCurriculum.ItemView({ model: item1 });

  view1.render();
  view2.render();
  view3.render();

  assert.ok( view1.$el.find( 'input' ).length, "An editable view has an input." );
  assert.notOk( view2.$el.find( 'input' ).length, "A non-editable (explicit) view has no input." );
  assert.notOk( view3.$el.find( 'input' ).length, "A non-editable (implicit) view has no input." );
  assert.ok( view3.$el.hasClass( view3.className + '--boolKey' ), "Truthy boolean data items are added as classes." );
  assert.notOk( view3.$el.hasClass( view3.className + '--otherBoolKey' ), "Falsy boolean data items are not added as classes." );
});

/**
 * Test ItemView events. ItemViews trigger several events, as well as react to
 * multiple DOM events.
 */
QUnit.test( "view events", function( assert ) {
  assert.expect( 11 );

  var doneCheckboxEvent = assert.async( 2 ),
      checked = false,
      item1 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ], id: 1, active: checked }),
      view1 = new ArchibaldCurriculum.ItemView({ model: item1, editable: true });
  view1.on( 'model:change', function( itemModel, itemView, e ) {
    // The active (checked) state should have changed.
    checked != checked;
    assert.ok( true, "The view triggers a model:change event on checking the checkbox." );
    assert.equal( itemModel.get( 'active'), checked, "The model active state correctly changed." );
    doneCheckboxEvent();
  });
  // (Un)check on the checkbox, twice.
  view1.render();
  view1.$el.find('input').change();
  view1.$el.find('input').change();

  var doneClickEvent = assert.async(),
      item2 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ], id: 2 }),
      view2 = new ArchibaldCurriculum.ItemView({ model: item2, editable: true });
  view2.on( 'select', function() {
    assert.ok( true, "The view triggers a select event on being clicked." );
    doneClickEvent();
  });
  // Click on the element.
  view2.render();
  view2.$el.click();
  // A click on the checkbox should not bubble up.
  view2.$el.find('input').click();

  var doneDblClickEvent = assert.async( 2 ),
      item3 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ], id: 3, active: false }),
      view3 = new ArchibaldCurriculum.ItemView({ model: item3, editable: true });
  view3.on( 'active', function( state, itemModel, itemView ) {
    assert.ok( true, "The view triggers a active event on being double-clicked." );
    assert.equal( state, true, "The passed state is correct." );
    assert.equal( itemModel.get( 'active'), true, "The model active state correctly changed." );
    doneDblClickEvent();
  });
  view3.on( 'unactive', function( state, itemModel, itemView ) {
    assert.ok( true, "The view triggers an unactive event on being double-clicked." );
    assert.equal( state, false, "The passed state is correct." );
    assert.equal( itemModel.get( 'active'), false, "The model active state correctly changed." );
    doneDblClickEvent();
  });
  view3.on( 'select', function( state, itemModel, itemView ) {
    assert.ok( false, "The view should not trigger a click event when double-clicked." );
  });
  // Double-click on the element, twice.
  view3.render();
  view3.$el.dblclick();
  view3.$el.dblclick();
});

QUnit.module( "ItemListView" );

/**
 * Test initialization logic. It should not be possible to initialize an
 * ItemListView without a collection.
 */
QUnit.test( "initialize", function( assert ) {
  assert.throws(
    function() {
      var view = new ArchibaldCurriculum.ItemListView();
    },
    "Initializing a view without any collection throws an error."
  );
});

/**
 * Test collection event binding. ItemListViews should react on several
 * collection events.
 */
QUnit.test( "collection events", function( assert ) {
  assert.expect( 6 );

  var doneAddRemoveEvent = assert.async( 2 ),
      doneRenderEvent = assert.async( 2 ),
      collection1 = new ArchibaldCurriculum.ItemCollection([ { name: [ "First item " ] }]),
      view1 = new ArchibaldCurriculum.ItemListView({ collection: collection1 }),
      addedItem = new ArchibaldCurriculum.ItemModel({ name: [ "Some name" ] });
  // Render it a first time BEFORE attaching event listeners. This will allow us
  // to cover the childViews[] array.
  view1.render();
  view1.on( 'collection:add', function( item, collection, view ) {
    assert.ok( true, "The view triggers a collection:add event on adding a model." );
    assert.equal( item, addedItem, "The view passes the added item to the event handler." );
    doneAddRemoveEvent();
  });
  view1.on( 'collection:remove', function( item, collection, view ) {
    assert.ok( true, "The view triggers a collection:remove event on removing a model." );
    assert.equal( item, addedItem, "The view passes the removed item to the event handler." );
    doneAddRemoveEvent();
  });
  view1.on( 'render', function() {
    assert.ok( true, "The view is re-rendered whenever an item is removed or added to the collection." );
    doneRenderEvent();
  });
  collection1.add( addedItem );
  collection1.remove( addedItem );
});

/**
 * Test child ItemView event binding. ItemListViews should react on several
 * child view events.
 */
QUnit.test( "child view events", function( assert ) {
  assert.expect();

  var doneSelectEvent = assert.async(),
      item1 = new ArchibaldCurriculum.ItemModel({ name: [ "Model name" ] }),
      collection1 = new ArchibaldCurriculum.ItemCollection([ item1 ]),
      view1 = new ArchibaldCurriculum.ItemListView({ collection: collection1 });
  view1.on( 'item:select', function() {
    assert.ok( true, "The view triggers a item:select event on clicking on a child view." );
    doneSelectEvent();
  });
  view1.render();
  item1.set( 'name', [ "Some new name" ] );
  view1.$el.find('li').click();
});

/**
 * Test ItemListView events. ItemListViews trigger several events, as well as
 * react to multiple DOM events.
 */
QUnit.test( "view events", function( assert ) {
  assert.expect( 6 );

  var doneCollapseExpandEvent = assert.async( 2 ),
      collection1 = new ArchibaldCurriculum.ItemCollection(),
      view1 = new ArchibaldCurriculum.ItemListView({ collection: collection1 });
  view1.on( 'column:collapse', function() {
    assert.ok( true, "The view triggers a column:collapse event on being collapsed." );
    assert.ok( view1.isCollapsed(), "The view gives correct information about being collapsed." );
    doneCollapseExpandEvent();
  });
  view1.on( 'column:expand', function() {
    assert.ok( true, "The view triggers a column:expand event on being collapsed." );
    assert.ok( view1.isExpanded(), "The view gives correct information about being expanded." );
    doneCollapseExpandEvent();
  });
  view1.collapse().expand();

  var doneGoBackEvent = assert.async(),
      doneGoToRootEvent = assert.async(),
      collection2 = new ArchibaldCurriculum.ItemCollection(),
      view2 = new ArchibaldCurriculum.ItemListView({ collection: collection2 });
  view2.on( 'column:go-back', function() {
    assert.ok( true, "The view triggers a column:go-back event on clicking on the Go Back button." );
    doneGoBackEvent();
  });
  view2.on( 'column:go-to-root', function() {
    assert.ok( true, "The view triggers a column:go-to-root event on clicking on the Go Back button." );
    doneGoToRootEvent();
  });
  view2.render();
  view2.$el.find('.archibald-column__button--show-parent').click();
  view2.$el.find('.archibald-column__button--show-root').click();
});

QUnit.module( "ItemInfoView" );

/**
 * Test initialization logic. It should not be possible to initialize an
 * ItemInfoView with an invalid model.
 */
QUnit.test( "initialize", function( assert ) {
  assert.throws(
    function() {
      var item = new ArchibaldCurriculum.ItemModel(),
          view = new ArchibaldCurriculum.ItemInfoView({ model: item });
    },
    "Initializing a view with an invalid model throws an error."
  );
});

/**
 * Test view events. ItemInfoViews trigger several events.
 */
QUnit.test( "view events", function( assert ) {
  assert.expect( 3 );

  var doneRenderEvent = assert.async(),
      doneCollapseExpandEvent = assert.async( 2 ),
      model1 = new ArchibaldCurriculum.ItemModel({ name: [ "Some name" ] }),
      view1 = new ArchibaldCurriculum.ItemInfoView({ model: model1 });

  view1.on( 'render', function() {
    assert.ok( true, "The view triggers a render event when rendered." );
    doneRenderEvent();
  });
  view1.render();

  view1.on( 'collapse', function() {
    assert.ok( true, "The view triggers a collapse event when collapsed." );
    doneCollapseExpandEvent();
  });
  view1.on( 'expand', function() {
    assert.ok( true, "The view triggers a expand event when expanded." );
    doneCollapseExpandEvent();
  });
  view1.$el.find( '.archibald-curriculum-ui-item-info__label' ).click().click();
});

QUnit.module( "SummaryTreeView" );

/**
 * Test initialization logic. It should not be possible to initialize a
 * SummaryTreeView without a collection.
 */
QUnit.test( "initialize", function( assert ) {
  assert.throws(
    function() {
      var view = new ArchibaldCurriculum.SummaryTreeView();
    },
    "Initializing a view without any model throws an error."
  );
});

/**
 * Test collection event binding. SummaryTreeViews should react on several
 * collection events.
 */
QUnit.test( "collection events", function( assert ) {
  assert.expect( 3 );

  var doneRenderEvent = assert.async( 3 ),
      collection = new ArchibaldCurriculum.ItemCollection(),
      view = new ArchibaldCurriculum.SummaryTreeView({ collection: collection }),
      addedItem1 = new ArchibaldCurriculum.ItemModel({ name: [ "Some name" ] }),
      addedItem2 = new ArchibaldCurriculum.ItemModel({ name: [ "Some name" ] });
  view.on( 'render', function() {
    assert.ok( true, "The view is re-rendered whenever an item is changed, removed or added to the collection." );
    doneRenderEvent();
  });
  collection.add( addedItem1 );
  // SummaryTreeViews have a protection mechanism against too many render calls.
  // In order for our second and third events to actually trigger a re-rendering
  // we must wait a little. However, if we trigger some in quick succession on
  // purpose, we should not have more render calls than we expect.
  collection.add( addedItem2 );
  addedItem2.set({ 'name': [ "Some new name" ] });
  setTimeout(function() {
    addedItem1.set({ 'name': [ "Some new name" ] });
    setTimeout(function() {
      collection.remove( addedItem1 );
    }, 100);
  }, 100);
});
<|endoftext|>