<commit_before>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2019, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

import _ from 'lodash';
import sundial from 'sundial';

import TZOUtil from '../../TimezoneOffsetUtil';
import annotate from '../../eventAnnotations';
import { remote } from 'electron';

const isBrowser = typeof window !== 'undefined';
// eslint-disable-next-line no-console
const debug = isBrowser ? require('bows')('BluetoothLEDriver') : console.log;

module.exports = (config) => {
  const cfg = _.clone(config);
  cfg.deviceTags = ['bgm'];

  // With no date & time settings changes available,
  // timezone is applied across-the-board
  cfg.tzoUtil = new TZOUtil(cfg.timezone, new Date().toISOString(), []);

  return {
   /* eslint no-param-reassign:
      [ "error", { "props": true, "ignorePropertyModificationsFor": ["data"] } ] */

   detect(deviceInfo, cb) {
     debug('no detect function needed', deviceInfo);
     cb(null, deviceInfo);
   },

   setup(deviceInfo, progress, cb) {
     debug('in setup!');
     progress(100);
     cb(null, { deviceInfo });
   },

   connect(progress, data, cb) {
     debug('in connect!');

     (async () => {
       await cfg.deviceComms.ble.connectTimeout();
     })().then(() => {
       return cb(null, data);
     }).catch((error) => {
       debug('Error in connect: ', error);
       return cb(error, null);
     });
   },

   getConfigInfo(progress, data, cb) {
     debug('in getConfigInfo', data);
     progress(0);

     (async () => {
       _.assign(cfg.deviceInfo , await cfg.deviceComms.ble.getDeviceInfo());
     })().then(() => {
       if (!cfg.deviceInfo.name.startsWith('CareSens')) {
         return cb (new Error('We don\'t currently support this meter.'));
       }

       cfg.deviceTags = ['bgm'];
       cfg.deviceInfo.deviceId = `${[cfg.deviceInfo.manufacturers]}-${cfg.deviceInfo.model}-${remote.getGlobal('bluetoothDeviceId')}`;
       data.deviceModel = cfg.deviceInfo.model; // for metrics
       cfg.builder.setDefaults({ deviceId: cfg.deviceInfo.deviceId });
       return cb(null, data);
     }).catch((error) => {
       debug('Error in getConfigInfo: ', error);
       return cb(error, null);
     });
   },

   fetchData(progress, data, cb) {
     debug('in fetchData', data);

     cfg.deviceComms.ble.once('data', (result) => {
       debug('Records:', result);
       data.records = result;
       return cb(null, data);
     });

     (async () => {
       await cfg.deviceComms.ble.getAllRecords();
     })().catch((error) => {
       return cb(error, null);
     });
   },

   processData(progress, data, cb) {
     progress(0);
     data.post_records = [];

     _.forEach(data.records, (result) => {
       const record = result;
       let annotation = null;

       if (record.value > 600) {
         record.value = 601;
         annotation = {
           code: 'bg/out-of-range',
           threshold: 600,
           value: 'high',
         };
       } else if (record.value < 20) {
         record.value = 19;
         annotation = {
           code: 'bg/out-of-range',
           threshold: 20,
           value: 'low',
         };
       }

       if (record.type !== 10) { //check that it's not control solution
         const postRecord = cfg.builder.makeSMBG()
           .with_value(record.value)
           .with_units(record.units)
           .with_deviceTime(sundial.formatDeviceTime(record.timestamp))
           .set('index', record.seqNum);

         if (annotation) {
           annotate.annotateEvent(postRecord, annotation);
         }

         cfg.tzoUtil.fillInUTCInfo(postRecord, record.timestamp);
         delete postRecord.index;

         data.post_records.push(postRecord.done());
       }
     });

     debug('POST records:', data.post_records);

     if (data.post_records.length === 0) {
       debug('Device has no records to upload');
       return cb(new Error('Device has no records to upload'), null);
     }

     progress(100);
     return cb(null, data);
   },

   uploadData(progress, data, cb) {
     progress(0);

     const sessionInfo = {
       deviceTags: cfg.deviceTags,
       deviceManufacturers: cfg.deviceInfo.manufacturers,
       deviceModel: cfg.deviceInfo.model,
       deviceId: cfg.deviceInfo.deviceId,
       deviceSerialNumber: cfg.deviceInfo.serial,
       start: sundial.utcDateString(),
       timeProcessing: cfg.tzoUtil.type,
       tzName: cfg.timezone,
       version: cfg.version,
     };

     cfg.api.upload.toPlatform(
       data.post_records, sessionInfo, progress, cfg.groupId,
       (err, result) => {
         progress(100);

         if (err) {
           debug(err);
           debug(result);
           return cb(err, data);
         }
         data.cleanup = true;
         return cb(null, data);
       },
       'dataservices',
     );
   },

   disconnect(progress, data, cb) {
     // performing disconnect in cleanup
     data.disconnect = true;
     cb(null, data);
   },

   cleanup(progress, data, cb) {
     debug('in cleanup');

     (async () => {
       await cfg.deviceComms.ble.disconnect();
     })().then(() => {
       progress(100);
       data.cleanup = true;
       return cb();
     });
   },
  };
};
<commit_msg>handle ketones on caresens dual<commit_after>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2019, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

import _ from 'lodash';
import sundial from 'sundial';

import TZOUtil from '../../TimezoneOffsetUtil';
import annotate from '../../eventAnnotations';
import { remote } from 'electron';

const isBrowser = typeof window !== 'undefined';
// eslint-disable-next-line no-console
const debug = isBrowser ? require('bows')('BluetoothLEDriver') : console.log;

const KETONE_VALUE_FACTOR = 10;
const KETONE_HI = 8.0;

module.exports = (config) => {
  const cfg = _.clone(config);
  cfg.deviceTags = ['bgm'];

  // With no date & time settings changes available,
  // timezone is applied across-the-board
  cfg.tzoUtil = new TZOUtil(cfg.timezone, new Date().toISOString(), []);

  return {
   /* eslint no-param-reassign:
      [ "error", { "props": true, "ignorePropertyModificationsFor": ["data"] } ] */

   detect(deviceInfo, cb) {
     debug('no detect function needed', deviceInfo);
     cb(null, deviceInfo);
   },

   setup(deviceInfo, progress, cb) {
     debug('in setup!');
     progress(100);
     cb(null, { deviceInfo });
   },

   connect(progress, data, cb) {
     debug('in connect!');

     (async () => {
       await cfg.deviceComms.ble.connectTimeout();
     })().then(() => {
       return cb(null, data);
     }).catch((error) => {
       debug('Error in connect: ', error);
       return cb(error, null);
     });
   },

   getConfigInfo(progress, data, cb) {
     debug('in getConfigInfo', data);
     progress(0);

     (async () => {
       _.assign(cfg.deviceInfo , await cfg.deviceComms.ble.getDeviceInfo());
     })().then(() => {
       if (!cfg.deviceInfo.name.startsWith('CareSens')) {
         return cb (new Error('We don\'t currently support this meter.'));
       }

       cfg.deviceTags = ['bgm'];
       cfg.deviceInfo.deviceId = `${[cfg.deviceInfo.manufacturers]}-${cfg.deviceInfo.model}-${remote.getGlobal('bluetoothDeviceId')}`;
       data.deviceModel = cfg.deviceInfo.model; // for metrics
       cfg.builder.setDefaults({ deviceId: cfg.deviceInfo.deviceId });
       return cb(null, data);
     }).catch((error) => {
       debug('Error in getConfigInfo: ', error);
       return cb(error, null);
     });
   },

   fetchData(progress, data, cb) {
     debug('in fetchData', data);

     cfg.deviceComms.ble.once('data', (result) => {
       debug('Records:', result);
       _.assign(data, result);
       return cb(null, data);
     });

     (async () => {
       await cfg.deviceComms.ble.getAllRecords();
     })().catch((error) => {
       return cb(error, null);
     });
   },

   processData(progress, data, cb) {
     progress(0);
     data.post_records = [];
     let isKetone = false;

     _.forEach(data.records, (result) => {
       const record = result;
       let annotation = null;

       if (record.hasContext) {
         const context = _.find(
           data.contextRecords,
           { 'seqNum' : record.seqNum }
         );

         if (context) {
           if (context.meal && context.meal === 6) {
             isKetone = true;
           }
         } else {
           throw new Error ('Could not find context of measurement');
         }
       }

       if (isKetone) {
         // According to spec, HI > 8 mmol/L
         // there is no LO as values are between 0 and 8 mmol/L
         if (record.value > (KETONE_HI * KETONE_VALUE_FACTOR) ) {
           record.value = KETONE_HI + (1 / KETONE_VALUE_FACTOR);
           annotation = {
             code: 'ketone/out-of-range',
             threshold: KETONE_HI,
             value: 'high',
           };
         } else {
           record.value /= KETONE_VALUE_FACTOR;
         }
       } else {
         if (record.value > 600) {
           record.value = 601;
           annotation = {
             code: 'bg/out-of-range',
             threshold: 600,
             value: 'high',
           };
         } else if (record.value < 20) {
           record.value = 19;
           annotation = {
             code: 'bg/out-of-range',
             threshold: 20,
             value: 'low',
           };
         }
       }

       if (record.type !== 10) { //check that it's not control solution
         let postRecord = null;

         if (isKetone) {
           postRecord = cfg.builder.makeBloodKetone()
             .with_value(record.value)
             .with_units('mmol/L'); // ketones are hard-coded in mmol/L
         } else {
           postRecord = cfg.builder.makeSMBG()
             .with_value(record.value)
             .with_units(record.units);
         }

         postRecord
            .with_deviceTime(sundial.formatDeviceTime(record.timestamp))
            .set('index', record.seqNum);

         if (annotation) {
           annotate.annotateEvent(postRecord, annotation);
         }

         cfg.tzoUtil.fillInUTCInfo(postRecord, record.timestamp);
         delete postRecord.index;

         data.post_records.push(postRecord.done());
       }
     });

     debug('POST records:', data.post_records);

     if (data.post_records.length === 0) {
       debug('Device has no records to upload');
       return cb(new Error('Device has no records to upload'), null);
     }

     progress(100);
     return cb(null, data);
   },

   uploadData(progress, data, cb) {
     progress(0);

     const sessionInfo = {
       deviceTags: cfg.deviceTags,
       deviceManufacturers: cfg.deviceInfo.manufacturers,
       deviceModel: cfg.deviceInfo.model,
       deviceId: cfg.deviceInfo.deviceId,
       deviceSerialNumber: cfg.deviceInfo.serial,
       start: sundial.utcDateString(),
       timeProcessing: cfg.tzoUtil.type,
       tzName: cfg.timezone,
       version: cfg.version,
     };

     cfg.api.upload.toPlatform(
       data.post_records, sessionInfo, progress, cfg.groupId,
       (err, result) => {
         progress(100);

         if (err) {
           debug(err);
           debug(result);
           return cb(err, data);
         }
         data.cleanup = true;
         return cb(null, data);
       },
       'dataservices',
     );
   },

   disconnect(progress, data, cb) {
     // performing disconnect in cleanup
     data.disconnect = true;
     cb(null, data);
   },

   cleanup(progress, data, cb) {
     debug('in cleanup');

     (async () => {
       await cfg.deviceComms.ble.disconnect();
     })().then(() => {
       progress(100);
       data.cleanup = true;
       return cb();
     }).catch((error) => {
       debug('Error during disconnect: ', error);
       return cb();
    });
   },
  };
};
<|endoftext|>


