<commit_before>/**
 *  FullScreen widget:
 *
 *  var widget = new cdb.ui.common.FullScreen({
 *    doc: ".container", // optional; if not specified, we do the fullscreen of the whole window
 *    template: this.getTemplate("table/views/fullscreen")
 *  });
 *
 */

cdb.ui.common.FullScreen = cdb.core.View.extend({

  tagName: 'div',
  className: 'cartodb-fullscreen',

  events: {
    "click a": "_toggleFullScreen"
  },

  initialize: function() {
    _.bindAll(this, 'render');
    _.defaults(this.options, this.default_options);
    this._addWheelEvent();
  },

  _addWheelEvent: function() {
    var self    = this;
    var mapView = this.options.mapView;

    $(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() {
      if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) {
        if (self.model.get("allowWheelOnFullscreen")) {
          mapView.options.map.set("scrollwheel", false);
        }
      }
      mapView.invalidateSize();
    });
  },

  _toggleFullScreen: function(ev) {
    if (ev) {
      this.killEvent(ev);
    }

    var doc   = window.document;
    var docEl = doc.documentElement;

    if (this.options.doc) { // we use a custom element
      docEl = $(this.options.doc)[0];
    }

    var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
    var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;
    var mapView = this.options.mapView;

    if (!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) {
      if (docEl.webkitRequestFullScreen) {
        // Cartodb.js #361 :: Full screen button not working on Safari 8.0.3 #361
        // Safari has a bug that fullScreen doestn't work with Element.ALLOW_KEYBOARD_INPUT);
        // Reference: Ehttp://stackoverflow.com/questions/8427413/webkitrequestfullscreen-fails-when-passing-element-allow-keyboard-input-in-safar
        requestFullScreen.call(docEl, undefined);
      } else {
        // CartoDB.js #412 :: Fullscreen button is throwing errors
        // Nowadays (2015/03/25), fullscreen is not supported in iOS Safari. Reference: http://caniuse.com/#feat=fullscreen
        if (requestFullScreen) {
          requestFullScreen.call(docEl);
        }
      }

      if (mapView) {
        if (this.model.get("allowWheelOnFullscreen")) {
          mapView.options.map.set("scrollwheel", true);
        }
      }
    } else {
      cancelFullScreen.call(doc);
    }
  },

  render: function() {
    var $el = this.$el;
    var options = _.extend(
      this.options,
      {
        mapUrl: location.href || ''
      }
    );
    $el.html(this.options.template(options));

    if (!this._canFullScreenBeEnabled()) {
      this.undelegateEvents();
      cdb.log.info('FullScreen API is deprecated on insecure origins. See https://goo.gl/rStTGz for more details.');
    }

    return this;
  },

  _canFullScreenBeEnabled: function() {
    if (this._isInIframe()) {
      var parentUrl = document.referrer;
      if (parentUrl.search('https:') !== 0) {
        return false;
      }
    }
    return true;
  },

  _isInIframe: function() {
    try {
      return window.self !== window.top;
    } catch (e) {
      return true;
    }
  }

});
<commit_msg>Removed unnecessary  element<commit_after>/**
 *  FullScreen widget:
 *
 *  var widget = new cdb.ui.common.FullScreen({
 *    doc: ".container", // optional; if not specified, we do the fullscreen of the whole window
 *    template: this.getTemplate("table/views/fullscreen")
 *  });
 *
 */

cdb.ui.common.FullScreen = cdb.core.View.extend({

  tagName: 'div',
  className: 'cartodb-fullscreen',

  events: {
    "click a": "_toggleFullScreen"
  },

  initialize: function() {
    _.bindAll(this, 'render');
    _.defaults(this.options, this.default_options);
    this._addWheelEvent();
  },

  _addWheelEvent: function() {
    var self    = this;
    var mapView = this.options.mapView;

    $(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() {
      if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) {
        if (self.model.get("allowWheelOnFullscreen")) {
          mapView.options.map.set("scrollwheel", false);
        }
      }
      mapView.invalidateSize();
    });
  },

  _toggleFullScreen: function(ev) {
    if (ev) {
      this.killEvent(ev);
    }

    var doc   = window.document;
    var docEl = doc.documentElement;

    if (this.options.doc) { // we use a custom element
      docEl = $(this.options.doc)[0];
    }

    var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
    var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;
    var mapView = this.options.mapView;

    if (!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) {
      if (docEl.webkitRequestFullScreen) {
        // Cartodb.js #361 :: Full screen button not working on Safari 8.0.3 #361
        // Safari has a bug that fullScreen doestn't work with Element.ALLOW_KEYBOARD_INPUT);
        // Reference: Ehttp://stackoverflow.com/questions/8427413/webkitrequestfullscreen-fails-when-passing-element-allow-keyboard-input-in-safar
        requestFullScreen.call(docEl, undefined);
      } else {
        // CartoDB.js #412 :: Fullscreen button is throwing errors
        // Nowadays (2015/03/25), fullscreen is not supported in iOS Safari. Reference: http://caniuse.com/#feat=fullscreen
        if (requestFullScreen) {
          requestFullScreen.call(docEl);
        }
      }

      if (mapView) {
        if (this.model.get("allowWheelOnFullscreen")) {
          mapView.options.map.set("scrollwheel", true);
        }
      }
    } else {
      cancelFullScreen.call(doc);
    }
  },

  render: function() {
    var options = _.extend(
      this.options,
      {
        mapUrl: location.href || ''
      }
    );
    this.$el.html(this.options.template(options));

    if (!this._canFullScreenBeEnabled()) {
      this.undelegateEvents();
      cdb.log.info('FullScreen API is deprecated on insecure origins. See https://goo.gl/rStTGz for more details.');
    }

    return this;
  },

  _canFullScreenBeEnabled: function() {
    if (this._isInIframe()) {
      var parentUrl = document.referrer;
      if (parentUrl.search('https:') !== 0) {
        return false;
      }
    }
    return true;
  },

  _isInIframe: function() {
    try {
      return window.self !== window.top;
    } catch (e) {
      return true;
    }
  }

});
<|endoftext|>


<commit_before>module.exports = {

  friendlyName: 'Download song by name and artist',

  description: 'Download a song, and save it into a folder, by name and artist',

  extendedDescription: '',

  inputs: {

    name: {
      example: 'Bohemian Rhapsody',
      description: 'Song name, not case sensitive',
      required: true
    },

    artist: {
      example: 'Queen',
      description: 'Artist name, not case sensitive',
      required: true
    },

    path: {
      example: '/userId/coolFolder',
      description: 'ABSOLUTE Path to the folder where the song will be saved, if the folder doesn\'t exist it will be created',
      required: true
    }

  },

  defaultExit: 'success',

  exits: {

    error: {
      description: 'Unexpected error occurred.',
    },

    notFound: {
      description: 'Song not found, try with another name/artist'
    },

    downloadLimitExceded: {
      description: 'It looks like we are banned by Grooveshark, please try again in a few hours'
    },

    success: {
      description: 'Downloaded.',
    }

  },

  fn: function (inputs, exits) {

    var GS = require('grooveshark-downloader');
    var async = require('async');
    var fs = require('fs');
    var request = require('request');

    GS.Tinysong.getSongInfo(inputs.name, inputs.artist, function(err, info) {
      if(err) return exits.error(err);

      if(!info) return exits.notFound();

      GS.Grooveshark.getStreamingUrl(info.SongID, function(err, streamUrl) {
        if(err) return exits.error(err);

        if(!fs.existsSync(inputs.path)){
          var mkdirp = require('mkdirp');
          mkdirp.sync(inputs.path);
        }

        var songPath = inputs.path + '/' + info.SongName + '.mp3';

        request
          .get(streamUrl)
           .on('error', function(err){
             return exits.error(err);
           })
           .on('end', function(){
             return exits.success();
           })
           .pipe(fs.createWriteStream(songPath));
      });
    });

  },

};
<commit_msg>if banned trigger banned error<commit_after>module.exports = {

  friendlyName: 'Download song by name and artist',

  description: 'Download a song, and save it into a folder, by name and artist',

  extendedDescription: '',

  inputs: {

    name: {
      example: 'Bohemian Rhapsody',
      description: 'Song name, not case sensitive',
      required: true
    },

    artist: {
      example: 'Queen',
      description: 'Artist name, not case sensitive',
      required: true
    },

    path: {
      example: '/userId/coolFolder',
      description: 'ABSOLUTE Path to the folder where the song will be saved, if the folder doesn\'t exist it will be created',
      required: true
    }

  },

  defaultExit: 'success',

  exits: {

    error: {
      description: 'Unexpected error occurred.',
    },

    notFound: {
      description: 'Song not found, try with another name/artist'
    },

    downloadLimitExceded: {
      description: 'It looks like we are banned by Grooveshark, please try again in a few hours'
    },

    success: {
      description: 'Downloaded.',
    }

  },

  fn: function (inputs, exits) {

    var GS = require('grooveshark-downloader');
    var async = require('async');
    var fs = require('fs');
    var request = require('request');

    GS.Tinysong.getSongInfo(inputs.name, inputs.artist, function(err, info) {
      if(err) return exits.error(err);

      if(!info) return exits.notFound();

      GS.Grooveshark.getStreamingUrl(info.SongID, function(err, streamUrl) {
        if(err){
          if(err === 'banned') return exits.downloadLimitExceded();
          return exits.error(err);
        }

        if(!fs.existsSync(inputs.path)){
          var mkdirp = require('mkdirp');
          mkdirp.sync(inputs.path);
        }

        var songPath = inputs.path + '/' + info.SongName + '.mp3';

        request
          .get(streamUrl)
           .on('error', function(err){
             return exits.error(err);
           })
           .on('end', function(){
             return exits.success();
           })
           .pipe(fs.createWriteStream(songPath));
      });
    });

  },

};
<|endoftext|>