<commit_before>const React = require("react")
const classes = require("./classes")

const $ = React.createElement

function makeType(t, i) {
  const className = classes(
    `type-${t}`,
    "ttu tc db ph1 pv2 f5-ns f6 br2 ba badge with-border-color b",
    {mt1: i > 0}
  )
  const style = {
    minWidth: "7em"
  }
  return $("span", {key: t, className, style}, t)
}

function makePKMN(p) {
  const className = classes(
    "bt b--black-10",
    "ph2 pv3",
    "flex items-center"
  )
  const height = "5rem"
  const style = {
    lineHeight: height,
    minHeight: height,
  }
  return $("div", {key: p.number, className},
    $("div", {className: "flex-auto f4 f2-ns mv0"},
      $("h3", {className: "truncate mt0 mb1"}, p.name),
      $("p", {className: "silver mv0"}, `#${p.number}`)
    ),
    $("div", {}, p.types.map(makeType))
  )
}

function Dex(props) {
  const {pkmn, search, updateSearch} = props
  const className = classes(
    "ph2 mt3",
    "center mw7"
  )
  const searchInput =
    $("input", {
      className: classes(
        "f2 w-100 border-box",
        "pv2 ph3",
        "mv4",
        "chunky-focus",
        "br2 ba b--black-20"
      ),
      placeholder: "search",
      value: search,
      onChange: event =>
        updateSearch(event.target.value),
    })
  return $("div", {className},
    $("a", {href: "#", className: "GoToTop"}, "⬆"),
    $("div", {className: "mh2"}, searchInput),
    pkmn.map(makePKMN)
  )
}

module.exports = Dex
<commit_msg>Pill mode<commit_after>const React = require("react")
const classes = require("./classes")

const $ = React.createElement

function makeType(t, i) {
  const className = classes(
    `type-${t}`,
    "ttu tc db ph1 pv2 f5-ns f6 br2 ba badge with-border-color b",
    {mt1: i > 0}
  )
  const style = {
    minWidth: "7em"
  }
  return $("span", {key: t, className, style}, t)
}

function makePKMN(p) {
  const className = classes(
    "bt b--black-10",
    "ph2 pv3",
    "flex items-center"
  )
  const height = "5rem"
  const style = {
    lineHeight: height,
    minHeight: height,
  }
  return $("div", {key: p.number, className},
    $("div", {className: "flex-auto f4 f2-ns mv0"},
      $("h3", {className: "truncate mt0 mb1"}, p.name),
      $("p", {className: "silver mv0"}, `#${p.number}`)
    ),
    $("div", {}, p.types.map(makeType))
  )
}

function Dex(props) {
  const {pkmn, search, updateSearch} = props
  const className = classes(
    "ph2 mt3",
    "center mw7"
  )
  const searchInput =
    $("input", {
      className: classes(
        "f2 w-100 border-box",
        "pv2 ph4",
        "mv4",
        "chunky-focus",
        "br-pill ba b--black-20"
      ),
      placeholder: "search",
      value: search,
      onChange: event =>
        updateSearch(event.target.value),
    })
  return $("div", {className},
    $("a", {href: "#", className: "GoToTop"}, "⬆"),
    $("div", {className: "mh2"}, searchInput),
    pkmn.map(makePKMN)
  )
}

module.exports = Dex
<|endoftext|>


<commit_before>(function () {
  'use strict';

  // bc.vc, shortcut, dirty hack
  $.register({
    rule: {
      host: /^bc\.vc$/,
      query: /^.+(https?:\/\/.+)/,
    },
    start: function (m) {
      $.openLink(m.query[1]);
    },
  });

  // bc.vc, shortcut
  // FIXME may cut hash or query string
  $.register({
    rule: {
      host: /^bc\.vc$/,
      path: /^.+(https?:\/\/.+)$/,
    },
    start: function (m) {
      $.openLink(m.path[1]);
    },
  });

  function decompress (script, unzip) {
    if (!unzip) {
      return script;
    }
    var matches = script.match(/eval(.*)/);
    matches = matches[1];
    script = eval(matches);
    return script;
  }

  function searchScript (unzip) {
    var content = $.$$('script').find(function (script) {
      if (script.innerHTML.indexOf('make_log') < 0) {
        return _.nop;
      }
      return script.innerHTML;
    });
    if (content) {
      return {
        direct: false,
        script: decompress(content.payload, unzip),
      };
    }
    content = $.$$('script').find(function (script) {
      if (script.innerHTML.indexOf('click_log') < 0) {
        return _.nop;
      }
      return script.innerHTML;
    });
    if (content) {
      return {
        direct: true,
        script: decompress(content.payload, unzip),
      };
    }
    throw _.AdsBypasserError('script changed');
  }

  function knockServer (script, dirtyFix) {
    var matches = script.match(/\$.post\('([^']*)'[^{]+(\{opt:'make_log'[^}]+\}\}),/i);
    var make_url = matches[1];
    var make_opts = eval('(' + matches[2] + ')');

    var i = setInterval(function () {
      $.post(make_url, make_opts, function (text) {
        if (dirtyFix) {
          // dirty fix for tr5.in
          text = text.match(/\{.+\}/)[0];
        }
        var jj = JSON.parse(text);
        if (jj.message) {
          clearInterval(i);
          $.openLink(jj.message.url);
        }
      });
    }, 1000);
  }

  function knockServer2 (script) {
    // somehow I must use jQuery AJAX
    var post = unsafeWindow.$.post;
    // mock a fake AJAX function
    unsafeWindow.$.post = $.inject(function (a, b, c) {
      if (typeof c !== 'function') {
        return;
      }
      setTimeout(function () {
        var data = {
          error: false,
          message: {
            url: '#',
          },
        };
        c(JSON.stringify(data));
      }, 1000);
    });

    var matches = script.match(/\$.post\('([^']*)'[^{]+(\{opt:'make_log'[^}]+\}\}),/i);
    var make_url = matches[1];
    var make_opts = eval('(' + matches[2] + ')');

    function makeLog () {
        make_opts.opt = 'make_log';
        post(make_url, $.inject(make_opts), $.inject(function (text) {
          var data = JSON.parse(text);
          _.info('make_log', data);
          if (!data.message) {
            checksLog();
            return;
          }

          $.openLink(data.message.url);
        }));
    }

    function checkLog () {
      make_opts.opt = 'check_log';
      post(make_url, $.inject(make_opts), $.inject(function (text) {
        var data = JSON.parse(text);
        _.info('check_log', data);
        if (!data.message) {
          checkLog();
          return;
        }

        makeLog();
      }));
    }

    function checksLog () {
      make_opts.opt = 'checks_log';
      post(make_url, $.inject(make_opts), $.inject(function () {
        _.info('checks_log');
        checkLog();
      }));
    }

    checksLog();
  }

  // bc.vc
  $.register({
    rule: {
      host: /^bc\.vc$/,
      path: /^\/.+/,
    },
    ready: function () {
      $.removeNodes('iframe');

      var result = searchScript(false);
      if (!result.direct) {
        knockServer2(result.script);
      } else {
        result = result.script.match(/top\.location\.href = '([^']+)'/);
        if (!result) {
          throw new _.AdsBypasserError('script changed');
        }
        result = result[1];
        $.openLink(result);
      }
    },
  });

  function run (dirtyFix) {
    // prevent redirection by iframe
    $.removeNodes('iframe');

    var result = searchScript(true);
    if (!result.direct) {
      knockServer(result.script,dirtyFix);
    } else {
      result = result.script.match(/top\.location\.href='([^']+)'/);
      if (!result) {
        throw new _.AdsBypasserError('script changed');
      }
      result = result[1];
      $.openLink(result);
    }
  }

  // adcrun.ch
  $.register({
    rule: {
      host: /^adcrun\.ch$/,
      path: /^\/\w+$/,
    },
    ready: function () {
      // Try to bypass the survey
      $.removeNodes('.user_content');

      var rSurveyLink = /http\.open\("GET", "api_ajax\.php\?sid=\d*&ip=[^&]*&longurl=([^"]+)" \+ first_time, (?:true|false)\);/;
      var l = $.searchScripts(rSurveyLink);
      // Redirect to the target link if we found it
      if (l) {
        $.openLink(l[1]);
        return;
      }

      // Otherwise it's most likely a simple bc.vc-like link
      // Malformed JSON
      run(true);
    },
  });

  $.register({
    rule: {
      host: [
        /^1tk\.us$/,
        /^gx\.si$/,
        /^adwat\.ch$/,
        /^(fly2url|urlwiz|xafox)\.com$/,
        /^(zpoz|ultry)\.net$/,
        /^(wwy|myam)\.me$/,
        /^ssl\.gs$/,
        /^link\.tl$/,
        /^hit\.us$/,
        /^shortit\.in$/,
        /^(adbla|tl7)\.us$/,
        /^www\.adjet\.eu$/,
        /^srk\.gs$/,
        /^cun\.bz$/,
        /^miniurl\.tk$/,
      ],
      path: /^\/.+/,
    },
    ready: run,
  });

  $.register({
    rule: {
      host: /^adtr\.im|ysear\.ch|xip\.ir$/,
      path: /^\/.+/,
    },
    ready: function () {
      var a = $.$('div.fly_head a.close');
      var f = $.$('iframe.fly_frame');
      // the iframe may be an ad link
      // so also check the close button
      if (a && f) {
        $.openLink(f.src);
      } else {
        run();
      }
    },
  });

  $.register({
    rule: {
      host: /^ad5\.eu$/,
      path: /^\/[^.]+$/,
    },
    ready: function() {
      $.removeNodes('iframe');
      var s = searchScript(true);

      // Find the form
      var m = s.script.match(/(<form name="form1"method="post".*(?!<\\form>)<\/form>)/);

      if (!m) {return;}

      m = m[1];

      // Set the correct timezone
      var tz = -(new Date().getTimezoneOffset()/60);
      m = m.replace("'+timezone+'",tz);

      // Wrap the form into a useless div
      var d = document.createElement('div');
      d.setAttribute('id','AdsBypasserFTW');
      d.setAttribute('style', 'display:none;');

      // Feed with the right form
      d.innerHTML = m;
      document.body.appendChild(d);

      // Redirect to next page
      $('#AdsBypasserFTW > form[name=form1]').submit();
    },
  });

  $.register({
    rule: {
      host: /^tr5\.in$/,
      path: /^\/.+/,
    },
    ready: function () {
      // Malformed JSON
      run(true);
    },
  });

})();

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<commit_msg>Fix bc.vc shortcut<commit_after>(function () {
  'use strict';

  // bc.vc, shortcut
  $.register({
    rule: {
      host: /^bc\.vc$/,
      path: /^.+(https?:\/\/.+)$/,
    },
    start: function (m) {
      $.openLink(m.path[1] + document.location.search + document.location.hash);
    },
  });

  function decompress (script, unzip) {
    if (!unzip) {
      return script;
    }
    var matches = script.match(/eval(.*)/);
    matches = matches[1];
    script = eval(matches);
    return script;
  }

  function searchScript (unzip) {
    var content = $.$$('script').find(function (script) {
      if (script.innerHTML.indexOf('make_log') < 0) {
        return _.nop;
      }
      return script.innerHTML;
    });
    if (content) {
      return {
        direct: false,
        script: decompress(content.payload, unzip),
      };
    }
    content = $.$$('script').find(function (script) {
      if (script.innerHTML.indexOf('click_log') < 0) {
        return _.nop;
      }
      return script.innerHTML;
    });
    if (content) {
      return {
        direct: true,
        script: decompress(content.payload, unzip),
      };
    }
    throw _.AdsBypasserError('script changed');
  }

  function knockServer (script, dirtyFix) {
    var matches = script.match(/\$.post\('([^']*)'[^{]+(\{opt:'make_log'[^}]+\}\}),/i);
    var make_url = matches[1];
    var make_opts = eval('(' + matches[2] + ')');

    var i = setInterval(function () {
      $.post(make_url, make_opts, function (text) {
        if (dirtyFix) {
          // dirty fix for tr5.in
          text = text.match(/\{.+\}/)[0];
        }
        var jj = JSON.parse(text);
        if (jj.message) {
          clearInterval(i);
          $.openLink(jj.message.url);
        }
      });
    }, 1000);
  }

  function knockServer2 (script) {
    // somehow I must use jQuery AJAX
    var post = unsafeWindow.$.post;
    // mock a fake AJAX function
    unsafeWindow.$.post = $.inject(function (a, b, c) {
      if (typeof c !== 'function') {
        return;
      }
      setTimeout(function () {
        var data = {
          error: false,
          message: {
            url: '#',
          },
        };
        c(JSON.stringify(data));
      }, 1000);
    });

    var matches = script.match(/\$.post\('([^']*)'[^{]+(\{opt:'make_log'[^}]+\}\}),/i);
    var make_url = matches[1];
    var make_opts = eval('(' + matches[2] + ')');

    function makeLog () {
        make_opts.opt = 'make_log';
        post(make_url, $.inject(make_opts), $.inject(function (text) {
          var data = JSON.parse(text);
          _.info('make_log', data);
          if (!data.message) {
            checksLog();
            return;
          }

          $.openLink(data.message.url);
        }));
    }

    function checkLog () {
      make_opts.opt = 'check_log';
      post(make_url, $.inject(make_opts), $.inject(function (text) {
        var data = JSON.parse(text);
        _.info('check_log', data);
        if (!data.message) {
          checkLog();
          return;
        }

        makeLog();
      }));
    }

    function checksLog () {
      make_opts.opt = 'checks_log';
      post(make_url, $.inject(make_opts), $.inject(function () {
        _.info('checks_log');
        checkLog();
      }));
    }

    checksLog();
  }

  // bc.vc
  $.register({
    rule: {
      host: /^bc\.vc$/,
      path: /^\/.+/,
    },
    ready: function () {
      $.removeNodes('iframe');

      var result = searchScript(false);
      if (!result.direct) {
        knockServer2(result.script);
      } else {
        result = result.script.match(/top\.location\.href = '([^']+)'/);
        if (!result) {
          throw new _.AdsBypasserError('script changed');
        }
        result = result[1];
        $.openLink(result);
      }
    },
  });

  function run (dirtyFix) {
    // prevent redirection by iframe
    $.removeNodes('iframe');

    var result = searchScript(true);
    if (!result.direct) {
      knockServer(result.script,dirtyFix);
    } else {
      result = result.script.match(/top\.location\.href='([^']+)'/);
      if (!result) {
        throw new _.AdsBypasserError('script changed');
      }
      result = result[1];
      $.openLink(result);
    }
  }

  // adcrun.ch
  $.register({
    rule: {
      host: /^adcrun\.ch$/,
      path: /^\/\w+$/,
    },
    ready: function () {
      // Try to bypass the survey
      $.removeNodes('.user_content');

      var rSurveyLink = /http\.open\("GET", "api_ajax\.php\?sid=\d*&ip=[^&]*&longurl=([^"]+)" \+ first_time, (?:true|false)\);/;
      var l = $.searchScripts(rSurveyLink);
      // Redirect to the target link if we found it
      if (l) {
        $.openLink(l[1]);
        return;
      }

      // Otherwise it's most likely a simple bc.vc-like link
      // Malformed JSON
      run(true);
    },
  });

  $.register({
    rule: {
      host: [
        /^1tk\.us$/,
        /^gx\.si$/,
        /^adwat\.ch$/,
        /^(fly2url|urlwiz|xafox)\.com$/,
        /^(zpoz|ultry)\.net$/,
        /^(wwy|myam)\.me$/,
        /^ssl\.gs$/,
        /^link\.tl$/,
        /^hit\.us$/,
        /^shortit\.in$/,
        /^(adbla|tl7)\.us$/,
        /^www\.adjet\.eu$/,
        /^srk\.gs$/,
        /^cun\.bz$/,
        /^miniurl\.tk$/,
      ],
      path: /^\/.+/,
    },
    ready: run,
  });

  $.register({
    rule: {
      host: /^adtr\.im|ysear\.ch|xip\.ir$/,
      path: /^\/.+/,
    },
    ready: function () {
      var a = $.$('div.fly_head a.close');
      var f = $.$('iframe.fly_frame');
      // the iframe may be an ad link
      // so also check the close button
      if (a && f) {
        $.openLink(f.src);
      } else {
        run();
      }
    },
  });

  $.register({
    rule: {
      host: /^ad5\.eu$/,
      path: /^\/[^.]+$/,
    },
    ready: function() {
      $.removeNodes('iframe');
      var s = searchScript(true);

      // Find the form
      var m = s.script.match(/(<form name="form1"method="post".*(?!<\\form>)<\/form>)/);

      if (!m) {return;}

      m = m[1];

      // Set the correct timezone
      var tz = -(new Date().getTimezoneOffset()/60);
      m = m.replace("'+timezone+'",tz);

      // Wrap the form into a useless div
      var d = document.createElement('div');
      d.setAttribute('id','AdsBypasserFTW');
      d.setAttribute('style', 'display:none;');

      // Feed with the right form
      d.innerHTML = m;
      document.body.appendChild(d);

      // Redirect to next page
      $('#AdsBypasserFTW > form[name=form1]').submit();
    },
  });

  $.register({
    rule: {
      host: /^tr5\.in$/,
      path: /^\/.+/,
    },
    ready: function () {
      // Malformed JSON
      run(true);
    },
  });

})();

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<|endoftext|>


<commit_before>import React from 'react'
import {render} from 'react-dom'
import {Router, browserHistory} from 'react-router'
import 'whatwg-fetch'

import routes from './routes'

render(
  <Router history={browserHistory} routes={routes} />,
  document.body.appendChild(document.createElement('div'))
)

<commit_msg>fix height<commit_after>import React from 'react'
import {render} from 'react-dom'
import {Router, browserHistory} from 'react-router'
import 'whatwg-fetch'

import routes from './routes'

const container = document.createElement('div')
container.style.height = '100%'

render(
  <Router history={browserHistory} routes={routes} />,
  document.body.appendChild(container)
)

<|endoftext|>


<commit_before>function HttpRouter(types) {
	this.types = types;
	this.exact = {};
	this.re = [];
}

module.exports = HttpRouter;

HttpRouter.prototype.get = function (path) {
	if (!path) {
		return;
	}

	if (path.substr(-1) === '/') {
		path = path.slice(0, -1);	// drop last slash
	}

	// find a handler that was registered to this exact route

	var route = this.exact[path];
	if (route) {
		return route;
	}

	// if no exact route handler found, try the regexp registered routes

	for (var i = 0, len = this.re.length; i < len; i++) {
		if (path.match(this.re[i].matcher)) {
			return this.re[i];
		}
	}
};

HttpRouter.prototype.add = function (pathMatch, fn, type) {
	if (this.types.indexOf(type) === -1) {
		throw new Error('Route type must be of ' + this.types.join(', ') + '. Instead received: ' + type);
	}

	if (typeof fn !== 'function') {
		throw new TypeError('Route handler must be a function');
	}

	// pathMatch is a regexp or string to match on
	// register it as the route

	if (typeof pathMatch === 'string') {
		// add a starting slash

		if (pathMatch[0] !== '/') {
			pathMatch = '/' + pathMatch;
		}

		// strip the final slash

		if (pathMatch.substr(-1) === '/') {
			pathMatch = pathMatch.slice(0, -1);
		}

		this.exact[pathMatch] = { matcher: pathMatch, handler: fn, type: type };
	} else if (pathMatch instanceof RegExp) {
		// remove it if it already exists

		this.del(pathMatch);

		// register the route

		this.re.push({ matcher: pathMatch, handler: fn, type: type });
	} else {
		throw new TypeError('Invalid path matcher: ' + pathMatch);
	}
};

HttpRouter.prototype.del = function (pathMatch) {
	if (typeof pathMatch === 'string') {
		// add a starting slash

		if (pathMatch[0] !== '/') {
			pathMatch = '/' + pathMatch;
		}

		// strip the final slash

		if (pathMatch.substr(-1) === '/') {
			pathMatch = pathMatch.slice(0, -1);
		}

		delete this.exact[pathMatch];
	} else if (pathMatch instanceof RegExp) {
		pathMatch = '' + pathMatch;

		this.re = this.re.filter(function (re) {
			return '' + re.matcher !== pathMatch;
		});
	} else {
		throw new TypeError('Invalid path matcher: ' + pathMatch);
	}
};
<commit_msg>Additional slashes in a path are cleaned up<commit_after>const resolve = require('path').posix.resolve;

function HttpRouter(types) {
	this.types = types;
	this.exact = {};
	this.re = [];
}

module.exports = HttpRouter;

HttpRouter.prototype.get = function (path) {
	if (!path) {
		return;
	}

	// Clean up the received path

	path = resolve(path);

	// find a handler that was registered to this exact route

	var route = this.exact[path];
	if (route) {
		return route;
	}

	// if no exact route handler found, try the regexp registered routes

	for (var i = 0, len = this.re.length; i < len; i++) {
		if (path.match(this.re[i].matcher)) {
			return this.re[i];
		}
	}
};

HttpRouter.prototype.add = function (pathMatch, fn, type) {
	if (this.types.indexOf(type) === -1) {
		throw new Error('Route type must be of ' + this.types.join(', ') + '. Instead received: ' + type);
	}

	if (typeof fn !== 'function') {
		throw new TypeError('Route handler must be a function');
	}

	// pathMatch is a regexp or string to match on
	// register it as the route

	if (typeof pathMatch === 'string') {
		// add a starting slash

		if (pathMatch[0] !== '/') {
			pathMatch = '/' + pathMatch;
		}

		// strip the final slash

		if (pathMatch.substr(-1) === '/') {
			pathMatch = pathMatch.slice(0, -1);
		}

		this.exact[pathMatch] = { matcher: pathMatch, handler: fn, type: type };
	} else if (pathMatch instanceof RegExp) {
		// remove it if it already exists

		this.del(pathMatch);

		// register the route

		this.re.push({ matcher: pathMatch, handler: fn, type: type });
	} else {
		throw new TypeError('Invalid path matcher: ' + pathMatch);
	}
};