<commit_before>const pool = require('./api/db');
const SQL = require('sql-template-strings')

//     //to run a query we just pass it to the pool
//     //after we're done nothing has to be taken care of
//     //we don't have to return any client to the pool or close a connection

const rollback = (client, done) => {
    client.query('ROLLBACK', (err) => {
        return done(err);
    });
}

const get_num_couples_per_event_for_competition = cid => {
    return pool.query(SQL`SELECT COUNT(p.number), e.id
        FROM partnership p
        LEFT JOIN event e ON (e.id = p.eventid)
        WHERE p.competitionid = ${cid}
        GROUP BY e.id`);
}

const create_rounds_for_events_for_competition = cid => {
    return new Promise(function(resolve, reject) {
       get_num_couples_per_event_for_competition(cid).then(value => {
          pool.connect(function(err, client, done) {
              if (err) {
                  console.error('error getting client', err);
                  reject(err);
              } else {
                  client.query('BEGIN', (err) => {
                      if (err) {
                          rollback(client, done);
                          return reject(err);
                      }
                      let ordernumber = 1;
                      for (let row of value) {
                          let couples = parseInt(row.count);
                          let eventid = row.id;
                          let numRounds = Math.ceil(couples / 7.0);
                          for (let i = 1; i <= numRounds; i++) {
                              let size = Math.min(couples, (numRounds - i + 1) * 7);
                              if (i == numRounds) {
                                  client.query(SQL`INSERT INTO round (eventid, name, ordernumber, size) VALUES (${eventid}, 'Final', ${ordernumber}, ${size})`, (err, result) => {
                                      if (err) {
                                          rollback(client, done);
                                          return reject(err);
                                      }
                                  });
                              } else if (i == numRounds - 1) {
                                  client.query(SQL`INSERT INTO round (eventid, name, ordernumber, size) VALUES (${eventid}, 'Semifinal', ${ordernumber}, ${size})`, (err, result) => {
                                      if (err) {
                                          rollback(client, done);
                                          return reject(err);
                                      }
                                  });
                              } else if (i == numRounds - 2) {
                                  client.query(SQL`INSERT INTO round (eventid, name, ordernumber, size) VALUES (${eventid}, 'Quarter', ${ordernumber}, ${size})`, (err, result) => {
                                      if (err) {
                                          rollback(client, done);
                                          return reject(err);
                                      }
                                  });
                              } else {
                                  const name = 'Round ' + i;
                                  client.query(SQL`INSERT INTO round (eventid, name, ordernumber, size) VALUES (${eventid}, ${name}, ${ordernumber}, ${size})`, (err, result) => {
                                      if (err) {
                                          rollback(client, done);
                                          return reject(err);
                                      }
                                  });
                              }
                              ordernumber++;
                          }
                      }
                      client.query('COMMIT', (err) => {
                          if (err) {
                              rollback(client, done);
                              return reject(err);
                          }
                          done(null);
                          resolve("{finished: true}");
                      });
                  });
              }
          })
       });
    });
}