HttpRouter.prototype.del = function (pathMatch) {
	if (typeof pathMatch === 'string') {
		// add a starting slash

		if (pathMatch[0] !== '/') {
			pathMatch = '/' + pathMatch;
		}

		// strip the final slash

		if (pathMatch.substr(-1) === '/') {
			pathMatch = pathMatch.slice(0, -1);
		}

		delete this.exact[pathMatch];
	} else if (pathMatch instanceof RegExp) {
		pathMatch = '' + pathMatch;

		this.re = this.re.filter(function (re) {
			return '' + re.matcher !== pathMatch;
		});
	} else {
		throw new TypeError('Invalid path matcher: ' + pathMatch);
	}
};
<|endoftext|>


<commit_before>/**
 * THIS IS THE ENTRY POINT FOR THE CLIENT, JUST LIKE server.js IS THE ENTRY POINT FOR THE SERVER.
 */
import 'babel/polyfill'
import React from 'react'
import BrowserHistory from 'react-router/lib/BrowserHistory'
import Location from 'react-router/lib/Location'
import queryString from 'query-string'
import createStore from './redux/create'
import ApiClient from './helpers/ApiClient'
import universalRouter from './helpers/universalRouter'
const history = new BrowserHistory()
const client = new ApiClient()

const dest = document.getElementById('content')
const store = createStore(client, window.__data)
const search = document.location.search
const query = search && queryString.parse(search)
const location = new Location(document.location.pathname, query)
universalRouter(location, history, store)
  .then(({ component }) => {
    if (__DEVTOOLS__) {
      const { DevTools, DebugPanel, LogMonitor } = require('redux-devtools/lib/react')
      console.info('You will see a "Warning: React attempted to reuse markup in a container but the checksum was' +
        ' invalid." message. That\'s because the redux-devtools are enabled.')
      React.render(

        {component}
        <DebugPanel top right bottom key="debugPanel">
          <DevTools store={store} monitor={LogMonitor}/>
        </DebugPanel>

, dest)
    } else {
      React.render(component, dest)
    }
  }, (error) => {
    console.error(error)
  })

if (process.env.NODE_ENV !== 'production') {
  window.React = React // enable debugger
  const reactRoot = window.document.getElementById('content')

  if (!reactRoot || !reactRoot.firstChild || !reactRoot.firstChild.attributes || !reactRoot.firstChild.attributes['data-react-checksum']) {
    console.error('Server-side React render was discarded. Make sure that your initial render does not contain any client-side code.')
  }
}
<commit_msg>add new branch demo1<commit_after>/**
 * THIS IS THE ENTRY POINT FOR THE CLIENT, JUST LIKE server.js IS THE ENTRY POINT FOR THE SERVER.
 */
import 'babel/polyfill'
import React from 'react'
import BrowserHistory from 'react-router/lib/BrowserHistory'
import Location from 'react-router/lib/Location'
import queryString from 'query-string'
import createStore from './redux/create'
import ApiClient from './helpers/ApiClient'
import universalRouter from './helpers/universalRouter'
const history = new BrowserHistory()
const client = new ApiClient()

const dest = document.getElementById('content')
const store = createStore(client, window.__data)
const search = document.location.search
const query = search && queryString.parse(search)
const location = new Location(document.location.pathname, query)
universalRouter(location, history, store)
  .then(({ component }) => {
    if (__DEVTOOLS__) {
      const { DevTools, DebugPanel, LogMonitor } = require('redux-devtools/lib/react')
      console.info('You will see a "Warning: React attempted to reuse markup in a container but the checksum was' +
        ' invalid." message. That\'s because the redux-devtools are enabled.')
      React.render(

        {component}

, dest)
    } else {
      React.render(component, dest)
    }
  }, (error) => {
    console.error(error)
  })

if (process.env.NODE_ENV !== 'production') {
  window.React = React // enable debugger
  const reactRoot = window.document.getElementById('content')

  if (!reactRoot || !reactRoot.firstChild || !reactRoot.firstChild.attributes || !reactRoot.firstChild.attributes['data-react-checksum']) {
    console.error('Server-side React render was discarded. Make sure that your initial render does not contain any client-side code.')
  }
}
<|endoftext|>


<commit_before>//FORM-OCTO-WOOKIE!!
/*REQUIRE:
any addEventListener polyfill
*/
(function(window,und){
	var doc = window.document;
	var fpref = 'form-octo-wookie_';

	/* helpers */
	function ext(){
		var i,j,arg = arguments;
		for(i = 1; i < arg.length; i++){
			for(var j in arg[i])if(arg[i].hasOwnProperty(j)){ arg[0][j] = arg[i][j]; }
		}
	}
	var isCtrl = false, isShift = false;
	doc.addEventListener('keyup',function(e){
		var keyCode = ('which' in e) ? e.which : e.keyCode;
		if(keyCode == 17){ isCtrl = false; }
		if(keyCode == 16){ isShift = false; }
	});
	doc.addEventListener('keydown',function(e){
		var keyCode = ('which' in e) ? e.which : e.keyCode;
		if(keyCode == 17){ isCtrl = true; }
		if(keyCode == 16){ isShift = true; }
	});
	/* helpers */

	function inp(){
		var opt,type,obj;
		if(typeof arguments[0] == 'object'){ opt = arguments[0]; }
		else{ opt = { type:arguments[0] }; }
		obj = new inp[opt.type](opt);
		// Добавить в глобальную базу объектов, на форму, еще кудато
		return obj;
	}
	var faces = {
		inp:{
			$inp:true
			, label:''
			, label_pos:'before'
			, hint:''
			, init:function(){
				this._dom();
				this._events();
			}
			, _dom:function(){
				var z = this;
				z.elem = doc.createElement('label');
				if(z.label){ z._addLabel(); }
				if(z.hint){ z._addHint(); }
				z._addInp();
				if(z.validate){ z._addMessage(); }
			}
			, _events:function(){/*events*/}
			, _addLabel:function(){
				var z = this;
				z.el_label = doc.createElement('div');
				z.el_label.className = fpref+'label';
				z.el_label.innerHTML = z.label;
				z.elem.appendChild(z.el_label);
			}
			, _addHint:function(){
				var z = this;
				z.el_hint = doc.createElement('div');
				z.el_hint.className = fpref+'hint';
				z.el_hint.innerHTML = z.hint;
				z.elem.appendChild(z.el_hint);
			}
			, _addMessage:function(){}
			, _addInp:function(){/* сам инпут */ throw('call virtual method _addInp');}
			, val:function(){
				var z = this;
				if(arguments.length){ return z._set.apply(this,arguments); }
				return z._get();
			}
			, _get:function(){ /* возврат значения */ throw('call virtual method _get'); }
			, _set:function(value){ /* установка значения */ throw('call virtual method _set'); }
		}
		, callbacks:{
			$callbacks:true
			, invoke:function(ev){
				var z = this,i;
				if(!z.callbacks){ z.callbacks = {}; }
				if(!z.callbacks[ev]){ return; }
				for( i = 0; i < z.callbacks.length; i++)if(z.callbacks[i]){
					z.callbacks[i].fn.call(z.callbacks[i].context || z);
				}
			}
			, addListener:function(ev,fn,ct){
				var z = this;
				if(!z.callbacks){ z.callbacks = {}; }
				if(!z.callbacks[ev]){ z.callbacks[ev] = []; }
				z.callbacks[ev].push({
					event:ev
					, func:fn
					, context:ct
				});
			}
			, removeListener:function(ev,fn){
				var z = this,i;
				if(!z.callbacks){ z.callbacks = {}; }
				if(!z.callbacks[ev]){return;}
				for(i = 0; i < z.callbacks.length; i++)if(z.callbacks[i]){
					if(fn){ if(z.callbacks[i].fn === fn){ z.callbacks[i] = null; } }
					else{ z.callbacks[i] = null; }
				}
			}
			, pauseListener:function(ev,fn){}
			, playListener:function(ev,fn){}
		}
		, sequence:{
			$sequence:true
			, next:function(){/* следующее значение */ throw('call virtual method next');}
			, prev:function(){/* предыдущее значение */ throw('call virtual method prev');}
		}
	};
	inp.text = function(opt){ ext(this,opt); this.init(); }
	ext(inp.text.prototype
		, faces.inp
		, faces.callbacks
		, {
			_addInp:function(){
				var z = this;
				z.inp = doc.createElement('input');
				z.inp.type = 'text';
				z.inp.name = z.name;
				z.inpWrap = doc.createElement('div');
				z.inpWrap.appendChild(z.inp);
				z.elem.appendChild(z.inpWrap);
				// добавить свистелки и свистульки
			}
			, _get:function(){ var z = this; return z.inp.value; }
			, _set:function(val){ var z = this; z.inp.value = val; }
		}
	);
//var keyCode = ('which' in event) ? event.which : event.keyCode;
	inp.number = function(opt){ ext(this,opt); this.init(); }
	ext(inp.number.prototype
		, faces.inp
		, faces.callbacks
		, faces.sequence
		, {
			_addInp:function(){
				var z = this;
				z.inp = doc.createElement('input');
				z.inp.type = 'text';
				z.inp.name = z.name;
				z.inpWrap = doc.createElement('div');
				z.inpWrap.appendChild(z.inp);
				z.elem.appendChild(z.inpWrap);
				// добавить свистелки и свистульки
			}
			, _get:function(){ var z = this; return z.inp.value; }
			, _set:function(val){ var z = this; z.inp.value = val; }
			, _events:function(){
				console.info('add events');
				var z = this;
				z.inp.addEventListener('keydown',function(e){
					var keyCode = ('which' in e) ? e.which : e.keyCode;
					console.info('inp event',keyCode);
					if(
						( ~[46, 8, 9, 27, 13, 110, 190].indexOf(keyCode) )
						|| ( keyCode == 65 && isCtrl )
						|| ( keyCode == 67 && isCtrl )
						|| ( keyCode == 88 && isCtrl )
						|| ( keyCode > 34 && keyCode < 40 )
					){ return; }
					if((isShift || (keyCode < 48 || keyCode > 57)) && (keyCode < 96 || keyCode > 105)){ e.preventDefault(); }
				});
			}
			, next:function(){
				var z = this,val;
				val = parseFloat(z._get());
				val++;
				z._set(val);
				return val;
			}
			, prev:function(){
				var z = this,val;
				val = parseFloat(z._get());
				val--;
				z._set(val);
				return val;
			}
		}
	);

	window.fow = inp;
})(window);
<commit_msg>check event values<commit_after>//FORM-OCTO-WOOKIE!!
/*REQUIRE:
any addEventListener polyfill
*/
(function(window,und){
	var doc = window.document;
	var fpref = 'form-octo-wookie_';

	/* helpers */
	function ext(){
		var i,j,arg = arguments;
		for(i = 1; i < arg.length; i++){
			for(var j in arg[i])if(arg[i].hasOwnProperty(j)){ arg[0][j] = arg[i][j]; }
		}
	}
	var isCtrl = false, isShift = false;
	doc.addEventListener('keyup',function(e){
		var keyCode = ('which' in e) ? e.which : e.keyCode;
		if(keyCode == 17){ isCtrl = false; }
		if(keyCode == 16){ isShift = false; }
	});
	doc.addEventListener('keydown',function(e){
		var keyCode = ('which' in e) ? e.which : e.keyCode;
		if(keyCode == 17){ isCtrl = true; }
		if(keyCode == 16){ isShift = true; }
	});
	/* helpers */

	function inp(){
		var opt,type,obj;
		if(typeof arguments[0] == 'object'){ opt = arguments[0]; }
		else{ opt = { type:arguments[0] }; }
		obj = new inp[opt.type](opt);
		// Добавить в глобальную базу объектов, на форму, еще кудато
		return obj;
	}
	var faces = {
		inp:{
			$inp:true
			, label:''
			, label_pos:'before'
			, hint:''
			, init:function(){
				this._dom();
				this._events();
			}
			, _dom:function(){
				var z = this;
				z.elem = doc.createElement('label');
				if(z.label){ z._addLabel(); }
				if(z.hint){ z._addHint(); }
				z._addInp();
				if(z.validate){ z._addMessage(); }
			}
			, _events:function(){/*events*/}
			, _addLabel:function(){
				var z = this;
				z.el_label = doc.createElement('div');
				z.el_label.className = fpref+'label';
				z.el_label.innerHTML = z.label;
				z.elem.appendChild(z.el_label);
			}
			, _addHint:function(){
				var z = this;
				z.el_hint = doc.createElement('div');
				z.el_hint.className = fpref+'hint';
				z.el_hint.innerHTML = z.hint;
				z.elem.appendChild(z.el_hint);
			}
			, _addMessage:function(){}
			, _addInp:function(){/* сам инпут */ throw('call virtual method _addInp');}
			, val:function(){
				var z = this;
				if(arguments.length){ return z._set.apply(this,arguments); }
				return z._get();
			}
			, _get:function(){ /* возврат значения */ throw('call virtual method _get'); }
			, _set:function(value){ /* установка значения */ throw('call virtual method _set'); }
		}
		, callbacks:{
			$callbacks:true
			, invoke:function(ev){
				var z = this,i;
				if(!z.callbacks){ z.callbacks = {}; }
				if(!z.callbacks[ev]){ return; }
				for( i = 0; i < z.callbacks.length; i++)if(z.callbacks[i]){
					z.callbacks[i].fn.call(z.callbacks[i].context || z);
				}
			}
			, addListener:function(ev,fn,ct){
				var z = this;
				if(!z.callbacks){ z.callbacks = {}; }
				if(!z.callbacks[ev]){ z.callbacks[ev] = []; }
				z.callbacks[ev].push({
					event:ev
					, func:fn
					, context:ct
				});
			}
			, removeListener:function(ev,fn){
				var z = this,i;
				if(!z.callbacks){ z.callbacks = {}; }
				if(!z.callbacks[ev]){return;}
				for(i = 0; i < z.callbacks.length; i++)if(z.callbacks[i]){
					if(fn){ if(z.callbacks[i].fn === fn){ z.callbacks[i] = null; } }
					else{ z.callbacks[i] = null; }
				}
			}
			, pauseListener:function(ev,fn){}
			, playListener:function(ev,fn){}
		}
		, sequence:{
			$sequence:true
			, next:function(){/* следующее значение */ throw('call virtual method next');}
			, prev:function(){/* предыдущее значение */ throw('call virtual method prev');}
		}
	};
	inp.text = function(opt){ ext(this,opt); this.init(); }
	ext(inp.text.prototype
		, faces.inp
		, faces.callbacks
		, {
			_addInp:function(){
				var z = this;
				z.inp = doc.createElement('input');
				z.inp.type = 'text';
				z.inp.name = z.name;
				z.inpWrap = doc.createElement('div');
				z.inpWrap.appendChild(z.inp);
				z.elem.appendChild(z.inpWrap);
				// добавить свистелки и свистульки
			}
			, _get:function(){ var z = this; return z.inp.value; }
			, _set:function(val){ var z = this; z.inp.value = val; }
		}
	);
//var keyCode = ('which' in event) ? event.which : event.keyCode;
	inp.number = function(opt){ ext(this,opt); this.init(); }
	ext(inp.number.prototype
		, faces.inp
		, faces.callbacks
		, faces.sequence
		, {
			_addInp:function(){
				var z = this;
				z.inp = doc.createElement('input');
				z.inp.type = 'text';
				z.inp.name = z.name;
				z.inpWrap = doc.createElement('div');
				z.inpWrap.appendChild(z.inp);
				z.elem.appendChild(z.inpWrap);
				// добавить свистелки и свистульки
			}
			, _get:function(){ var z = this; return z.inp.value; }
			, _set:function(val){ var z = this; z.inp.value = val; }
			, _events:function(){
				console.info('add events');
				var z = this;
				z.inp.addEventListener('keydown',function(e){
					var keyCode = ('which' in e) ? e.which : e.keyCode;
					console.info('inp event',keyCode);
					if(
						( ~[46, 8, 9, 27, 13, 110, 190].indexOf(keyCode) )
						|| ( keyCode == 65 && isCtrl )
						|| ( keyCode == 67 && isCtrl )
						|| ( keyCode == 88 && isCtrl )
						|| ( keyCode > 34 && keyCode < 40 )
					){ return; }
					if( keyCode == 86 && isCtrl ){ /* разрешить вставку, но удалить все не цифры */
						console.info(z.inp.value);
					}
					if((isShift || (keyCode < 48 || keyCode > 57)) && (keyCode < 96 || keyCode > 105)){ e.preventDefault(); }
				});
			}
			, next:function(){
				var z = this,val;
				val = parseFloat(z._get());
				val++;
				z._set(val);
				return val;
			}
			, prev:function(){
				var z = this,val;
				val = parseFloat(z._get());
				val--;
				z._set(val);
				return val;
			}
		}
	);

	window.fow = inp;
})(window);
<|endoftext|>


<commit_before>import 'dom-shims/shim/CustomEvent';
import 'dom-shims/shim/Element.mutation';
import 'es6-shim';
import es7 from 'es7-shim';

import { EventEmitter } from 'events';
import { FastClick } from 'fastclick';
import { request } from 'https';
import get from 'lodash-es/get';

import {
  HttpConnection,
  PubSub,
  WsConnection,
  load as loadApi
} from '@scola/api';

import {
  Auth,
  setUser,
  logIn,
  logOut,
  load as loadAuth
} from '@scola/auth-client';

import {
  cache as cacheFactory,
  i18n as i18nFactory,
  router as routerFactory,
  main as mainFactory,
  menu as menuFactory,
  model as modelFactory
} from '@scola/d3';

import { ScolaError } from '@scola/error';
import { load as loadValidator } from '@scola/validator';
import Route from './route';

export default class Client extends EventEmitter {
  constructor() {
    super();

    this._auth = null;
    this._config = null;
    this._http = null;
    this._i18n = null;
    this._pubsub = null;
    this._router = null;
    this._storage = null;
    this._user = null;
    this._ws = null;

    this._mainModifier = null;
    this._menuModifiers = new Map();

    this._state = {
      auth: false,
      open: false
    };

    this._fastClick = FastClick.attach(document.body);

    this._handleClose = () => this._close();
    this._handleError = (e) => this._error(e);
    this._handleMain = (t) => this._main(t);
    this._handleMenu = (t) => this._menu(t);
    this._handleOnline = () => this._online();
    this._handleOpen = (e) => this._open(e);
    this._handleSetAuth = (e) => this._setAuth(e);
  }

  destroy() {
    this._fastClick.destroy();

    this._unbindAuth();
    this._unbindRouter();
    this._unbindWs();
  }

  state(name, value = null) {
    if (value === null) {
      return typeof this._state[name] === 'undefined' ?
        null : this._state[name];
    }

    this._state[name] = value;
    this.emit(name, value);

    return this;
  }

  auth(options = null) {
    if (options === null) {
      return this._auth;
    }

    const model = modelFactory(options.name, true)
      .connection(this._ws || this._http)
      .serialize((d) => this._serializeAuth(d));

    const cache = cacheFactory()
      .model(model);

    this._auth = new Auth()
      .cache(cache);

    this._bindAuth();
    return this;
  }

  config(value = null) {
    if (value === null) {
      return this._config;
    }

    if (typeof value === 'string') {
      return get(this._config, value);
    }

    this._config = value;
    return this;
  }

  error(message) {
    return new ScolaError(message);
  }

  http(options = null) {
    if (options === null) {
      return this._http;
    }

    this._http = new HttpConnection()
      .http({ request })
      .codec(options.codec)
      .host(options.host)
      .port(options.port);

    return this;
  }

  i18n(options = null) {
    if (options === null) {
      return this._i18n;
    }

    this._i18n = i18nFactory()
      .locale(options.locale)
      .timezone(options.timezone);

    return this;
  }

  main(modifier = (e) => e.size()) {
    this._mainModifier = modifier;
    this._router.target('main').render(this._handleMain);

    return this;
  }

  menu(name, modifier = (e) => e.size()) {
    this._menuModifiers.set(name, modifier);
    this._router.target(name).render(this._handleMenu);

    return this;
  }

  pubsub(options = null) {
    if (this._pubsub === null) {
      this._pubsub = new PubSub();
    }

    if (options === null) {
      return this._pubsub;
    }

    if (options === true) {
      this._pubsub.connection(this._ws);
      return this;
    }

    options.factory = (u, p) => {
      return new WebSocket(u, p);
    };

    const connection = new WsConnection()
      .codec(options.codec)
      .reconnector(options);

    this._pubsub.connection(connection);
    return this;
  }

  route() {
    return new Route()
      .client(this);
  }

  router(options = null) {
    if (options === null) {
      return this._router;
    }

    const model = modelFactory(options.name, true);
    this._router = routerFactory().model(model);

    this._bindRouter();
    return this;
  }

  storage(value = null) {
    if (value === null) {
      return this._storage;
    }

    this._storage = value;
    return this;
  }

  user(value = null) {
    if (value === null) {
      return this._user;
    }

    this._user = value === false ?
      null : value;

    if (this._ws) {
      this._ws.user(value);
    }

    if (this._http) {
      this._http.user(value);
    }

    if (this._router) {
      this._router.user(value);
    }

    return this;
  }

  ws(options = null) {
    if (options === null) {
      return this._ws;
    }

    options.factory = (u, p) => {
      return new WebSocket(u, p);
    };

    this._ws = new WsConnection()
      .codec(options.codec)
      .reconnector(options);

    this._bindWs();
    return this;
  }

  start() {
    es7.shim();

    loadApi(this);
    loadValidator(this);

    if (this._pubsub) {
      this._pubsub.open();
    }

    if (this._auth === null) {
      this._popState();
      return this;
    }

    loadAuth(this);
    setUser(this, () => this._popState());

    return this;
  }

  _bindAuth() {
    if (this._auth) {
      this.on('auth', this._handleSetAuth);
    }
  }

  _unbindAuth() {
    if (this._auth) {
      this.removeListener('auth', this._handleSetAuth);
    }
  }

  _bindRouter() {
    if (this._router) {
      this._router.on('error', this._handleError);
    }
  }

  _unbindRouter() {
    if (this._router) {
      this._router.removeListener('error', this._handleError);
    }
  }