const update_events_for_competition = data => {
    return new Promise(function(resolve, reject) {
        pool.connect(function(err, client, done) {
           if (err) {
               console.error('error getting client', err);
               reject(err);
           } else {
               client.query('BEGIN', (err) => {
                   if (err) {
                       rollback(client, done);
                       return reject(err);
                   }
                   client.query(SQL`CREATE TEMPORARY TABLE newevents (
                        id integer,
                        styleid integer,
                        stylename character varying(30),
                        levelid integer,
                        levelname character varying(30),
                        dance character varying(30),
                        ordernumber integer
                        ) ON COMMIT DROP`, (err, result) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   for (let row of data.rows) {
                       client.query(SQL`INSERT INTO newevents (id, stylename, levelname, dance, ordernumber) VALUES (${row.id}, ${row.style}, ${row.level}, ${row.dance}, ${row.ordernumber})`, (err, result) => {
                           if (err) {
                               rollback(client, done);
                               return reject(err);
                           }
                       });
                   }
                   client.query(SQL`UPDATE newevents SET styleid = s.id FROM style s WHERE newevents.stylename = s.name AND s.competitionid = ${data.cid}`, (err, result) => {
                       if (err) {
                           console.log(err);
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   client.query(SQL`UPDATE newevents SET levelid = l.id FROM level l WHERE newevents.levelname = l.name AND l.competitionid = ${data.cid}`, (err, result) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   client.query(SQL`DELETE FROM event WHERE id NOT IN
                    (SELECT id FROM newevents)`, (err, result) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   client.query(SQL`UPDATE event e SET ordernumber = n.ordernumber FROM newevents n
                    WHERE e.id = n.id`, (err, result) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   client.query(SQL`INSERT INTO event (competitionid, styleid, levelid, dance, ordernumber)
                    SELECT ${data.cid} AS competitionid, styleid, levelid, dance, ordernumber
                    FROM newevents
                    WHERE id = NULL`, (err, result) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   client.query('COMMIT', (err) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                       done(null);
                       resolve("{finished: true}");
                   });
               });
           }
        });
    });
}

const update_competition_info = data => {
    return pool.query(SQL`UPDATE competition SET name = ${data.name}, leadidstartnum = ${data.leadidstartnum},
        locationname = ${data.locationname}, earlyprice = ${data.earlyprice}, regularprice = ${data.regularprice},
        lateprice = ${data.lateprice}, startdate = ${data.startdate}, enddate = ${data.enddate},
        regstartdate = ${data.regstartdate}, earlyregdeadline = ${data.earlyregdeadline},
        regularregdeadline = ${data.regularregdeadline}, lateregdeadline = ${data.lateregdeadline},
        description = ${data.description} WHERE id = ${data.cid}`);
}

const update_competition_current_event_id = data => {
    return pool.query(SQL`UPDATE competition SET currenteventid = ${data.currenteventid} WHERE id = ${data.cid}`);
}

const get_all_admins = () => {
    return pool.query('SELECT * FROM admin', []);
}

const get_judges_for_competition = (comp_id) => {
    return pool.query(SQL`SELECT * FROM judge WHERE competitionid = ${comp_id}`);
}

const get_judge = id => {
    return pool.query(SQL`SELECT * FROM judge WHERE id = ${id}`);
}

const get_affiliations = () => {
    return pool.query('SELECT * FROM affiliation', []);
}

const get_levels_for_competition = cid => {
    return pool.query(SQL`SELECT id, name, ordernumber FROM level WHERE competitionid = ${cid}`);
}

const get_styles_for_competition = cid => {
    return pool.query(SQL`SELECT id, name, ordernumber FROM style WHERE competitionid = ${cid}`);
}

const get_competition_info = cid => {
    return pool.query(SQL`SELECT * FROM competition WHERE id = ${cid}`);
}

const get_events_for_competition = cid => {
    return pool.query(SQL`SELECT style.name, level.name, dance, event.ordernumber FROM event
        LEFT JOIN style ON (style.id = event.styleid)
        LEFT JOIN level ON (level.id = event.levelid)
        WHERE event.competitionid = ${cid} ORDER BY ordernumber`);
}

const get_rounds_for_competition = cid => {
    return pool.query(SQL`SELECT r.id, e.levelid, e.styleid, e.dance, r.name, r.ordernumber, r.size, r.nextround,
        r.judgeid1, r.judgeid2, r.judgeid3, r.judgeid4, r.judgeid5, r.judgeid6 FROM event e
        LEFT JOIN round r ON (e.id = r.eventid) WHERE e.competitionid = ${cid} ORDER BY r.ordernumber`);
}

const get_competitors_for_competition = cid => {
    return pool.query(SQL`SELECT DISTINCT ON (id) c.id, firstname || ' ' || lastname as name, email,
        CASE WHEN c.id = p.leadcompetitorid THEN p.number ELSE NULL END as number, a.name as affiliationname,
        pr.paidwithaffiliation, pr.amount FROM competitor c
        LEFT JOIN partnership p ON (c.id = p.leadcompetitorid OR c.id = p.followcompetitorid)
        LEFT JOIN paymentrecord pr ON (c.id = pr.competitorid)
        LEFT JOIN  affiliation a ON (c.affiliationid = a.id)
        WHERE p.competitionid = ${cid}`);
}

const get_affiliations_for_competition = cid => {
    return pool.query(SQL`SELECT DISTINCT ON (affiliationname) a.name as affiliationname
        FROM competitor c
        LEFT JOIN partnership p ON (c.id = p.leadcompetitorid OR c.id = p.followcompetitorid)
        LEFT JOIN  affiliation a ON (c.affiliationid = a.id)
        WHERE p.competitionid = ${cid}`);
}

const get_num_competitors_per_style_for_competition = cid => {
    return pool.query(SQL`SELECT COUNT(c.id), s.name
        FROM competitor c
        LEFT JOIN partnership p ON (c.id = p.leadcompetitorid OR c.id = p.followcompetitorid)
        LEFT JOIN event e ON (e.id = p.eventid)
        LEFT JOIN style s ON (e.styleid = s.id)
        WHERE p.competitionid = ${cid}
        GROUP BY s.name`)
}

const add_new_judge = (judge) => {
    return pool.query(SQL`INSERT INTO judge (email, token, firstname, lastname, phonenumber, competitionid)
        VALUES (${judge.email}, ${judge.token}, ${judge.firstName}, ${judge.lastName}, ${judge.phoneNumber}, ${judge.competitionId})`);
}

// INSERT

// DELETE

module.exports = {
    get_all_admins,
    get_judges_for_competition,
    get_judge,
    get_affiliations,
    get_levels_for_competition,
    get_styles_for_competition,
    get_competition_info,
    get_events_for_competition,
    get_rounds_for_competition,
    get_competitors_for_competition,
    get_affiliations_for_competition,
    get_num_competitors_per_style_for_competition,
    add_new_judge,
    create_rounds_for_events_for_competition,
    update_events_for_competition,
    update_competition_info,
    update_competition_current_event_id
}
<commit_msg>insert next round id when generating rounds<commit_after>const pool = require('./api/db');
const SQL = require('sql-template-strings')

//     //to run a query we just pass it to the pool
//     //after we're done nothing has to be taken care of
//     //we don't have to return any client to the pool or close a connection

const rollback = (client, done) => {
    client.query('ROLLBACK', (err) => {
        return done(err);
    });
}

const get_num_couples_per_event_for_competition = cid => {
    return pool.query(SQL`SELECT COUNT(p.number), e.id
        FROM partnership p
        LEFT JOIN event e ON (e.id = p.eventid)
        WHERE p.competitionid = ${cid}
        GROUP BY e.id`);
}

const create_rounds_for_events_for_competition = cid => {
    return new Promise(function(resolve, reject) {
       get_num_couples_per_event_for_competition(cid).then(value => {
          pool.connect(function(err, client, done) {
              if (err) {
                  console.error('error getting client', err);
                  reject(err);
              } else {
                  client.query('BEGIN', (err) => {
                      if (err) {
                          rollback(client, done);
                          return reject(err);
                      }
                      let ordernumber = 1;
                      for (let row of value) {
                          let couples = parseInt(row.count);
                          let eventid = row.id;
                          let numRounds = Math.ceil(couples / 7.0);
                          let nextRound = null;
                          for (let i = numRounds; i >= 1; i++) {
                              let size = Math.min(couples, (numRounds - i + 1) * 7);
                              if (i == numRounds) {
                                  client.query(SQL`INSERT INTO round (eventid, name, ordernumber, size) VALUES (${eventid}, 'Final', ${ordernumber}, ${size}) RETURNING id`, (err, result) => {
                                      if (err) {
                                          rollback(client, done);
                                          return reject(err);
                                      }
                                      nextRound = result.rows[0].id;
                                  });
                              } else if (i == numRounds - 1) {
                                  client.query(SQL`INSERT INTO round (eventid, name, ordernumber, size, nextround) VALUES (${eventid}, 'Semifinal', ${ordernumber}, ${size}, ${nextround}) RETURNING id`, (err, result) => {
                                      if (err) {
                                          rollback(client, done);
                                          return reject(err);
                                      }
                                      nextRound = result.rows[0].id;
                                  });
                              } else if (i == numRounds - 2) {
                                  client.query(SQL`INSERT INTO round (eventid, name, ordernumber, size) VALUES (${eventid}, 'Quarter', ${ordernumber}, ${size}, ${nextround}) RETURNING id`, (err, result) => {
                                      if (err) {
                                          rollback(client, done);
                                          return reject(err);
                                      }
                                      nextRound = result.rows[0].id;
                                  });
                              } else {
                                  const name = 'Round ' + i;
                                  client.query(SQL`INSERT INTO round (eventid, name, ordernumber, size) VALUES (${eventid}, ${name}, ${ordernumber}, ${size}, ${nextround}) RETURNING id`, (err, result) => {
                                      if (err) {
                                          rollback(client, done);
                                          return reject(err);
                                      }
                                      nextRound = result.rows[0].id;
                                  });
                              }
                              ordernumber++;
                          }
                      }
                      client.query('COMMIT', (err) => {
                          if (err) {
                              rollback(client, done);
                              return reject(err);
                          }
                          done(null);
                          resolve("{finished: true}");
                      });
                  });
              }
          })
       });
    });
}

const update_events_for_competition = data => {
    return new Promise(function(resolve, reject) {
        pool.connect(function(err, client, done) {
           if (err) {
               console.error('error getting client', err);
               reject(err);
           } else {
               client.query('BEGIN', (err) => {
                   if (err) {
                       rollback(client, done);
                       return reject(err);
                   }
                   client.query(SQL`CREATE TEMPORARY TABLE newevents (
                        id integer,
                        styleid integer,
                        stylename character varying(30),
                        levelid integer,
                        levelname character varying(30),
                        dance character varying(30),
                        ordernumber integer
                        ) ON COMMIT DROP`, (err, result) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   for (let row of data.rows) {
                       client.query(SQL`INSERT INTO newevents (id, stylename, levelname, dance, ordernumber) VALUES (${row.id}, ${row.style}, ${row.level}, ${row.dance}, ${row.ordernumber})`, (err, result) => {
                           if (err) {
                               rollback(client, done);
                               return reject(err);
                           }
                       });
                   }
                   client.query(SQL`UPDATE newevents SET styleid = s.id FROM style s WHERE newevents.stylename = s.name AND s.competitionid = ${data.cid}`, (err, result) => {
                       if (err) {
                           console.log(err);
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   client.query(SQL`UPDATE newevents SET levelid = l.id FROM level l WHERE newevents.levelname = l.name AND l.competitionid = ${data.cid}`, (err, result) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   client.query(SQL`DELETE FROM event WHERE id NOT IN
                    (SELECT id FROM newevents)`, (err, result) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   client.query(SQL`UPDATE event e SET ordernumber = n.ordernumber FROM newevents n
                    WHERE e.id = n.id`, (err, result) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   client.query(SQL`INSERT INTO event (competitionid, styleid, levelid, dance, ordernumber)
                    SELECT ${data.cid} AS competitionid, styleid, levelid, dance, ordernumber
                    FROM newevents
                    WHERE id = NULL`, (err, result) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                   });
                   client.query('COMMIT', (err) => {
                       if (err) {
                           rollback(client, done);
                           return reject(err);
                       }
                       done(null);
                       resolve("{finished: true}");
                   });
               });
           }
        });
    });
}

const update_competition_info = data => {
    return pool.query(SQL`UPDATE competition SET name = ${data.name}, leadidstartnum = ${data.leadidstartnum},
        locationname = ${data.locationname}, earlyprice = ${data.earlyprice}, regularprice = ${data.regularprice},
        lateprice = ${data.lateprice}, startdate = ${data.startdate}, enddate = ${data.enddate},
        regstartdate = ${data.regstartdate}, earlyregdeadline = ${data.earlyregdeadline},
        regularregdeadline = ${data.regularregdeadline}, lateregdeadline = ${data.lateregdeadline},
        description = ${data.description} WHERE id = ${data.cid}`);
}

const update_competition_current_event_id = data => {
    return pool.query(SQL`UPDATE competition SET currenteventid = ${data.currenteventid} WHERE id = ${data.cid}`);
}

const get_all_admins = () => {
    return pool.query('SELECT * FROM admin', []);
}

const get_judges_for_competition = (comp_id) => {
    return pool.query(SQL`SELECT * FROM judge WHERE competitionid = ${comp_id}`);
}

const get_judge = id => {
    return pool.query(SQL`SELECT * FROM judge WHERE id = ${id}`);
}

const get_affiliations = () => {
    return pool.query('SELECT * FROM affiliation', []);
}

const get_levels_for_competition = cid => {
    return pool.query(SQL`SELECT id, name, ordernumber FROM level WHERE competitionid = ${cid}`);
}

const get_styles_for_competition = cid => {
    return pool.query(SQL`SELECT id, name, ordernumber FROM style WHERE competitionid = ${cid}`);
}

const get_competition_info = cid => {
    return pool.query(SQL`SELECT * FROM competition WHERE id = ${cid}`);
}

const get_events_for_competition = cid => {
    return pool.query(SQL`SELECT style.name, level.name, dance, event.ordernumber FROM event
        LEFT JOIN style ON (style.id = event.styleid)
        LEFT JOIN level ON (level.id = event.levelid)
        WHERE event.competitionid = ${cid} ORDER BY ordernumber`);
}

const get_rounds_for_competition = cid => {
    return pool.query(SQL`SELECT r.id, e.levelid, e.styleid, e.dance, r.name, r.ordernumber, r.size, r.nextround,
        r.judgeid1, r.judgeid2, r.judgeid3, r.judgeid4, r.judgeid5, r.judgeid6 FROM event e
        LEFT JOIN round r ON (e.id = r.eventid) WHERE e.competitionid = ${cid} ORDER BY r.ordernumber`);
}

const get_competitors_for_competition = cid => {
    return pool.query(SQL`SELECT DISTINCT ON (id) c.id, firstname || ' ' || lastname as name, email,
        CASE WHEN c.id = p.leadcompetitorid THEN p.number ELSE NULL END as number, a.name as affiliationname,
        pr.paidwithaffiliation, pr.amount FROM competitor c
        LEFT JOIN partnership p ON (c.id = p.leadcompetitorid OR c.id = p.followcompetitorid)
        LEFT JOIN paymentrecord pr ON (c.id = pr.competitorid)
        LEFT JOIN  affiliation a ON (c.affiliationid = a.id)
        WHERE p.competitionid = ${cid}`);
}

const get_affiliations_for_competition = cid => {
    return pool.query(SQL`SELECT DISTINCT ON (affiliationname) a.name as affiliationname
        FROM competitor c
        LEFT JOIN partnership p ON (c.id = p.leadcompetitorid OR c.id = p.followcompetitorid)
        LEFT JOIN  affiliation a ON (c.affiliationid = a.id)
        WHERE p.competitionid = ${cid}`);
}

const get_num_competitors_per_style_for_competition = cid => {
    return pool.query(SQL`SELECT COUNT(c.id), s.name
        FROM competitor c
        LEFT JOIN partnership p ON (c.id = p.leadcompetitorid OR c.id = p.followcompetitorid)
        LEFT JOIN event e ON (e.id = p.eventid)
        LEFT JOIN style s ON (e.styleid = s.id)
        WHERE p.competitionid = ${cid}
        GROUP BY s.name`)
}

const add_new_judge = (judge) => {
    return pool.query(SQL`INSERT INTO judge (email, token, firstname, lastname, phonenumber, competitionid)
        VALUES (${judge.email}, ${judge.token}, ${judge.firstName}, ${judge.lastName}, ${judge.phoneNumber}, ${judge.competitionId})`);
}

// INSERT

// DELETE

module.exports = {
    get_all_admins,
    get_judges_for_competition,
    get_judge,
    get_affiliations,
    get_levels_for_competition,
    get_styles_for_competition,
    get_competition_info,
    get_events_for_competition,
    get_rounds_for_competition,
    get_competitors_for_competition,
    get_affiliations_for_competition,
    get_num_competitors_per_style_for_competition,
    add_new_judge,
    create_rounds_for_events_for_competition,
    update_events_for_competition,
    update_competition_info,
    update_competition_current_event_id
}
<|endoftext|>


<commit_before>/*
 * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
 * Copyright [2016-2017] EMBL-European Bioinformatics Institute
 *
 * 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.
 */

Ensembl.Share = {
  shareInit: function (options) {
    var panel = this;

    this.protocol = window.location.href.split('//');
    this.shareOptions = $.extend({
      species: {},
      type: 'page',
      positionPopup: function (popup, link) {
        return popup.css({ top: $(link).offset().top + 1, left: this.el.outerWidth(true) });
      }
    }, options);

    this.elLk.shareLink = $('a.share', this.el).on('click', function () {
      if (!panel.elLk.share) {
        panel.elLk.share        = $('

').appendTo('body').css('left', panel.el.offset().left).data('loading', true);
        panel.elLk.shareSpinner = $('

').appendTo(panel.elLk.share);

        panel.share(this.href, this);

        panel.elLk.share.on('click', '.close, .cancel', function () {
          panel.elLk.share.hide();
        }).on('click', '.url', function () {
          $(this).select();
        });

        panel.elLk.shareLink.data('popup', panel.elLk.share);
      } else if (!panel.elLk.share.data('loading')) {
        panel.shareOptions.positionPopup.call(panel, panel.elLk.share, this).toggle();
      }

      return false;
    });
  },

  share: function (url, link) {
    var panel = this;

    if (!this.elLk.share) {
      return;
    }
    this.shareOptions.positionPopup.call(this, this.elLk.share, link);

    this.shareTimeout = setTimeout(function () {
      panel.elLk.share.add(panel.elLk.shareSpinner).show();
    }, 200);

    if (this.shareEnabled === false) {
      this.shareWaiting = true;
      return;
    }

    $.ajax({
      url: url,
      dataType: 'json',
      data: { species: JSON.stringify(this.shareOptions.species), hash: window.location.hash.replace('#', '') },
      success: function (json) {
        clearTimeout(panel.shareTimeout);

        panel.elLk.shareSpinner.hide();

        if (json.url) {
          if (json.url.match('^//')) {
            json.url = panel.protocol[0] +  json.url;
          }

          if (!$('.url', panel.elLk.share).val(json.url).add('.copy', panel.elLk.share).show().length) {
            panel.elLk.share.find('.fbutton').addClass('bottom-margin');
            panel.elLk.shareSpinner.before('
Copy this link:
<input class="url" type="text" value="' + json.url + '" />');
          }
        } else if (json.confirmShare) {
          panel.elLk.shareSpinner.before(
            '
This ' + panel.shareOptions.type + ' is displaying some custom tracks.
Select which of these you\'d like to share:

' +
            $.map(json.confirmShare, function (f) { return '
' + f[0] + '<input class="file" type="checkbox" value="' + f[1] + '" />
'; }).join('') +
            '
<input type="button" class="go fbutton" value="Accept" /><input type="button" class="cancel fbutton" value="Cancel" />'
          );

          $('.go', panel.elLk.share).on('click', function () {
            $('.url', panel.elLk.share).add('.copy', panel.elLk.share).hide();
            panel.elLk.shareSpinner.show();
            panel.share(url + ';custom_data=' + ($('.file', panel.elLk.share).map(function () { return this.checked ? this.value : undefined; }).toArray().join(',') || 'none'), link);
          });
        }

        panel.elLk.share.show().removeData('loading');
      },
      error: function () {
        panel.elLk.share.remove();
        delete panel.elLk.share;
      }
    });
  },

  removeShare: function () {
    if (this.elLk.share) {
      this.elLk.share.remove();
      delete this.elLk.share;
    }
  }
};<commit_msg>Merging postreleasefix/90 to master<commit_after>/*
 * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
 * Copyright [2016-2017] EMBL-European Bioinformatics Institute
 *
 * 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.
 */

Ensembl.Share = {
  shareInit: function (options) {
    var panel = this;

    this.shareOptions = $.extend({
      species: {},
      type: 'page',
      positionPopup: function (popup, link) {
        return popup.css({ top: $(link).offset().top + 1, left: this.el.outerWidth(true) });
      }
    }, options);

    this.elLk.shareLink = $('a.share', this.el).on('click', function () {
      if (!panel.elLk.share) {
        panel.elLk.share        = $('

').appendTo('body').css('left', panel.el.offset().left).data('loading', true);
        panel.elLk.shareSpinner = $('

').appendTo(panel.elLk.share);

        panel.share(this.href, this);

        panel.elLk.share.on('click', '.close, .cancel', function () {
          panel.elLk.share.hide();
        }).on('click', '.url', function () {
          $(this).select();
        });

        panel.elLk.shareLink.data('popup', panel.elLk.share);
      } else if (!panel.elLk.share.data('loading')) {
        panel.shareOptions.positionPopup.call(panel, panel.elLk.share, this).toggle();
      }

      return false;
    });
  },

  share: function (url, link) {
    var panel = this;

    if (!this.elLk.share) {
      return;
    }
    this.shareOptions.positionPopup.call(this, this.elLk.share, link);

    this.shareTimeout = setTimeout(function () {
      panel.elLk.share.add(panel.elLk.shareSpinner).show();
    }, 200);

    if (this.shareEnabled === false) {
      this.shareWaiting = true;
      return;
    }

    $.ajax({
      url: url,
      dataType: 'json',
      data: { species: JSON.stringify(this.shareOptions.species), hash: window.location.hash.replace('#', '') },
      success: function (json) {
        clearTimeout(panel.shareTimeout);

        panel.elLk.shareSpinner.hide();

        if (json.url) {
          json.url = $('').attr('href', json.url).prop('href'); // in case protocol or domain is missing

          if (!$('.url', panel.elLk.share).val(json.url).add('.copy', panel.elLk.share).show().length) {
            panel.elLk.share.find('.fbutton').addClass('bottom-margin');
            panel.elLk.shareSpinner.before('
Copy this link:
<input class="url" type="text" value="' + json.url + '" />');
          }
        } else if (json.confirmShare) {
          panel.elLk.shareSpinner.before(
            '
This ' + panel.shareOptions.type + ' is displaying some custom tracks.
Select which of these you\'d like to share:

' +
            $.map(json.confirmShare, function (f) { return '
' + f[0] + '<input class="file" type="checkbox" value="' + f[1] + '" />
'; }).join('') +
            '
<input type="button" class="go fbutton" value="Accept" /><input type="button" class="cancel fbutton" value="Cancel" />'
          );

          $('.go', panel.elLk.share).on('click', function () {
            $('.url', panel.elLk.share).add('.copy', panel.elLk.share).hide();
            panel.elLk.shareSpinner.show();
            panel.share(url + ';custom_data=' + ($('.file', panel.elLk.share).map(function () { return this.checked ? this.value : undefined; }).toArray().join(',') || 'none'), link);
          });
        }

        panel.elLk.share.show().removeData('loading');
      },
      error: function () {
        panel.elLk.share.remove();
        delete panel.elLk.share;
      }
    });
  },

  removeShare: function () {
    if (this.elLk.share) {
      this.elLk.share.remove();
      delete this.elLk.share;
    }
  }
};
<|endoftext|>


<commit_before>// Copyright (c) 2011-2012 UX Productivity Pty Ltd. All rights reserved.

(function() {

    var viewportMetaElement = null;

    function getOrCreateHead()
    {
        var html = document.documentElement;
        for (var child = html.firstChild; child != null; child = child.nextSibling) {
            if (child.nodeName == "HEAD")
                return child;
        }
        var head = DOM.createElement(document,"HEAD");
        DOM.insertBefore(html,head,html.firstChild);
        return head;
    }

    // public
    function setViewportWidth(width)
    {
        if (viewportMetaElement == null) {
            var head = getOrCreateHead();
            for (var child = head.firstChild; child != null; child = child.nextSibling) {
                if ((child.nodeName == "META") && (child.getAttribute("name") == "viewport")) {
                    viewportMetaElement = child;
                    break;
                }
            }
            if (viewportMetaElement == null) {
                viewportMetaElement = DOM.createElement(document,"META");
                viewportMetaElement.setAttribute("name","viewport");
                DOM.appendChild(head,viewportMetaElement);
            }
        }
        viewportMetaElement.setAttribute("content","width = "+width);
        Selection.updateSelectionDisplay();
        Cursor.ensureCursorVisible();
    }

    // public
    function getZoom()
    {
        return window.outerWidth/window.innerWidth;
    }

    window.Viewport = new Object();
    Viewport.setViewportWidth = setViewportWidth;
    Viewport.getZoom = getZoom;

})();
<commit_msg>Changed setViewportWidth() to setViewportSize(), to also allow the height to be specified. We only update the viewport meta element if the width changes.<commit_after>// Copyright (c) 2011-2012 UX Productivity Pty Ltd. All rights reserved.

(function() {

    var viewportMetaElement = null;
    var viewportWidth = null;
    var viewportHeight = null;

    function getOrCreateHead()
    {
        var html = document.documentElement;
        for (var child = html.firstChild; child != null; child = child.nextSibling) {
            if (child.nodeName == "HEAD")
                return child;
        }
        var head = DOM.createElement(document,"HEAD");
        DOM.insertBefore(html,head,html.firstChild);
        return head;
    }

    // public
    function setViewportSize(width,height)
    {
        if (viewportWidth != width) {
            if (viewportMetaElement == null) {
                var head = getOrCreateHead();
                for (var child = head.firstChild; child != null; child = child.nextSibling) {
                    if ((child.nodeName == "META") && (child.getAttribute("name") == "viewport")) {
                        viewportMetaElement = child;
                        break;
                    }
                }
                if (viewportMetaElement == null) {
                    viewportMetaElement = DOM.createElement(document,"META");
                    viewportMetaElement.setAttribute("name","viewport");
                    DOM.appendChild(head,viewportMetaElement);
                }
            }
            viewportMetaElement.setAttribute("content","width = "+width);
        }

        viewportWidth = width;
        viewportHeight = height;

        Selection.updateSelectionDisplay();
        Cursor.ensureCursorVisible();
    }

    // public
    function getViewportWidth()
    {
        return viewportWidth;
    }

    // public
    function getViewportHeight()
    {
        return viewportHeight;
    }

    // public
    function getZoom()
    {
        return window.outerWidth/window.innerWidth;
    }

    window.Viewport = new Object();
    Viewport.setViewportSize = setViewportSize;
    Viewport.getViewportWidth = getViewportWidth;
    Viewport.getViewportHeight = getViewportHeight;
    Viewport.getZoom = getZoom;

})();
<|endoftext|>


<commit_before>window.onload = function() {
   loadOptions();
   updateTime();
   document.getElementById('fixedHelpBtn').addEventListener('click', fixedHelpBtnCB);
   document.getElementById('fixedOptionsBtn').addEventListener('click', fixedOptionsBtnCB);
};

var USER_OPTIONS = JSON.parse(localStorage.getItem('userOptions'));
var comLinks = {
   'r':'https://www.reddit.com/r/',
   'g':'https://www.google.com/search?q=',
   'y':'https://www.youtube.com/results?search_query=',
   'a':'http://smile.amazon.com/s?url=search-alias%3Daps&field-keywords=',
   'w':'https://www.wikipedia.org/w/index.php?title=Special:Search&search=',
   'wa':'http://www.wolframalpha.com/input/?i=',
   'imdb':'https://www.imdb.com/find?s=all&q=',
   'img':'https://www.google.com/search?tbm=isch&q=',
   't':'',
}

function interpret() {
   inputElem = document.getElementById('commandInput');
   inputElem.select();
   var input = inputElem.value;
   if (input == '') { return; }

   // Check for available commands
   if (input.trim() === 'help') {
      displayHelp();
      return;
   } else if (input.trim() === 'options') {
      displayOptions();
      return;
   }

   // Parse input
   var inputArray = input.split(';');
   var nt;
   if (inputArray[inputArray.length-1] === 'n' || USER_OPTIONS.alwaysNewTab) {
      nt = true;
   } else {
      nt = false;
   }
   switch(inputArray.length) {
      case 1:
         command = USER_OPTIONS.defaultCommand;
         query = inputArray[0].trim();
         break;
      case 2:
         if (inputArray[inputArray.length-1] !== 'n') {
            command = inputArray[0].trim();
            query = inputArray[1].trim();
            break;
         } else {
            command = USER_OPTIONS.defaultCommand;
            query = inputArray[0];
            break;
         }
      case 3:
         command = inputArray[0].trim();
         query = inputArray[1].trim();
         // Assume inputArray[2] is new tab flag
         break;
      default:
         displayText('unable to interpret');
   }
   if (command === 'w') { // Wikipedia fix
      query = query.replace(/ /g,'+'); // replace all spaces with +'s
   } else {
      query = encodeURIComponent(query);
   }
   if (comLinks.hasOwnProperty(command)) {
      goToSite(comLinks[command] + query, nt);
      return false;
   } else {
      displayText('command not recognized');
      return;
   }
}

function verifyKey(e) {
   var keycode;
   if (window.event) {
      keycode = window.event.keyCode;
   } else if (e) {
      keycode = e.which;
   }
   if (keycode == 13) { // Enter/return key
      clearTextDiv();
      interpret();
   }
   updateInputLength();
}

function updateInputLength() {
   var input = document.getElementById('commandInput');
   if (input.value.length >= (input.size - 1)) {
      input.size = input.value.length + 1;
   }
}

function goToSite(url, nt) {
   if (!url.startsWith('http')) {
      url = 'https://'+url;
   }
   if (nt) {
      var win = window.open(url);
      win.focus();
      return false;
   } else {
      window.location.href = url;
      return false;
   }
}

function displayText(string) {
   var div = document.getElementById('text_div');
   clearTextDiv();
   div.innerHTML += '
'+string+'
';
}

function clearTextDiv() {
   document.getElementById('text_div').innerHTML = '';
}

function setBgColor(c) {
   document.body.style.backgroundColor = c;
}

function saveOptionsBtnCB() {
   if (typeof(Storage) !== "undefined") {
      // Default command
      var defaultCommandRadios = document.getElementById('defaultCommandForm');
      var defaultCommand = null;
      for (var i=0; i < defaultCommandRadios.length; i++) {
         if (defaultCommandRadios[i].checked) {
            defaultCommand = defaultCommandRadios[i].value;
            break;
         }
      }
      if (defaultCommand !== null) {
         USER_OPTIONS.defaultCommand = defaultCommand;
      }

      // Tab open style
      var alwaysNewTab = document.getElementById('alwaysNewTabCheckbox').checked;
      USER_OPTIONS.alwaysNewTab = alwaysNewTab;

      // Background color
      var bgColor = document.getElementById('bgColorInput').value;
            // check if valid hex value
      if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(bgColor)) {
         USER_OPTIONS.bgColor = bgColor;
         setBgColor(bgColor);

         // Store prefs
         localStorage.setItem('userOptions', JSON.stringify(USER_OPTIONS));
         document.getElementById('optionsSubText').innerHTML = 'settings saved';
      } else {
         document.getElementById('optionsSubText').innerHTML = 'not a valid color';
      }

   } else {
      alert("Browser does not support local storage: your settings won't be saved (sorry)");
   }
   clearTextDiv();
   comInput = document.getElementById('commandInput');
   comInput.value = '';
   comInput.select();
}

function loadOptions() {
   if (typeof(Storage) !== "undefined") {
      if (localStorage.getItem('userOptions') !== null) { // Load options
         var userOptions = localStorage.getItem('userOptions');
         userOptions = JSON.parse(userOptions);
         USER_OPTIONS = userOptions;
         setBgColor(USER_OPTIONS.bgColor);
         return userOptions;
      } else { // Create defaults
         var options = {
            "defaultCommand": "g",
            "alwaysNewTab": false,
            "bgColor": "#A1C0C0"
         };
         localStorage.setItem('userOptions', JSON.stringify(options));
         userOptions = localStorage.getItem('userOptions');
         USER_OPTIONS = JSON.parse(userOptions);
      }
   }
}

function displayOptions() {
   var optionsHTML =
      `

         Default Command (command that executes if no command was specified)

            <form id='defaultCommandForm'>
               <input type='radio' name='defaultCommandRadio' value='t'>Go to website

               <input type='radio' name='defaultCommandRadio' value='g'>Google search

               <input type='radio' name='defaultCommandRadio' value='w'>Wikipedia search

               <input type='radio' name='defaultCommandRadio' value='y'>YouTube search

               <input type='radio' name='defaultCommandRadio' value='a'>Amazon search

               <input type='radio' name='defaultCommandRadio' value='imdb'>IMDB search

               <input type='radio' name='defaultCommandRadio' value='img'>Google Images search

               <input type='radio' name='defaultCommandRadio' value='wa'>Wolfram Alpha search

               <input type='radio' name='defaultCommandRadio' value='r'>Go to subreddit
            </form>

         Open Style

            <input type='checkbox' id='alwaysNewTabCheckbox' value='newTab'>Always open in new tab

         Background Color

            Color: <input type='text' id='bgColorInput' placeholder='#A1C0C0' size='7' spellcheck='false'>
            Color Picker

            <button type='button' id='saveOptionsBtn'>Done</button>

      `
   document.getElementById('text_div').innerHTML = optionsHTML;
   document.getElementById('saveOptionsBtn').onclick = saveOptionsBtnCB;

   // Display saved options
   if (localStorage.getItem('userOptions') !== null) {
      displaySavedOptions();
   } else {
      loadOptions();
      displaySavedOptions();
   }
}

function displaySavedOptions() {
   var defaultCommandRadios = document.getElementById('defaultCommandForm');
   for (var i=0; i < defaultCommandRadios.length; i++) {
      if (USER_OPTIONS.defaultCommand === defaultCommandRadios[i].value) {
         defaultCommandRadios[i].checked = true;
      }
   }
   document.getElementById('alwaysNewTabCheckbox').checked = USER_OPTIONS.alwaysNewTab;
   document.getElementById('bgColorInput').value = USER_OPTIONS.bgColor;
}

function displayHelp() {
   var helpHTML =
      `
syntax:
command;query[;n]

            Command
            Description

            options
            show options menu

            r;&ltsubreddit&gt
            go to subreddit

            g;&ltquery&gt
            google search

            y;&ltquery&gt
            youtube search

            a;&ltquery&gt
            amazon search

            w;&ltquery&gt
            wikipedia search

            imdb;&ltquery&gt
            imdb search

            img;&ltquery&gt
            google images search

            wa;&ltquery&gt
            wolfram alpha search

            t;&lturl&gt
            open url in current tab

            &ltcommand&gt;n
            open action in new tab

            help
            show this text

`
   document.getElementById('text_div').innerHTML = helpHTML;
}

function fixedHelpBtnCB() {
   input = document.getElementById('commandInput');
   input.value = 'help';
   input.select();
   displayHelp();
}

function fixedOptionsBtnCB() {
   input = document.getElementById('commandInput');
   input.value = 'options';
   input.select();
   displayOptions();
}

function checkTime(i) {
   if (i < 10) { i = '0' + i };
   if (i == 0) { i = '12' };
   return i;
}
function updateTime() {
   var d = new Date();
   var h = d.getHours(); if (h > 12) { h -= 12; }; h = checkTime(h);
   var m = checkTime(d.getMinutes());
   document.getElementById('time_div').innerHTML = "
"+h+':'+m+'
';
   var t = setTimeout(updateTime, 5000);
}
<commit_msg>reddit url parameter fix<commit_after>window.onload = function() {
   loadOptions();
   updateTime();
   document.getElementById('fixedHelpBtn').addEventListener('click', fixedHelpBtnCB);
   document.getElementById('fixedOptionsBtn').addEventListener('click', fixedOptionsBtnCB);
};

var USER_OPTIONS = JSON.parse(localStorage.getItem('userOptions'));
var comLinks = {
   'r':'https://www.reddit.com/r/',
   'g':'https://www.google.com/search?q=',
   'y':'https://www.youtube.com/results?search_query=',
   'a':'http://smile.amazon.com/s?url=search-alias%3Daps&field-keywords=',
   'w':'https://www.wikipedia.org/w/index.php?title=Special:Search&search=',
   'wa':'http://www.wolframalpha.com/input/?i=',
   'imdb':'https://www.imdb.com/find?s=all&q=',
   'img':'https://www.google.com/search?tbm=isch&q=',
   't':'',
}

function interpret() {
   inputElem = document.getElementById('commandInput');
   inputElem.select();
   var input = inputElem.value;
   if (input == '') { return; }

   // Check for available commands
   if (input.trim() === 'help') {
      displayHelp();
      return;
   } else if (input.trim() === 'options') {
      displayOptions();
      return;
   }

   // Parse input
   var inputArray = input.split(';');
   var nt;
   if (inputArray[inputArray.length-1] === 'n' || USER_OPTIONS.alwaysNewTab) {
      nt = true;
   } else {
      nt = false;
   }
   switch(inputArray.length) {
      case 1:
         command = USER_OPTIONS.defaultCommand;
         query = inputArray[0].trim();
         break;
      case 2:
         if (inputArray[inputArray.length-1] !== 'n') {
            command = inputArray[0].trim();
            query = inputArray[1].trim();
            break;
         } else {
            command = USER_OPTIONS.defaultCommand;
            query = inputArray[0];
            break;
         }
      case 3:
         command = inputArray[0].trim();
         query = inputArray[1].trim();
         // Assume inputArray[2] is new tab flag
         break;
      default:
         displayText('unable to interpret');
   }
   if (command === 'w') {        // Wikipedia fix
      query = query.replace(/ /g,'+'); // replace all spaces with +'s
   } else if (command === 'r') { // Reddit fix
      // Don't encode, allowing for adding of url parameters e.g. /top?t=month
   } else {
      query = encodeURIComponent(query);
   }
   if (comLinks.hasOwnProperty(command)) {
      goToSite(comLinks[command] + query, nt);
      return false;
   } else {
      displayText('command not recognized');
      return;
   }
}

function verifyKey(e) {
   var keycode;
   if (window.event) {
      keycode = window.event.keyCode;
   } else if (e) {
      keycode = e.which;
   }
   if (keycode == 13) { // Enter/return key
      clearTextDiv();
      interpret();
   }
   updateInputLength();
}

function updateInputLength() {
   var input = document.getElementById('commandInput');
   if (input.value.length >= (input.size - 1)) {
      input.size = input.value.length + 1;
   }
}

function goToSite(url, nt) {
   if (!url.startsWith('http')) {
      url = 'https://'+url;
   }
   if (nt) {
      var win = window.open(url);
      win.focus();
      return false;
   } else {
      window.location.href = url;
      return false;
   }
}

function displayText(string) {
   var div = document.getElementById('text_div');
   clearTextDiv();
   div.innerHTML += '
'+string+'
';
}

function clearTextDiv() {
   document.getElementById('text_div').innerHTML = '';
}

function setBgColor(c) {
   document.body.style.backgroundColor = c;
}

function saveOptionsBtnCB() {
   if (typeof(Storage) !== "undefined") {
      // Default command
      var defaultCommandRadios = document.getElementById('defaultCommandForm');
      var defaultCommand = null;
      for (var i=0; i < defaultCommandRadios.length; i++) {
         if (defaultCommandRadios[i].checked) {
            defaultCommand = defaultCommandRadios[i].value;
            break;
         }
      }
      if (defaultCommand !== null) {
         USER_OPTIONS.defaultCommand = defaultCommand;
      }

      // Tab open style
      var alwaysNewTab = document.getElementById('alwaysNewTabCheckbox').checked;
      USER_OPTIONS.alwaysNewTab = alwaysNewTab;

      // Background color
      var bgColor = document.getElementById('bgColorInput').value;
            // check if valid hex value
      if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(bgColor)) {
         USER_OPTIONS.bgColor = bgColor;
         setBgColor(bgColor);

         // Store prefs
         localStorage.setItem('userOptions', JSON.stringify(USER_OPTIONS));
         document.getElementById('optionsSubText').innerHTML = 'settings saved';
      } else {
         document.getElementById('optionsSubText').innerHTML = 'not a valid color';
      }

   } else {
      alert("Browser does not support local storage: your settings won't be saved (sorry)");
   }
   clearTextDiv();
   comInput = document.getElementById('commandInput');
   comInput.value = '';
   comInput.select();
}

function loadOptions() {
   if (typeof(Storage) !== "undefined") {
      if (localStorage.getItem('userOptions') !== null) { // Load options
         var userOptions = localStorage.getItem('userOptions');
         userOptions = JSON.parse(userOptions);
         USER_OPTIONS = userOptions;
         setBgColor(USER_OPTIONS.bgColor);
         return userOptions;
      } else { // Create defaults
         var options = {
            "defaultCommand": "g",
            "alwaysNewTab": false,
            "bgColor": "#A1C0C0"
         };
         localStorage.setItem('userOptions', JSON.stringify(options));
         userOptions = localStorage.getItem('userOptions');
         USER_OPTIONS = JSON.parse(userOptions);
      }
   }
}

function displayOptions() {
   var optionsHTML =
      `

         Default Command (command that executes if no command was specified)

            <form id='defaultCommandForm'>
               <input type='radio' name='defaultCommandRadio' value='t'>Go to website

               <input type='radio' name='defaultCommandRadio' value='g'>Google search

               <input type='radio' name='defaultCommandRadio' value='w'>Wikipedia search

               <input type='radio' name='defaultCommandRadio' value='y'>YouTube search

               <input type='radio' name='defaultCommandRadio' value='a'>Amazon search

               <input type='radio' name='defaultCommandRadio' value='imdb'>IMDB search

               <input type='radio' name='defaultCommandRadio' value='img'>Google Images search

               <input type='radio' name='defaultCommandRadio' value='wa'>Wolfram Alpha search

               <input type='radio' name='defaultCommandRadio' value='r'>Go to subreddit
            </form>

         Open Style

            <input type='checkbox' id='alwaysNewTabCheckbox' value='newTab'>Always open in new tab

         Background Color

            Color: <input type='text' id='bgColorInput' placeholder='#A1C0C0' size='7' spellcheck='false'>
            Color Picker

            <button type='button' id='saveOptionsBtn'>Done</button>

      `
   document.getElementById('text_div').innerHTML = optionsHTML;
   document.getElementById('saveOptionsBtn').onclick = saveOptionsBtnCB;

   // Display saved options
   if (localStorage.getItem('userOptions') !== null) {
      displaySavedOptions();
   } else {
      loadOptions();
      displaySavedOptions();
   }
}

function displaySavedOptions() {
   var defaultCommandRadios = document.getElementById('defaultCommandForm');
   for (var i=0; i < defaultCommandRadios.length; i++) {
      if (USER_OPTIONS.defaultCommand === defaultCommandRadios[i].value) {
         defaultCommandRadios[i].checked = true;
      }
   }
   document.getElementById('alwaysNewTabCheckbox').checked = USER_OPTIONS.alwaysNewTab;
   document.getElementById('bgColorInput').value = USER_OPTIONS.bgColor;
}

function displayHelp() {
   var helpHTML =
      `
syntax:
command;query[;n]

            Command
            Description

            options
            show options menu

            r;&ltsubreddit&gt
            go to subreddit

            g;&ltquery&gt
            google search

            y;&ltquery&gt
            youtube search

            a;&ltquery&gt
            amazon search

            w;&ltquery&gt
            wikipedia search

            imdb;&ltquery&gt
            imdb search

            img;&ltquery&gt
            google images search

            wa;&ltquery&gt
            wolfram alpha search

            t;&lturl&gt
            open url in current tab

            &ltcommand&gt;n
            open action in new tab

            help
            show this text

`
   document.getElementById('text_div').innerHTML = helpHTML;
}

function fixedHelpBtnCB() {
   input = document.getElementById('commandInput');
   input.value = 'help';
   input.select();
   displayHelp();
}

function fixedOptionsBtnCB() {
   input = document.getElementById('commandInput');
   input.value = 'options';
   input.select();
   displayOptions();
}

function checkTime(i) {
   if (i < 10) { i = '0' + i };
   if (i == 0) { i = '12' };
   return i;
}
function updateTime() {
   var d = new Date();
   var h = d.getHours(); if (h > 12) { h -= 12; }; h = checkTime(h);
   var m = checkTime(d.getMinutes());
   document.getElementById('time_div').innerHTML = "
"+h+':'+m+'
';
   var t = setTimeout(updateTime, 5000);
}
<|endoftext|>


<commit_before>/**
 * @fileOverview 自定义的 shape
 * @author dxq613@gmail.com
 * @author sima.zhang1990@gmail.com
 */

const Util = require('../../util');
const Shape = require('./shape');
const Global = require('../../global');

function _parseValue(value) {
  if (!Util.isArray(value)) {
    value = [ value ];
  }
  const min = value[0]; // 最小值
  const max = value[value.length - 1]; // 最大值
  const min1 = value.length > 1 ? value[1] : min;
  const max1 = value.length > 3 ? value[3] : max;
  const median = value.length > 2 ? value[2] : min1;

  return {
    min, // 最小值
    max, // 最大值
    min1,
    max1,
    median
  };
}

function addPoints(from, to) {
  Util.each(from, function(subArr) {
    to.push({
      x: subArr[0],
      y: subArr[1]
    });
  });
}

function getAttrs(cfg) {
  const defaultAttrs = Global.shape.line;
  const attrs = Util.mix({}, defaultAttrs, {
    stroke: cfg.color,
    strokeOpacity: cfg.opacity
  });
  return attrs;
}

function getBoxPoints(x, y, width) {
  const points = [];
  let pointsArray;
  let obj;
  if (Util.isArray(y)) { // 2维
    obj = _parseValue(y);
    pointsArray = [
      [ x - width / 2, obj.max ],
      [ x + width / 2, obj.max ],
      [ x, obj.max ],
      [ x, obj.max1 ],
      [ x - width / 2, obj.min1 ],
      [ x - width / 2, obj.max1 ],
      [ x + width / 2, obj.max1 ],
      [ x + width / 2, obj.min1 ],
      [ x, obj.min1 ],
      [ x, obj.min ],
      [ x - width / 2, obj.min ],
      [ x + width / 2, obj.min ],
      [ x - width / 2, obj.median ],
      [ x + width / 2, obj.median ]
    ];
  } else { // 只有一个维度
    y = y || 0.5;
    obj = _parseValue(x);
    pointsArray = [
      [ obj.min, y - width / 2 ],
      [ obj.min, y + width / 2 ],
      [ obj.min, y ],
      [ obj.min1, y ],
      [ obj.min1, y - width / 2 ],
      [ obj.min1, y + width / 2 ],
      [ obj.max1, y + width / 2 ],
      [ obj.max1, y - width / 2 ],
      [ obj.max1, y ],
      [ obj.max, y ],
      [ obj.max, y - width / 2 ],
      [ obj.max, y + width / 2 ],
      [ obj.median, y - width / 2 ],
      [ obj.median, y + width / 2 ]
    ];
  }
  addPoints(pointsArray, points);
  return points;
}

function _sortValue(value) {
  if (!Util.isArray(value)) {
    value = [ value ];
  }
  // 从大到小排序
  const sorted = value.sort(function(a, b) {
    return a < b ? 1 : -1;
  });

  const length = sorted.length;
  if (length < 4) {
    const min = sorted[length - 1];
    for (let i = 0; i < (4 - length); i++) {
      sorted.push(min);
    }
  }

  return sorted;
}

// 获取K线图的points
function getCandlePoints(x, y, width) {
  const yValues = _sortValue(y);
  const points = [{
    x,
    y: yValues[0]
  }, {
    x,
    y: yValues[1]
  }, {
    x: x - width / 2,
    y: yValues[2]
  }, {
    x: x - width / 2,
    y: yValues[1]
  }, {
    x: x + width / 2,
    y: yValues[1]
  }, {
    x: x + width / 2,
    y: yValues[2]
  }, {
    x,
    y: yValues[2]
  }, {
    x,
    y: yValues[3]
  }]; // 按照顺时针连接
  return points;
}

function getBoxPath(points) {
  const path = [
    [ 'M', points[0].x, points[0].y ],
    [ 'L', points[1].x, points[1].y ],
    [ 'M', points[2].x, points[2].y ],
    [ 'L', points[3].x, points[3].y ],
    [ 'M', points[4].x, points[4].y ],
    [ 'L', points[5].x, points[5].y ],
    [ 'L', points[6].x, points[6].y ],
    [ 'L', points[7].x, points[7].y ],
    [ 'L', points[4].x, points[4].y ], // 封闭 z
    [ 'Z' ],
    [ 'M', points[8].x, points[8].y ],
    [ 'L', points[9].x, points[9].y ],
    [ 'M', points[10].x, points[10].y ],
    [ 'L', points[11].x, points[11].y ],
    [ 'M', points[12].x, points[12].y ],
    [ 'L', points[13].x, points[13].y ]
  ];
  return path;
}

function getCandlePath(points) {
  const path = [
    [ 'M', points[0].x, points[0].y ],
    [ 'L', points[1].x, points[1].y ],
    [ 'M', points[2].x, points[2].y ],
    [ 'L', points[3].x, points[3].y ],
    [ 'L', points[4].x, points[4].y ],
    [ 'L', points[5].x, points[5].y ],
    [ 'Z' ],
    [ 'M', points[6].x, points[6].y ],
    [ 'L', points[7].x, points[7].y ]
  ];
  return path;
}

// 获取图形的marker
function getMarkerCfg(cfg, fn) {
  return Util.mix({
    symbol: fn,
    radius: Global.markerRadius
  }, getAttrs(cfg));
}

const Schema = Shape.registerFactory('schema', {
  defaultShapeType: '',
  getActiveCfg(type, cfg) {
    if (type === 'box') {
      const lineWidth = cfg.lineWidth || 1;
      return {
        lineWidth: lineWidth + 1
      };
    }
    const opacity = cfg.fillOpacity || cfg.opacity || 1;
    return {
      fillOpacity: opacity - 0.15,
      strokeOpacity: opacity - 0.15
    };
  },
  getSelectedCfg(type, cfg) {
    if (cfg && cfg.style) {
      return cfg.style;
    }
    return this.getActiveCfg(type, cfg);
  }
});

// 箱线图
Shape.registerShape('schema', 'box', {
  getPoints(pointInfo) {
    return getBoxPoints(pointInfo.x, pointInfo.y, pointInfo.size);
  },
  draw(cfg, container) {
    const attrs = getAttrs(cfg);
    let path = getBoxPath(cfg.points);
    path = this.parsePath(path);
    return container.addShape('path', {
      attrs: Util.mix(attrs, {
        path,
        fill: '#fff',
        fillOpacity: 0
      })
    });
  },
  getMarkerCfg(cfg) {
    return getMarkerCfg(cfg, function(x, y, r, ctx) {
      const yValues = [ y - r, y - r / 2, y, y + r / 2, y + r ];
      const points = getBoxPoints(x, yValues, 1.2 * r);
      ctx.moveTo(points[0].x, points[0].y);
      ctx.lineTo(points[1].x, points[1].y);
      ctx.moveTo(points[2].x, points[2].y);
      ctx.lineTo(points[3].x, points[3].y);
      ctx.moveTo(points[4].x, points[4].y);
      ctx.lineTo(points[5].x, points[5].y);
      ctx.lineTo(points[6].x, points[6].y);
      ctx.lineTo(points[7].x, points[7].y);
      ctx.lineTo(points[4].x, points[4].y);
      ctx.closePath();
      ctx.moveTo(points[8].x, points[8].y);
      ctx.lineTo(points[9].x, points[9].y);
      ctx.moveTo(points[10].x, points[10].y);
      ctx.lineTo(points[11].x, points[11].y);
      ctx.moveTo(points[12].x, points[12].y);
      ctx.lineTo(points[13].x, points[13].y);
    });
  }
});

// K线
Shape.registerShape('schema', 'candle', {
  getPoints(pointInfo) {
    return getCandlePoints(pointInfo.x, pointInfo.y, pointInfo.size);
  },
  draw(cfg, container) {
    const attrs = getAttrs(cfg);
    let path = getCandlePath(cfg.points);
    path = this.parsePath(path);
    return container.addShape('path', {
      attrs: Util.mix(attrs, {
        path,
        fill: cfg.color,
        fillOpacity: cfg.opacity,
        lineWidth: 1
      })
    });
  },
  getMarkerCfg(cfg) {
    const tmp = getMarkerCfg(cfg, function(x, y, r, ctx) {
      y = [ y + 1.5 * r, y + r / 2, y - r / 2, y - 1.5 * r ];
      const points = getCandlePoints(x, y, r);
      ctx.moveTo(points[0].x, points[0].y);
      ctx.lineTo(points[1].x, points[1].y);
      ctx.moveTo(points[2].x, points[2].y);
      ctx.lineTo(points[3].x, points[3].y);
      ctx.lineTo(points[4].x, points[4].y);
      ctx.lineTo(points[5].x, points[5].y);
      ctx.closePath();
      ctx.moveTo(points[6].x, points[6].y);
      ctx.lineTo(points[7].x, points[7].y);
    });
    tmp.fill = cfg.color;
    tmp.fillOpacity = cfg.opacity;
    tmp.radius = 5;
    return tmp;
  }
});

module.exports = Schema;
<commit_msg>schema 支持 geom.style() 设置样式<commit_after>/**
 * @fileOverview 自定义的 shape
 * @author dxq613@gmail.com
 * @author sima.zhang1990@gmail.com
 */

const Util = require('../../util');
const Shape = require('./shape');
const Global = require('../../global');

function _parseValue(value) {
  if (!Util.isArray(value)) {
    value = [ value ];
  }
  const min = value[0]; // 最小值
  const max = value[value.length - 1]; // 最大值
  const min1 = value.length > 1 ? value[1] : min;
  const max1 = value.length > 3 ? value[3] : max;
  const median = value.length > 2 ? value[2] : min1;

  return {
    min, // 最小值
    max, // 最大值
    min1,
    max1,
    median
  };
}

function addPoints(from, to) {
  Util.each(from, function(subArr) {
    to.push({
      x: subArr[0],
      y: subArr[1]
    });
  });
}

function getAttrs(cfg) {
  const defaultAttrs = Global.shape.line;
  const attrs = Util.mix({}, defaultAttrs, {
    stroke: cfg.color,
    strokeOpacity: cfg.opacity
  }, cfg.style);
  return attrs;
}

function getFillAttrs(cfg) {
  const defaultAttrs = Global.shape.line;
  const attrs = Util.mix({}, defaultAttrs, {
    fill: cfg.color,
    stroke: cfg.color,
    fillOpacity: cfg.opacity
  }, cfg.style);
  return attrs;
}

function getBoxPoints(x, y, width) {
  const points = [];
  let pointsArray;
  let obj;
  if (Util.isArray(y)) { // 2维
    obj = _parseValue(y);
    pointsArray = [
      [ x - width / 2, obj.max ],
      [ x + width / 2, obj.max ],
      [ x, obj.max ],
      [ x, obj.max1 ],
      [ x - width / 2, obj.min1 ],
      [ x - width / 2, obj.max1 ],
      [ x + width / 2, obj.max1 ],
      [ x + width / 2, obj.min1 ],
      [ x, obj.min1 ],
      [ x, obj.min ],
      [ x - width / 2, obj.min ],
      [ x + width / 2, obj.min ],
      [ x - width / 2, obj.median ],
      [ x + width / 2, obj.median ]
    ];
  } else { // 只有一个维度
    y = y || 0.5;
    obj = _parseValue(x);
    pointsArray = [
      [ obj.min, y - width / 2 ],
      [ obj.min, y + width / 2 ],
      [ obj.min, y ],
      [ obj.min1, y ],
      [ obj.min1, y - width / 2 ],
      [ obj.min1, y + width / 2 ],
      [ obj.max1, y + width / 2 ],
      [ obj.max1, y - width / 2 ],
      [ obj.max1, y ],
      [ obj.max, y ],
      [ obj.max, y - width / 2 ],
      [ obj.max, y + width / 2 ],
      [ obj.median, y - width / 2 ],
      [ obj.median, y + width / 2 ]
    ];
  }
  addPoints(pointsArray, points);
  return points;
}

function _sortValue(value) {
  if (!Util.isArray(value)) {
    value = [ value ];
  }
  // 从大到小排序
  const sorted = value.sort(function(a, b) {
    return a < b ? 1 : -1;
  });

  const length = sorted.length;
  if (length < 4) {
    const min = sorted[length - 1];
    for (let i = 0; i < (4 - length); i++) {
      sorted.push(min);
    }
  }

  return sorted;
}

// 获取K线图的points
function getCandlePoints(x, y, width) {
  const yValues = _sortValue(y);
  const points = [{
    x,
    y: yValues[0]
  }, {
    x,
    y: yValues[1]
  }, {
    x: x - width / 2,
    y: yValues[2]
  }, {
    x: x - width / 2,
    y: yValues[1]
  }, {
    x: x + width / 2,
    y: yValues[1]
  }, {
    x: x + width / 2,
    y: yValues[2]
  }, {
    x,
    y: yValues[2]
  }, {
    x,
    y: yValues[3]
  }]; // 按照顺时针连接
  return points;
}

function getBoxPath(points) {
  const path = [
    [ 'M', points[0].x, points[0].y ],
    [ 'L', points[1].x, points[1].y ],
    [ 'M', points[2].x, points[2].y ],
    [ 'L', points[3].x, points[3].y ],
    [ 'M', points[4].x, points[4].y ],
    [ 'L', points[5].x, points[5].y ],
    [ 'L', points[6].x, points[6].y ],
    [ 'L', points[7].x, points[7].y ],
    [ 'L', points[4].x, points[4].y ], // 封闭 z
    [ 'Z' ],
    [ 'M', points[8].x, points[8].y ],
    [ 'L', points[9].x, points[9].y ],
    [ 'M', points[10].x, points[10].y ],
    [ 'L', points[11].x, points[11].y ],
    [ 'M', points[12].x, points[12].y ],
    [ 'L', points[13].x, points[13].y ]
  ];
  return path;
}

function getCandlePath(points) {
  const path = [
    [ 'M', points[0].x, points[0].y ],
    [ 'L', points[1].x, points[1].y ],
    [ 'M', points[2].x, points[2].y ],
    [ 'L', points[3].x, points[3].y ],
    [ 'L', points[4].x, points[4].y ],
    [ 'L', points[5].x, points[5].y ],
    [ 'Z' ],
    [ 'M', points[6].x, points[6].y ],
    [ 'L', points[7].x, points[7].y ]
  ];
  return path;
}

// 获取图形的marker
function getMarkerCfg(cfg, fn) {
  return Util.mix({
    symbol: fn,
    radius: Global.markerRadius
  }, getAttrs(cfg));
}

const Schema = Shape.registerFactory('schema', {
  defaultShapeType: '',
  getActiveCfg(type, cfg) {
    if (type === 'box') {
      const lineWidth = cfg.lineWidth || 1;
      return {
        lineWidth: lineWidth + 1
      };
    }
    const opacity = cfg.fillOpacity || cfg.opacity || 1;
    return {
      fillOpacity: opacity - 0.15,
      strokeOpacity: opacity - 0.15
    };
  },
  getSelectedCfg(type, cfg) {
    if (cfg && cfg.style) {
      return cfg.style;
    }
    return this.getActiveCfg(type, cfg);
  }
});

// 箱线图
Shape.registerShape('schema', 'box', {
  getPoints(pointInfo) {
    return getBoxPoints(pointInfo.x, pointInfo.y, pointInfo.size);
  },
  draw(cfg, container) {
    const attrs = getAttrs(cfg);
    let path = getBoxPath(cfg.points);
    path = this.parsePath(path);
    return container.addShape('path', {
      attrs: Util.mix(attrs, {
        path
      })
    });
  },
  getMarkerCfg(cfg) {
    return getMarkerCfg(cfg, function(x, y, r, ctx) {
      const yValues = [ y - r, y - r / 2, y, y + r / 2, y + r ];
      const points = getBoxPoints(x, yValues, 1.2 * r);
      ctx.moveTo(points[0].x, points[0].y);
      ctx.lineTo(points[1].x, points[1].y);
      ctx.moveTo(points[2].x, points[2].y);
      ctx.lineTo(points[3].x, points[3].y);
      ctx.moveTo(points[4].x, points[4].y);
      ctx.lineTo(points[5].x, points[5].y);
      ctx.lineTo(points[6].x, points[6].y);
      ctx.lineTo(points[7].x, points[7].y);
      ctx.lineTo(points[4].x, points[4].y);
      ctx.closePath();
      ctx.moveTo(points[8].x, points[8].y);
      ctx.lineTo(points[9].x, points[9].y);
      ctx.moveTo(points[10].x, points[10].y);
      ctx.lineTo(points[11].x, points[11].y);
      ctx.moveTo(points[12].x, points[12].y);
      ctx.lineTo(points[13].x, points[13].y);
    });
  }
});

// K线
Shape.registerShape('schema', 'candle', {
  getPoints(pointInfo) {
    return getCandlePoints(pointInfo.x, pointInfo.y, pointInfo.size);
  },
  draw(cfg, container) {
    const attrs = getFillAttrs(cfg);
    let path = getCandlePath(cfg.points);
    path = this.parsePath(path);
    return container.addShape('path', {
      attrs: Util.mix(attrs, {
        path
      })
    });
  },
  getMarkerCfg(cfg) {
    const tmp = getMarkerCfg(cfg, function(x, y, r, ctx) {
      y = [ y + 1.5 * r, y + r / 2, y - r / 2, y - 1.5 * r ];
      const points = getCandlePoints(x, y, r);
      ctx.moveTo(points[0].x, points[0].y);
      ctx.lineTo(points[1].x, points[1].y);
      ctx.moveTo(points[2].x, points[2].y);
      ctx.lineTo(points[3].x, points[3].y);
      ctx.lineTo(points[4].x, points[4].y);
      ctx.lineTo(points[5].x, points[5].y);
      ctx.closePath();
      ctx.moveTo(points[6].x, points[6].y);
      ctx.lineTo(points[7].x, points[7].y);
    });
    tmp.fill = cfg.color;
    tmp.fillOpacity = cfg.opacity;
    tmp.radius = 5;
    return tmp;
  }
});

module.exports = Schema;
<|endoftext|>