  _bindWs() {
    if (this._ws) {
      window.addEventListener('online', this._handleOnline);
      this._ws.on('close', this._handleClose);
      this._ws.on('error', this._handleError);
      this._ws.on('open', this._handleOpen);
    }
  }

  _unbindWs() {
    if (this._ws) {
      window.removeEventListener('online', this._handleOnline);
      this._ws.removeListener('close', this._handleClose);
      this._ws.removeListener('error', this._handleError);
      this._ws.removeListener('open', this._handleOpen);
    }
  }

  _popState() {
    const filter = this._user === null ? ['scola.auth'] : null;

    this._router.popState(filter);

    if (this._ws) {
      if (window.navigator.onLine === true) {
        this._ws.open();
      }
    }
  }

  _setAuth(value) {
    if (value !== 'valid' && this._mainModifier) {
      this._router.target('main').destroy();
    }
  }

  _serializeAuth(data) {
    return {
      token: data.user.token
    };
  }

  _error(error) {
    if (error.status === 500) {
      return;
    }

    if (error.status === 401 || error.status === 403) {
      logOut(this);
      return;
    }

    this.emit('error', error);
  }

  _main(target) {
    let element = mainFactory()
      .mode('over');

    element = this._mainModifier(element);
    const menus = Array.from(this._menuModifiers.keys());

    menus.forEach((name) => {
      const menu = target
        .router()
        .target(name)
        .element();

      if (menu !== null) {
        element.append(menu);
      }
    });

    document.body.appendChild(element.root().node());
    element.show(true);

    target
      .element(element)
      .once('destroy', () => {
        element.show(false).on('end', () => {
          element.destroy();
          target.routes(false);

          menus.forEach((name) => {
            target
              .router()
              .target(name)
              .destroy();
          });
        });
      });
  }

  _menu(target) {
    const modifier = this._menuModifiers.get(target.name());

    let element = menuFactory()
      .position('left');

    element = modifier(element);

    const main = target
      .router()
      .target('main')
      .element();

    if (main !== null) {
      main.append(element);
    }

    target
      .element(element)
      .once('destroy', () => {
        element.destroy();
        target.routes(false);
      });
  }

  _close() {
    this.state('open', false);
  }

  _online() {
    if (this._ws) {
      this._ws.open();
    }
  }

  _open() {
    this.state('open', true);

    if (this._auth) {
      logIn(this);
    }
  }
}
<commit_msg>Increase max listeners on eventemitters<commit_after>import 'dom-shims/shim/CustomEvent';
import 'dom-shims/shim/Element.mutation';
import 'es6-shim';
import es7 from 'es7-shim';

import { EventEmitter } from 'events';
import { FastClick } from 'fastclick';
import { request } from 'https';
import get from 'lodash-es/get';

import {
  HttpConnection,
  PubSub,
  WsConnection,
  load as loadApi
} from '@scola/api';

import {
  Auth,
  setUser,
  logIn,
  logOut,
  load as loadAuth
} from '@scola/auth-client';

import {
  cache as cacheFactory,
  i18n as i18nFactory,
  router as routerFactory,
  main as mainFactory,
  menu as menuFactory,
  model as modelFactory
} from '@scola/d3';

import { ScolaError } from '@scola/error';
import { load as loadValidator } from '@scola/validator';
import Route from './route';

export default class Client extends EventEmitter {
  constructor() {
    super();

    this._auth = null;
    this._config = null;
    this._http = null;
    this._i18n = null;
    this._pubsub = null;
    this._router = null;
    this._storage = null;
    this._user = null;
    this._ws = null;

    this._mainModifier = null;
    this._menuModifiers = new Map();

    this._state = {
      auth: false,
      open: false
    };

    this._fastClick = FastClick.attach(document.body);

    this._handleClose = () => this._close();
    this._handleError = (e) => this._error(e);
    this._handleMain = (t) => this._main(t);
    this._handleMenu = (t) => this._menu(t);
    this._handleOnline = () => this._online();
    this._handleOpen = (e) => this._open(e);
    this._handleSetAuth = (e) => this._setAuth(e);
  }

  destroy() {
    this._fastClick.destroy();

    this._unbindAuth();
    this._unbindRouter();
    this._unbindWs();
  }

  state(name, value = null) {
    if (value === null) {
      return typeof this._state[name] === 'undefined' ?
        null : this._state[name];
    }

    this._state[name] = value;
    this.emit(name, value);

    return this;
  }

  auth(options = null) {
    if (options === null) {
      return this._auth;
    }

    const model = modelFactory(options.name, true)
      .connection(this._ws || this._http)
      .serialize((d) => this._serializeAuth(d));

    const cache = cacheFactory()
      .model(model);

    this._auth = new Auth()
      .cache(cache);

    this._bindAuth();
    return this;
  }

  config(value = null) {
    if (value === null) {
      return this._config;
    }

    if (typeof value === 'string') {
      return get(this._config, value);
    }

    this._config = value;
    return this;
  }

  error(message) {
    return new ScolaError(message);
  }

  http(options = null) {
    if (options === null) {
      return this._http;
    }

    this._http = new HttpConnection()
      .http({ request })
      .codec(options.codec)
      .host(options.host)
      .port(options.port);

    return this;
  }

  i18n(options = null) {
    if (options === null) {
      return this._i18n;
    }

    this._i18n = i18nFactory()
      .locale(options.locale)
      .timezone(options.timezone);

    return this;
  }

  main(modifier = (e) => e.size()) {
    this._mainModifier = modifier;
    this._router.target('main').render(this._handleMain);

    return this;
  }

  menu(name, modifier = (e) => e.size()) {
    this._menuModifiers.set(name, modifier);
    this._router.target(name).render(this._handleMenu);

    return this;
  }

  pubsub(options = null) {
    if (this._pubsub === null) {
      this._pubsub = new PubSub();
    }

    if (options === null) {
      return this._pubsub;
    }

    if (options === true) {
      this._pubsub.connection(this._ws);
      return this;
    }

    options.factory = (u, p) => {
      return new WebSocket(u, p);
    };

    const connection = new WsConnection()
      .codec(options.codec)
      .reconnector(options);

    this._pubsub.connection(connection);
    return this;
  }

  route() {
    return new Route()
      .client(this);
  }

  router(options = null) {
    if (options === null) {
      return this._router;
    }

    const model = modelFactory(options.name, true);
    this._router = routerFactory().model(model);

    this._bindRouter();
    return this;
  }

  storage(value = null) {
    if (value === null) {
      return this._storage;
    }

    this._storage = value;
    return this;
  }

  user(value = null) {
    if (value === null) {
      return this._user;
    }

    this._user = value === false ?
      null : value;

    if (this._ws) {
      this._ws.user(value);
    }

    if (this._http) {
      this._http.user(value);
    }

    if (this._router) {
      this._router.user(value);
    }

    return this;
  }

  ws(options = null) {
    if (options === null) {
      return this._ws;
    }

    options.factory = (u, p) => {
      return new WebSocket(u, p);
    };

    this._ws = new WsConnection()
      .codec(options.codec)
      .reconnector(options);

    this._bindWs();
    return this;
  }

  start() {
    es7.shim();

    loadApi(this);
    loadValidator(this);

    if (this._pubsub) {
      this._pubsub.open();
    }

    if (this._auth === null) {
      this._popState();
      return this;
    }

    loadAuth(this);
    setUser(this, () => this._popState());

    return this;
  }

  _bindAuth() {
    if (this._auth) {
      this.setMaxListeners(this.getMaxListeners() + 1);
      this.on('auth', this._handleSetAuth);
    }
  }

  _unbindAuth() {
    if (this._auth) {
      this.setMaxListeners(this.getMaxListeners() - 1);
      this.removeListener('auth', this._handleSetAuth);
    }
  }

  _bindRouter() {
    if (this._router) {
      this._router.setMaxListeners(this._router.getMaxListeners() + 1);
      this._router.on('error', this._handleError);
    }
  }

  _unbindRouter() {
    if (this._router) {
      this._router.setMaxListeners(this._router.getMaxListeners() - 1);
      this._router.removeListener('error', this._handleError);
    }
  }

  _bindWs() {
    if (this._ws) {
      window.addEventListener('online', this._handleOnline);
      this._ws.setMaxListeners(this._ws.getMaxListeners() + 1);
      this._ws.on('close', this._handleClose);
      this._ws.on('error', this._handleError);
      this._ws.on('open', this._handleOpen);
    }
  }

  _unbindWs() {
    if (this._ws) {
      window.removeEventListener('online', this._handleOnline);
      this._ws.setMaxListeners(this._ws.getMaxListeners() - 1);
      this._ws.removeListener('close', this._handleClose);
      this._ws.removeListener('error', this._handleError);
      this._ws.removeListener('open', this._handleOpen);
    }
  }

  _popState() {
    const filter = this._user === null ? ['scola.auth'] : null;

    this._router.popState(filter);

    if (this._ws) {
      if (window.navigator.onLine === true) {
        this._ws.open();
      }
    }
  }

  _setAuth(value) {
    if (value !== 'valid' && this._mainModifier) {
      this._router.target('main').destroy();
    }
  }

  _serializeAuth(data) {
    return {
      token: data.user.token
    };
  }

  _error(error) {
    if (error.status === 500) {
      return;
    }

    if (error.status === 401 || error.status === 403) {
      logOut(this);
      return;
    }

    this.emit('error', error);
  }

  _main(target) {
    let element = mainFactory()
      .mode('over');

    element = this._mainModifier(element);
    const menus = Array.from(this._menuModifiers.keys());

    menus.forEach((name) => {
      const menu = target
        .router()
        .target(name)
        .element();

      if (menu !== null) {
        element.append(menu);
      }
    });

    document.body.appendChild(element.root().node());
    element.show(true);

    target
      .element(element)
      .once('destroy', () => {
        element.show(false).on('end', () => {
          element.destroy();
          target.routes(false);

          menus.forEach((name) => {
            target
              .router()
              .target(name)
              .destroy();
          });
        });
      });
  }

  _menu(target) {
    const modifier = this._menuModifiers.get(target.name());

    let element = menuFactory()
      .position('left');

    element = modifier(element);

    const main = target
      .router()
      .target('main')
      .element();

    if (main !== null) {
      main.append(element);
    }

    target
      .element(element)
      .once('destroy', () => {
        element.destroy();
        target.routes(false);
      });
  }

  _close() {
    this.state('open', false);
  }

  _online() {
    if (this._ws) {
      this._ws.open();
    }
  }

  _open() {
    this.state('open', true);

    if (this._auth) {
      logIn(this);
    }
  }
}
<|endoftext|>


<commit_before>import 'dom-shims';
import 'es6-shim';
import es7 from 'es7-shim';
import vp from 'viewport-units-buggyfill';

import { EventEmitter } from 'events';
import { FastClick } from 'fastclick';
import { request } from 'https';

import {
  HttpConnection,
  WsConnection,
  load as loadApi
} from '@scola/api';

import {
  AUTH_VALID,
  Auth,
  setUser,
  logIn,
  logOut,
  load as loadAuth
} from '@scola/auth-client';

import {
  cache as cacheFactory,
  i18n as i18nFactory,
  router as routerFactory,
  main as mainFactory,
  menu as menuFactory,
  model as modelFactory
} from '@scola/d3';

import { load as loadValidator } from '@scola/validator';

export default class Client extends EventEmitter {
  constructor() {
    super();

    this._auth = null;
    this._codec = null;
    this._http = null;
    this._i18n = null;
    this._mainModifier = null;
    this._menuModifiers = new Map();
    this._router = null;
    this._storage = null;
    this._user = null;
    this._ws = null;

    this._state = {
      auth: false,
      open: false
    };

    this._fastClick = FastClick.attach(document.body);

    this._handleClose = () => this._close();
    this._handleError = (e) => this._error(e);
    this._handleMain = (t) => this._main(t);
    this._handleMenu = (t) => this._menu(t);
    this._handleOnline = () => this._online();
    this._handleOpen = (e) => this._open(e);
    this._handleSetAuth = (e) => this._setAuth(e);
  }

  destroy() {
    this._fastClick.destroy();

    this._unbindAuth();
    this._unbindRouter();
    this._unbindWs();
  }

  state(name, value = null) {
    if (value === null) {
      return typeof this._state[name] === 'undefined' ?
        null : this._state[name];
    }

    this._state[name] = value;
    this.emit(name, value);

    return this;
  }

  auth(options = null) {
    if (options === null) {
      return this._auth;
    }

    const model = modelFactory(options.name, true)
      .connection(this._ws || this._http)
      .serialize((d) => this._serializeAuth(d));

    const cache = cacheFactory()
      .model(model);

    this._auth = new Auth()
      .cache(cache);

    this._bindAuth();
    return this;
  }

  codec(value = null) {
    if (value === null) {
      return this._codec;
    }

    this._codec = value;

    if (this._ws) {
      this._ws.codec(value);
    }

    return this;
  }

  http(options = null) {
    if (options === null) {
      return this._http;
    }

    this._http = new HttpConnection()
      .http({ request })
      .codec(this.codec())
      .host(options.host)
      .port(options.port);

    return this;
  }

  i18n(options = null) {
    if (options === null) {
      return this._i18n;
    }

    this._i18n = i18nFactory()
      .locale(options.locale)
      .timezone(options.timezone);

    return this;
  }

  main(modifier = (e) => e.size()) {
    this._mainModifier = modifier;
    this._router.target('main').render(this._handleMain);

    return this;
  }

  menu(name, modifier = (e) => e.size()) {
    this._menuModifiers.set(name, modifier);
    this._router.target(name).render(this._handleMenu);

    return this;
  }

  router(options = null) {
    if (options === null) {
      return this._router;
    }

    const model = modelFactory(options.name, true);
    this._router = routerFactory().model(model);

    this._bindRouter();
    return this;
  }

  storage(value = null) {
    if (value === null) {
      return this._storage;
    }

    this._storage = value;
    return this;
  }

  user(value = null) {
    if (value === null) {
      return this._user;
    }

    this._user = value === false ?
      null : value;

    if (this._ws) {
      this._ws.user(value);
    }

    if (this._http) {
      this._http.user(value);
    }

    if (this._router) {
      this._router.user(value);
    }

    return this;
  }

  ws(options = null) {
    if (options === null) {
      return this._ws;
    }

    options.factory = (u, p) => {
      return new WebSocket(u, p);
    };

    this._ws = new WsConnection()
      .router(this.router())
      .codec(this.codec())
      .reconnector(options);

    this._bindWs();
    return this;
  }

  start() {
    es7.shim();
    vp.init();

    loadApi(this);
    loadValidator(this);

    if (this._auth === null) {
      this._popState();
      return this;
    }

    loadAuth(this);
    setUser(this, () => this._popState());

    return this;
  }

  _bindAuth() {
    if (this._auth) {
      this.on('auth', this._handleSetAuth);
    }
  }

  _unbindAuth() {
    if (this._auth) {
      this.removeListener('auth', this._handleSetAuth);
    }
  }

  _bindRouter() {
    if (this._router) {
      this._router.on('error', this._handleError);
    }
  }

  _unbindRouter() {
    if (this._router) {
      this._router.removeListener('error', this._handleError);
    }
  }

  _bindWs() {
    if (this._ws) {
      window.addEventListener('online', this._handleOnline);
      this._ws.on('close', this._handleClose);
      this._ws.on('error', this._handleError);
      this._ws.on('open', this._handleOpen);
    }
  }

  _unbindWs() {
    if (this._ws) {
      window.removeEventListener('online', this._handleOnline);
      this._ws.removeListener('close', this._handleClose);
      this._ws.removeListener('error', this._handleError);
      this._ws.removeListener('open', this._handleOpen);
    }
  }

  _popState() {
    const filter = this._user === null ? ['scola.auth'] : null;

    this._router.popState(filter);

    if (this._ws) {
      if (window.navigator.onLine === true) {
        this._ws.open();
      }
    }
  }

  _setAuth(value) {
    if (value !== AUTH_VALID && this._mainModifier) {
      this._router.target('main').destroy('replace');
    }
  }

  _serializeAuth(data) {
    return {
      token: data.user.token
    };
  }

  _error(error) {
    if (error.status === 500) {
      return;
    }

    if (error.status === 401 || error.status === 403) {
      logOut(this);
      return;
    }

    this.emit('error', error);
  }

  _main(target) {
    let element = mainFactory()
      .mode('over');

    element = this._mainModifier(element);
    const menus = Array.from(this._menuModifiers.keys());

    menus.forEach((name) => {
      const menu = target
        .router()
        .target(name)
        .element();

      if (menu !== null) {
        element.append(menu);
      }
    });

    document.body.appendChild(element.root().node());
    element.show(true);

    target.element(element, () => {
      element.show(false).on('end', () => {
        element.destroy();
        target.routes(false);

        menus.forEach((name) => {
          target
            .router()
            .target(name)
            .destroy('replace');
        });
      });
    });
  }

  _menu(target) {
    const modifier = this._menuModifiers.get(target.name());

    let element = menuFactory()
      .position('left');

    element = modifier(element);

    const main = target
      .router()
      .target('main')
      .element();

    if (main !== null) {
      main.append(element);
    }

    target.element(element, () => {
      element.destroy();
      target.routes(false);
    });
  }

  _close() {
    this.state('open', false);
  }

  _online() {
    if (this._ws) {
      this._ws.open();
    }
  }

  _open() {
    this.state('open', true);

    if (this._auth) {
      logIn(this);
    }
  }
}
<commit_msg>More specific shim import<commit_after>import 'dom-shims/shim/Element.mutation';
import 'es6-shim';
import es7 from 'es7-shim';
import vp from 'viewport-units-buggyfill';

import { EventEmitter } from 'events';
import { FastClick } from 'fastclick';
import { request } from 'https';

import {
  HttpConnection,
  WsConnection,
  load as loadApi
} from '@scola/api';

import {
  AUTH_VALID,
  Auth,
  setUser,
  logIn,
  logOut,
  load as loadAuth
} from '@scola/auth-client';

import {
  cache as cacheFactory,
  i18n as i18nFactory,
  router as routerFactory,
  main as mainFactory,
  menu as menuFactory,
  model as modelFactory
} from '@scola/d3';

import { load as loadValidator } from '@scola/validator';

export default class Client extends EventEmitter {
  constructor() {
    super();

    this._auth = null;
    this._codec = null;
    this._http = null;
    this._i18n = null;
    this._mainModifier = null;
    this._menuModifiers = new Map();
    this._router = null;
    this._storage = null;
    this._user = null;
    this._ws = null;

    this._state = {
      auth: false,
      open: false
    };

    this._fastClick = FastClick.attach(document.body);

    this._handleClose = () => this._close();
    this._handleError = (e) => this._error(e);
    this._handleMain = (t) => this._main(t);
    this._handleMenu = (t) => this._menu(t);
    this._handleOnline = () => this._online();
    this._handleOpen = (e) => this._open(e);
    this._handleSetAuth = (e) => this._setAuth(e);
  }

  destroy() {
    this._fastClick.destroy();

    this._unbindAuth();
    this._unbindRouter();
    this._unbindWs();
  }

  state(name, value = null) {
    if (value === null) {
      return typeof this._state[name] === 'undefined' ?
        null : this._state[name];
    }

    this._state[name] = value;
    this.emit(name, value);

    return this;
  }

  auth(options = null) {
    if (options === null) {
      return this._auth;
    }

    const model = modelFactory(options.name, true)
      .connection(this._ws || this._http)
      .serialize((d) => this._serializeAuth(d));

    const cache = cacheFactory()
      .model(model);

    this._auth = new Auth()
      .cache(cache);

    this._bindAuth();
    return this;
  }

  codec(value = null) {
    if (value === null) {
      return this._codec;
    }

    this._codec = value;

    if (this._ws) {
      this._ws.codec(value);
    }

    return this;
  }

  http(options = null) {
    if (options === null) {
      return this._http;
    }

    this._http = new HttpConnection()
      .http({ request })
      .codec(this.codec())
      .host(options.host)
      .port(options.port);

    return this;
  }

  i18n(options = null) {
    if (options === null) {
      return this._i18n;
    }

    this._i18n = i18nFactory()
      .locale(options.locale)
      .timezone(options.timezone);

    return this;
  }

  main(modifier = (e) => e.size()) {
    this._mainModifier = modifier;
    this._router.target('main').render(this._handleMain);

    return this;
  }

  menu(name, modifier = (e) => e.size()) {
    this._menuModifiers.set(name, modifier);
    this._router.target(name).render(this._handleMenu);

    return this;
  }

  router(options = null) {
    if (options === null) {
      return this._router;
    }

    const model = modelFactory(options.name, true);
    this._router = routerFactory().model(model);

    this._bindRouter();
    return this;
  }

  storage(value = null) {
    if (value === null) {
      return this._storage;
    }

    this._storage = value;
    return this;
  }

  user(value = null) {
    if (value === null) {
      return this._user;
    }

    this._user = value === false ?
      null : value;

    if (this._ws) {
      this._ws.user(value);
    }

    if (this._http) {
      this._http.user(value);
    }

    if (this._router) {
      this._router.user(value);
    }

    return this;
  }

  ws(options = null) {
    if (options === null) {
      return this._ws;
    }

    options.factory = (u, p) => {
      return new WebSocket(u, p);
    };

    this._ws = new WsConnection()
      .router(this.router())
      .codec(this.codec())
      .reconnector(options);

    this._bindWs();
    return this;
  }

  start() {
    es7.shim();
    vp.init();

    loadApi(this);
    loadValidator(this);

    if (this._auth === null) {
      this._popState();
      return this;
    }

    loadAuth(this);
    setUser(this, () => this._popState());

    return this;
  }

  _bindAuth() {
    if (this._auth) {
      this.on('auth', this._handleSetAuth);
    }
  }

  _unbindAuth() {
    if (this._auth) {
      this.removeListener('auth', this._handleSetAuth);
    }
  }

  _bindRouter() {
    if (this._router) {
      this._router.on('error', this._handleError);
    }
  }

  _unbindRouter() {
    if (this._router) {
      this._router.removeListener('error', this._handleError);
    }
  }

  _bindWs() {
    if (this._ws) {
      window.addEventListener('online', this._handleOnline);
      this._ws.on('close', this._handleClose);
      this._ws.on('error', this._handleError);
      this._ws.on('open', this._handleOpen);
    }
  }

  _unbindWs() {
    if (this._ws) {
      window.removeEventListener('online', this._handleOnline);
      this._ws.removeListener('close', this._handleClose);
      this._ws.removeListener('error', this._handleError);
      this._ws.removeListener('open', this._handleOpen);
    }
  }

  _popState() {
    const filter = this._user === null ? ['scola.auth'] : null;

    this._router.popState(filter);

    if (this._ws) {
      if (window.navigator.onLine === true) {
        this._ws.open();
      }
    }
  }

  _setAuth(value) {
    if (value !== AUTH_VALID && this._mainModifier) {
      this._router.target('main').destroy('replace');
    }
  }

  _serializeAuth(data) {
    return {
      token: data.user.token
    };
  }

  _error(error) {
    if (error.status === 500) {
      return;
    }

    if (error.status === 401 || error.status === 403) {
      logOut(this);
      return;
    }

    this.emit('error', error);
  }

  _main(target) {
    let element = mainFactory()
      .mode('over');

    element = this._mainModifier(element);
    const menus = Array.from(this._menuModifiers.keys());

    menus.forEach((name) => {
      const menu = target
        .router()
        .target(name)
        .element();

      if (menu !== null) {
        element.append(menu);
      }
    });

    document.body.appendChild(element.root().node());
    element.show(true);

    target.element(element, () => {
      element.show(false).on('end', () => {
        element.destroy();
        target.routes(false);

        menus.forEach((name) => {
          target
            .router()
            .target(name)
            .destroy('replace');
        });
      });
    });
  }

  _menu(target) {
    const modifier = this._menuModifiers.get(target.name());

    let element = menuFactory()
      .position('left');

    element = modifier(element);

    const main = target
      .router()
      .target('main')
      .element();

    if (main !== null) {
      main.append(element);
    }

    target.element(element, () => {
      element.destroy();
      target.routes(false);
    });
  }

  _close() {
    this.state('open', false);
  }

  _online() {
    if (this._ws) {
      this._ws.open();
    }
  }

  _open() {
    this.state('open', true);

    if (this._auth) {
      logIn(this);
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

const logger = require('../lib/logger');
const db = require('../lib/db');
const extensions = require('./extensions');
const coreMW = require('../middlewares/core');
const ServantMessage = require('../modules/message').ServantMessage;

const defer = typeof setImmediate === 'function'
    ? setImmediate
    : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) };

class ServantClient {
    constructor(server, socket, finalHandler) {
        this.socket = socket;
        this._server = server;
        this.ip = socket.address();

        this.socket.on('pong', ServantClient._onPong.bind(this));
        this.socket.on('close', ServantClient._onClose.bind(this));
        this.socket.on('error', ServantClient._onError.bind(this));
        this.socket.on('message', ServantClient._onMessage.bind(this));

        const out = function (err) { if (err) { logger.error('Next error: ' + err.message); logger.verbose(err.stack); } };

        this.out = finalHandler || out;

        if (this.server.heartbeat) {
            this.intervalId = setInterval(() => {
                this.socket.ping();
            }, this.server.heartbeat * 1000);
        }
    }

    get server() {
        return this._server;
    }

    static _onPong() {
        logger.debug('Pong received from: ' + this.ip);

        this.server.emit('client.pong');
    }

    static _onClose(code, message) {
        this.server.workers[this.ip] = null;
        delete this.server.workers[this.ip];

        logger.debug('Current agents: ' + this.currentAgentsCount);

        clearInterval(this.intervalId);

        this.server.emit('client.disconnect', code, message, this);
    }

    static _onError(error) {
        this.server.emit('client.error', error);
    }

    static _onMessage(raw) {
        let index = 0;

        //check all handlers in stage stack

        let stage = this.server.stacks[coreMW.MESSAGE_RECEIVED_STAGE];
        let modules = this.server.stacks[coreMW.MODULE_STAGE];

        logger.debug('Receive new message: ' + raw);

        let message = null;
        try {
            message = new ServantMessage(raw);
        } catch (e) {
            logger.error(e.message);
            logger.verbose(e.stack);
        }

        if (!message) {
            return;
        }

        const nextModule = (err) => {
            let layer = modules[index++];

            if (!layer) { //end reached
                defer(this.out, err);
                return;
            }

            if (layer.route !== 'dummy' && message.module.toLowerCase() !== layer.route) {
                return nextModule(err);
            }

            ServantClient.call(layer.handle, this, message, err, nextModule);
        };

        const nextStage = (err) => {
            let layer = stage[index++];

            if (!layer) { //end reached
                if (err) {
                    return defer(this.out, err);
                } else {
                    index = 0;
                    return defer(nextModule, err);
                }
            }

            if (layer.route !== 'dummy' && message.module.toLowerCase() !== layer.route) {
                return nextStage(err);
            }

            ServantClient.call(layer.handle, this, message, err, nextStage);
        };

        nextStage();
    }

    static call(handler, agent, message, err, next) {
        var error = err;
        var arity = handler.length;

        try {
            if (error && arity == 4) {
                return handler(err, message, agent, next);
            } else if (!error && arity < 4) {
                return handler(message, agent, next);
            }
        } catch (e) {
            error = e;
        }

        next(error);
    }

    sendMessage(message) {
        if (message instanceof ServantMessage) {
            let index = 0;
            let stage = this.server.stacks[coreMW.MESSAGE_SEND_STAGE];

            const nextStage = (err) => {
                let layer = stage[index++];

                if (!layer) { //end reached
                    if (err) {
                        return defer(this.out, err);
                    } else {
                        return this.socket.send(message.toJSON());
                    }
                }

                if (layer.route !== 'dummy' && message.module.toLowerCase() !== layer.route) {
                    return nextStage(err);
                }

                ServantClient.call(layer.handle, this, message, err, nextStage);
            };

            nextStage();
        } else {
            throw new Error('"message" is not instance of "ServantMessage"');
        }
    }
}

exports.ServantClient = ServantClient;<commit_msg>fix log record<commit_after>'use strict';

const logger = require('../lib/logger');
const db = require('../lib/db');
const extensions = require('./extensions');
const coreMW = require('../middlewares/core');
const ServantMessage = require('../modules/message').ServantMessage;

const defer = typeof setImmediate === 'function'
    ? setImmediate
    : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) };

class ServantClient {
    constructor(server, socket, finalHandler) {
        this.socket = socket;
        this._server = server;
        this.ip = socket.address();

        this.socket.on('pong', ServantClient._onPong.bind(this));
        this.socket.on('close', ServantClient._onClose.bind(this));
        this.socket.on('error', ServantClient._onError.bind(this));
        this.socket.on('message', ServantClient._onMessage.bind(this));

        const out = function (err) { if (err) { logger.error('Next error: ' + err.message); logger.verbose(err.stack); } };

        this.out = finalHandler || out;

        if (this.server.heartbeat) {
            this.intervalId = setInterval(() => {
                this.socket.ping();
            }, this.server.heartbeat * 1000);
        }
    }

    get server() {
        return this._server;
    }

    static _onPong() {
        logger.debug('Pong received from: ' + this.ip);

        this.server.emit('client.pong');
    }

    static _onClose(code, message) {
        this.server.workers[this.ip] = null;
        delete this.server.workers[this.ip];

        logger.debug('Current agents: ' + this.server.currentAgentsCount);

        clearInterval(this.intervalId);

        this.server.emit('client.disconnect', code, message, this);
    }

    static _onError(error) {
        this.server.emit('client.error', error);
    }

    static _onMessage(raw) {
        let index = 0;

        //check all handlers in stage stack

        let stage = this.server.stacks[coreMW.MESSAGE_RECEIVED_STAGE];
        let modules = this.server.stacks[coreMW.MODULE_STAGE];

        logger.debug('Receive new message: ' + raw);

        let message = null;
        try {
            message = new ServantMessage(raw);
        } catch (e) {
            logger.error(e.message);
            logger.verbose(e.stack);
        }

        if (!message) {
            return;
        }

        const nextModule = (err) => {
            let layer = modules[index++];

            if (!layer) { //end reached
                defer(this.out, err);
                return;
            }

            if (layer.route !== 'dummy' && message.module.toLowerCase() !== layer.route) {
                return nextModule(err);
            }

            ServantClient.call(layer.handle, this, message, err, nextModule);
        };

        const nextStage = (err) => {
            let layer = stage[index++];

            if (!layer) { //end reached
                if (err) {
                    return defer(this.out, err);
                } else {
                    index = 0;
                    return defer(nextModule, err);
                }
            }

            if (layer.route !== 'dummy' && message.module.toLowerCase() !== layer.route) {
                return nextStage(err);
            }

            ServantClient.call(layer.handle, this, message, err, nextStage);
        };

        nextStage();
    }

    static call(handler, agent, message, err, next) {
        var error = err;
        var arity = handler.length;

        try {
            if (error && arity == 4) {
                return handler(err, message, agent, next);
            } else if (!error && arity < 4) {
                return handler(message, agent, next);
            }
        } catch (e) {
            error = e;
        }

        next(error);
    }

    sendMessage(message) {
        if (message instanceof ServantMessage) {
            let index = 0;
            let stage = this.server.stacks[coreMW.MESSAGE_SEND_STAGE];

            const nextStage = (err) => {
                let layer = stage[index++];

                if (!layer) { //end reached
                    if (err) {
                        return defer(this.out, err);
                    } else {
                        return this.socket.send(message.toJSON());
                    }
                }

                if (layer.route !== 'dummy' && message.module.toLowerCase() !== layer.route) {
                    return nextStage(err);
                }

                ServantClient.call(layer.handle, this, message, err, nextStage);
            };

            nextStage();
        } else {
            throw new Error('"message" is not instance of "ServantMessage"');
        }
    }
}

exports.ServantClient = ServantClient;<|endoftext|>


<commit_before>import Phaser from 'phaser'

export default class extends Phaser.Sprite {
  constructor ({ game, x, y, asset }) {
    super(game, x, y, asset)
    this.centerX = x
    this.centerY = y
    this.anchor.setTo(0.5)
    this.circleBasis = 0
  }

  update () {
    this.circleBasis += 0.05
    const scaleFactor = 5
    this.x = (scaleFactor * Math.cos(this.circleBasis)) + this.centerX
    this.y = (scaleFactor * Math.sin(this.circleBasis)) + this.centerY
    this.angle += 10
    //adding comment to merge with Carson
  }
}
<commit_msg>Added another cool comment<commit_after>import Phaser from 'phaser'

export default class extends Phaser.Sprite {
  constructor ({ game, x, y, asset }) {
    super(game, x, y, asset)
    this.centerX = x
    this.centerY = y
    this.anchor.setTo(0.5)
    this.circleBasis = 0
  }

  update () {
    this.circleBasis += 0.05
    const scaleFactor = 5
    this.x = (scaleFactor * Math.cos(this.circleBasis)) + this.centerX
    this.y = (scaleFactor * Math.sin(this.circleBasis)) + this.centerY
    this.angle += 10
    //adding comment to merge with Carson
    //another comment
  }
}
<|endoftext|>