<commit_before>const defaultConfig = require('./lib/default-config')
const getContents = require('./lib/get-file-contents')
const generateBody = require('./lib/generate-body')
const commitIsInPR = require('./lib/commit-is-in-pr')
const generateLabel = require('./lib/generate-label')
const reopenClosed = require('./lib/reopen-closed')
const metadata = require('./lib/metadata')

module.exports = (robot) => {
  robot.on('push', async context => {
    if (!context.payload.head_commit) return

    const config = await context.config('config.yml')
    const cfg = config && config.todo ? {...defaultConfig, ...config.todo} : defaultConfig

    const [issuePages, labels] = await Promise.all([
      context.github.paginate(context.github.issues.getForRepo(context.repo({state: 'all'}))),
      generateLabel(context, cfg)
    ])

    const issues = [].concat.apply([], issuePages.map(p => p.data))

    // Get array of issue objects in the current repo
    const {pusher, commits} = context.payload
    const author = pusher.name

    // Get the most up-to-date contents of each file
    // by the commit it was most recently edited in.
    const commitsByFiles = new Map()
    for (let c = 0; c < commits.length; c++) {
      const commit = commits[c]
      const files = [...commit.added, ...commit.modified]
      const mappedFiles = new Map()

      for (let i = 0; i < files.length; i++) {
        const file = files[i]
        const sliced = commits.slice(c + 1)

        if (sliced.every(com => com.modified.indexOf(file) === -1)) {
          const contents = await getContents(context, commit.id, file)
          mappedFiles.set(file, contents)
          break
        }
      }

      commitsByFiles.set(commit.id, mappedFiles)
    }

    commitsByFiles.forEach(async (files, sha) => {
      files.forEach(async (contents, file) => {
        // Get issue titles
        const regexFlags = cfg.caseSensitive ? 'g' : 'gi'
        const re = new RegExp(`${cfg.keyword}\\s(.*)`, regexFlags)
        const matches = contents.match(re)
        if (!matches) return

        const titles = matches.map(title => title.replace(new RegExp(`${cfg.keyword} `, regexFlags), ''))
        titles.forEach(async title => {
          // Check if an issue with that title exists
          const existingIssue = issues.find(issue => {
            if (!issue.body) return false
            const titleKey = metadata(context, issue).get('title')
            const fileKey = metadata(context, issue).get('file')
            return titleKey === title && fileKey === file
          })

          if (existingIssue) {
            if (cfg.reopenClosed && existingIssue.state === 'closed') {
              return reopenClosed(robot.log, context, cfg, existingIssue.number, file, sha)
            } else {
              return
            }
          }

          const pr = await commitIsInPR(context, sha)
          const body = generateBody(context, cfg, title, file, contents, author, sha, pr)

          const issueObj = { title, body, labels }
          if (cfg.autoAssign === true) {
            issueObj.assignee = author
          } else if (typeof cfg.autoAssign === 'string') {
            issueObj.assignee = cfg.autoAssign
          } else if (Array.isArray(cfg.autoAssign)) {
            issueObj.assignees = cfg.autoAssign
          }

          const issue = context.issue(issueObj)

          robot.log(`Creating issue: ${issue.title}, in ${context.repo().owner}/${context.repo().repo}`)
          return context.github.issues.create(issue)
        })
      })
    })
  })

  robot.on('installation.created', context => {
    const repos = context.payload.repositories.reduce((prev, repo, i, arr) => {
      if (i === 0) return prev + repo.full_name
      if (i === arr.length - 1) return `${prev} and ${repo.full_name}`
      return `${prev}, ${repo.full_name}`
    }, '')
    robot.log(`todo was just installed on ${repos}.`)
  })
}
<commit_msg>Move PR check outside of loops<commit_after>const defaultConfig = require('./lib/default-config')
const getContents = require('./lib/get-file-contents')
const generateBody = require('./lib/generate-body')
const commitIsInPR = require('./lib/commit-is-in-pr')
const generateLabel = require('./lib/generate-label')
const reopenClosed = require('./lib/reopen-closed')
const metadata = require('./lib/metadata')

module.exports = (robot) => {
  robot.on('push', async context => {
    if (!context.payload.head_commit) return

    let prFlag = false
    let pr

    const config = await context.config('config.yml')
    const cfg = config && config.todo ? {...defaultConfig, ...config.todo} : defaultConfig

    const [issuePages, labels] = await Promise.all([
      context.github.paginate(context.github.issues.getForRepo(context.repo({state: 'all'}))),
      generateLabel(context, cfg)
    ])

    const issues = [].concat.apply([], issuePages.map(p => p.data))

    // Get array of issue objects in the current repo
    const {pusher, commits} = context.payload
    const author = pusher.name

    // Get the most up-to-date contents of each file
    // by the commit it was most recently edited in.
    const commitsByFiles = new Map()
    for (let c = 0; c < commits.length; c++) {
      const commit = commits[c]
      const files = [...commit.added, ...commit.modified]
      const mappedFiles = new Map()

      for (let i = 0; i < files.length; i++) {
        const file = files[i]
        const sliced = commits.slice(c + 1)

        if (sliced.every(com => com.modified.indexOf(file) === -1)) {
          const contents = await getContents(context, commit.id, file)
          mappedFiles.set(file, contents)
          break
        }
      }

      commitsByFiles.set(commit.id, mappedFiles)
    }

    commitsByFiles.forEach(async (files, sha) => {
      files.forEach(async (contents, file) => {
        // Get issue titles
        const regexFlags = cfg.caseSensitive ? 'g' : 'gi'
        const re = new RegExp(`${cfg.keyword}\\s(.*)`, regexFlags)
        const matches = contents.match(re)
        if (!matches) return

        if (!prFlag) {
          prFlag = true
          pr = await commitIsInPR(context, sha)
        }

        const titles = matches.map(title => title.replace(new RegExp(`${cfg.keyword} `, regexFlags), ''))

        titles.forEach(async title => {
          // Check if an issue with that title exists
          const existingIssue = issues.find(issue => {
            if (!issue.body) return false
            const titleKey = metadata(context, issue).get('title')
            const fileKey = metadata(context, issue).get('file')
            return titleKey === title && fileKey === file
          })

          if (existingIssue) {
            if (cfg.reopenClosed && existingIssue.state === 'closed') {
              return reopenClosed(robot.log, context, cfg, existingIssue.number, file, sha)
            } else {
              return
            }
          }

          const body = generateBody(context, cfg, title, file, contents, author, sha, pr)

          const issueObj = { title, body, labels }
          if (cfg.autoAssign === true) {
            issueObj.assignee = author
          } else if (typeof cfg.autoAssign === 'string') {
            issueObj.assignee = cfg.autoAssign
          } else if (Array.isArray(cfg.autoAssign)) {
            issueObj.assignees = cfg.autoAssign
          }

          const issue = context.issue(issueObj)

          robot.log(`Creating issue: ${issue.title}, in ${context.repo().owner}/${context.repo().repo}`)
          return context.github.issues.create(issue)
        })
      })
    })
  })

  robot.on('installation.created', context => {
    const repos = context.payload.repositories.reduce((prev, repo, i, arr) => {
      if (i === 0) return prev + repo.full_name
      if (i === arr.length - 1) return `${prev} and ${repo.full_name}`
      return `${prev}, ${repo.full_name}`
    }, '')
    robot.log(`todo was just installed on ${repos}.`)
  })
}
<|endoftext|>


<commit_before>/*
Gordon Williams (gw@pur3.co.uk)

Common entrypoint for all communications from the IDE. This handles
all serial_*.js connection types and passes calls to the correct one.

To add a new serial device, you must add an object to
  Espruino.Core.Serial.devices:

  Espruino.Core.Serial.devices.push({
    "name" : "Test",               // Name, when initialising
    "init" : function()            // Gets called at startup
    "getPorts": function(callback) // calls 'callback' with an array of ports:
        callback([{path:"TEST",          // path passed to 'open' (and displayed to user)
                   description:"test",   // description displayed to user
                   type:"test",           // bluetooth|usb|socket - used to show icon in UI
                   // autoconnect : true  // automatically conect to this (without the connect menu)
                 }], true); // instantPorts - will getPorts return all the ports on the first call, or does it need multiple calls (eg. Bluetooth)
    "open": function(path, openCallback, receiveCallback, disconnectCallback),
    "write": function(dataAsString, callbackWhenWritten)
    "close": function(),
    "maxWriteLength": 20, // optional - the maximum amount of characters that should be given to 'write' at a time
  });

*/
(function() {

  // List of ports and the devices they map to
  var portToDevice = undefined;
  // The current connected device (from Espruino.Core.Serial.devices)
  var currentDevice = undefined;

  // called when data received
  var readListener = undefined;

  // are we sending binary data? If so, don't automatically insert breaks for stuff like Ctrl-C
  var sendingBinary = false;
  // For throttled write
  var slowWrite = true;
  var writeData = [];
  var writeTimeout = undefined;

  function init() {
    Espruino.Core.Config.add("BAUD_RATE", {
      section : "Communications",
      name : "Baud Rate",
      description : "When connecting over serial, this is the baud rate that is used. 9600 is the default for Espruino",
      type : {9600:9600,14400:14400,19200:19200,28800:28800,38400:38400,57600:57600,115200:115200},
      defaultValue : 9600,
    });

    var devices = Espruino.Core.Serial.devices;
    for (var i=0;i<devices.length;i++) {
      console.log("  - Initialising Serial "+devices[i].name);
      if (devices[i].init)
        devices[i].init();
    }
  }

  var startListening=function(callback) {
    var oldListener = readListener;
    readListener = callback;
    return oldListener;
  };

  /* Calls 'callback(port_list, shouldCallAgain)'
   'shouldCallAgain==true' means that more devices
   may appear later on (eg Bluetooth LE).*/
  var getPorts=function(callback) {
    var ports = [];
    var newPortToDevice = [];
    // get all devices
    var responses = 0;
    var devices = Espruino.Core.Serial.devices;
    if (!devices || devices.length==0) {
         portToDevice = newPortToDevice;
      return callback(ports, false);
    }
    var shouldCallAgain = false;
    devices.forEach(function (device) {
      //console.log("getPorts -->",device.name);
      device.getPorts(function(devicePorts, instantPorts) {
        //console.log("getPorts <--",device.name);
        if (instantPorts===false) shouldCallAgain = true;
        if (devicePorts) {
          devicePorts.forEach(function(port) {
            if (port.usb && port.usb[0]==0x0483 && port.usb[1]==0x5740)
              port.description = "Espruino board";
            ports.push(port);
            newPortToDevice[port.path] = device;
          });
        }
        responses++;
        if (responses == devices.length) {
          portToDevice = newPortToDevice;
          ports.sort(function(a,b) {
            if (a.unimportant && !b.unimportant) return 1;
            if (b.unimportant && !a.unimportant) return -1;
            return 0;
          });
          callback(ports, shouldCallAgain);
        }
      });
    });
  };

  var openSerial=function(serialPort, connectCallback, disconnectCallback) {
    return openSerialInternal(serialPort, connectCallback, disconnectCallback, 2);
  }

  var openSerialInternal=function(serialPort, connectCallback, disconnectCallback, attempts) {
    /* If openSerial is called, we need to have called getPorts first
      in order to figure out which one of the serial_ implementations
      we must call into. */
    if (portToDevice === undefined) {
      portToDevice = []; // stop recursive calls if something errors
      return getPorts(function() {
        openSerialInternal(serialPort, connectCallback, disconnectCallback, attempts);
      });
    }

    if (!(serialPort in portToDevice)) {
      if (serialPort.toLowerCase() in portToDevice) {
        serialPort = serialPort.toLowerCase();
      } else {
        if (attempts>0) {
          console.log("Port "+JSON.stringify(serialPort)+" not found - checking ports again ("+attempts+" attempts left)");
          return getPorts(function() {
            openSerialInternal(serialPort, connectCallback, disconnectCallback, attempts-1);
          });
        } else {
          console.error("Port "+JSON.stringify(serialPort)+" not found");
          return connectCallback(undefined);
        }
      }
    }

    connectionInfo = undefined;
    currentDevice = portToDevice[serialPort];
    currentDevice.open(serialPort, function(cInfo) {
      // CONNECT
      if (!cInfo) {
//        Espruino.Core.Notifications.error("Unable to connect");
        console.error("Unable to open device (connectionInfo="+cInfo+")");
        connectCallback(undefined);
      } else {
        connectionInfo = cInfo;
        connectedPort = serialPort;
        console.log("Connected", cInfo);
        var portInfo = { port:serialPort };
        if (connectionInfo.portName)
          portInfo.portName = connectionInfo.portName;
        Espruino.callProcessor("connected", portInfo, function() {
          connectCallback(cInfo);
        });
      }
    }, function(data) {
      // RECEIEVE DATA
      if (!(data instanceof ArrayBuffer)) console.warn("Serial port implementation is not returning ArrayBuffers");
      if (readListener) readListener(data);
    }, function() {
      currentDevice = undefined;
      if (!connectionInfo) {
        // we got a disconnect when we hadn't connected...
        // Just call connectCallback(undefined), don't bother sending disconnect
        connectCallback(undefined);
        return;
      }
      // DISCONNECT
      connectionInfo = undefined;
      if (writeTimeout!==undefined)
        clearTimeout(writeTimeout);
      writeTimeout = undefined;
      writeData = [];
      sendingBinary = false;

      Espruino.callProcessor("disconnected", undefined, function() {
        disconnectCallback();
      });
    });
  };

  var str2ab=function(str) {
    var buf=new ArrayBuffer(str.length);
    var bufView=new Uint8Array(buf);
    for (var i=0; i<str.length; i++) {
      var ch = str.charCodeAt(i);
      if (ch>=256) {
        console.warn("Attempted to send non-8 bit character - code "+ch);
        ch = "?".charCodeAt(0);
      }
      bufView[i] = ch;
    }
    return buf;
  };

  var closeSerial=function() {
    if (currentDevice) {
      currentDevice.close();
      currentDevice = undefined;
    } else
      console.error("Close called, but serial port not open");
  };

  var isConnected = function() {
    return currentDevice!==undefined;
  };

  var writeSerialWorker = function(isStarting) {
    writeTimeout = undefined; // we've been called

    // if we disconnected while sending, empty queue
    if (currentDevice === undefined) {
      if (writeData[0].callback)
        writeData[0].callback();
      writeData.shift();
      if (writeData.length) setTimeout(function() {
        writeSerialWorker(false);
      }, 1);
      return;
    }

    if (writeData[0].data === "") {
      if (writeData[0].showStatus)
        Espruino.Core.Status.setStatus("Sent");
      if (writeData[0].callback)
        writeData[0].callback();
      writeData.shift(); // remove this empty first element
      if (!writeData.length) return; // anything left to do?
      isStarting = true;
    }

    if (isStarting) {
      var blockSize = 512;
      if (currentDevice.maxWriteLength)
        blockSize = currentDevice.maxWriteLength;
      /* if we're throttling our writes we want to send small
       * blocks of data at once. We still limit the size of
       * sent blocks to 512 because on Mac we seem to lose
       * data otherwise (not on any other platforms!) */
      if (slowWrite) blockSize=19;
      writeData[0].blockSize = blockSize;

      writeData[0].showStatus &= writeData[0].data.length>writeData[0].blockSize;
      if (writeData[0].showStatus) {
        Espruino.Core.Status.setStatus("Sending...", writeData[0].data.length);
        console.log("---> "+JSON.stringify(writeData[0].data));
      }
    }

    // Initial split use previous, or don't
    var d = undefined;
    var split = writeData[0].nextSplit || { start:0, end:writeData[0].data.length, delay:0 };
    // if we get something like Ctrl-C or `reset`, wait a bit for it to complete
    if (!sendingBinary) {
      function findSplitIdx(prev, substr, delay, reason) {
        var match = writeData[0].data.match(substr);
        // not found
        if (match===null) return prev;
        // or previous find was earlier in str
        var end = match.index + match[0].length;
        if (end > prev.end) return prev;
        // found, and earlier
        prev.start = match.index;
        prev.end = end;
        prev.delay = delay;
        prev.match = match[0];
        prev.reason = reason;
        return prev;
      }
      split = findSplitIdx(split, /\x03/, 250, "Ctrl-C"); // Ctrl-C
      split = findSplitIdx(split, /reset\(\);\n/, 250, "reset()"); // Reset
      split = findSplitIdx(split, /load\(\);\n/, 250, "load()"); // Load
      split = findSplitIdx(split, /Modules.addCached\("[^\n]*"\);\n/, 250, "Modules.addCached"); // Adding a module
      split = findSplitIdx(split, /\x10require\("Storage"\).write\([^\n]*\);\n/, 500, "Storage.write"); // Write chunk of data
    }
    // Otherwise split based on block size
    if (!split.match || split.end >= writeData[0].blockSize) {
      if (split.match) writeData[0].nextSplit = split;
      split = { start:0, end:writeData[0].blockSize, delay:0 };
    }
    if (split.match) console.log("Splitting for "+split.reason+", delay "+split.delay);
    // Only send some of the data
    if (writeData[0].data.length>split.end) {
      if (slowWrite && split.delay==0) split.delay=50;
      d = writeData[0].data.substr(0,split.end);
      writeData[0].data = writeData[0].data.substr(split.end);
      if (writeData[0].nextSplit) {
        writeData[0].nextSplit.start -= split.end;
        writeData[0].nextSplit.end -= split.end;
        if (writeData[0].nextSplit.end<=0)
          writeData[0].nextSplit = undefined;
      }
    } else {
      d = writeData[0].data;
      writeData[0].data = "";
      writeData[0].nextSplit = undefined;
    }
    // update status
    if (writeData[0].showStatus)
      Espruino.Core.Status.incrementProgress(d.length);
    // actually write data
    //console.log("Sending block "+JSON.stringify(d)+", wait "+split.delay+"ms");
    currentDevice.write(d, function() {
      // Once written, start timeout
      writeTimeout = setTimeout(function() {
        writeSerialWorker();
      }, split.delay);
    });
  }

   // Throttled serial write
  var writeSerial = function(data, showStatus, callback) {
    if (showStatus===undefined) showStatus=true;

    /* Queue our data to write. If there was previous data and no callback to
    invoke on this data or the previous then just append data. This would happen
    if typing in the terminal for example. */
    if (!callback && writeData.length && !writeData[writeData.length-1].callback) {
      writeData[writeData.length-1].data += data;
    } else {
      writeData.push({data:data,callback:callback,showStatus:showStatus});
      /* if this is our first data, start sending now. Otherwise we're already
      busy sending and will pull data off writeData when ready */
      if (writeData.length==1)
        writeSerialWorker(true);
    }
  };

  // ----------------------------------------------------------
  Espruino.Core.Serial = {
    "devices" : [], // List of devices that can provide a serial API
    "init" : init,
    "getPorts": getPorts,
    "open": openSerial,
    "isConnected": isConnected,
    "startListening": startListening,
    "write": writeSerial,
    "close": closeSerial,
    "isSlowWrite": function() { return slowWrite; },
    "setSlowWrite": function(isOn, force) {
      if ((!force) && Espruino.Config.SERIAL_THROTTLE_SEND) {
        console.log("ForceThrottle option is set - set Slow Write = true");
        isOn = true;
      } else
        console.log("Set Slow Write = "+isOn);
      slowWrite = isOn;
    },
    "setBinary": function(isOn) {
      sendingBinary = isOn;
    }
  };
})();
<commit_msg>Add option to ignore serial ports with certain names (fix https://github.com/espruino/EspruinoWebIDE/issues/188)<commit_after>/*
Gordon Williams (gw@pur3.co.uk)

Common entrypoint for all communications from the IDE. This handles
all serial_*.js connection types and passes calls to the correct one.

To add a new serial device, you must add an object to
  Espruino.Core.Serial.devices:

  Espruino.Core.Serial.devices.push({
    "name" : "Test",               // Name, when initialising
    "init" : function()            // Gets called at startup
    "getPorts": function(callback) // calls 'callback' with an array of ports:
        callback([{path:"TEST",          // path passed to 'open' (and displayed to user)
                   description:"test",   // description displayed to user
                   type:"test",           // bluetooth|usb|socket - used to show icon in UI
                   // autoconnect : true  // automatically conect to this (without the connect menu)
                 }], true); // instantPorts - will getPorts return all the ports on the first call, or does it need multiple calls (eg. Bluetooth)
    "open": function(path, openCallback, receiveCallback, disconnectCallback),
    "write": function(dataAsString, callbackWhenWritten)
    "close": function(),
    "maxWriteLength": 20, // optional - the maximum amount of characters that should be given to 'write' at a time
  });

*/
(function() {

  // List of ports and the devices they map to
  var portToDevice = undefined;
  // The current connected device (from Espruino.Core.Serial.devices)
  var currentDevice = undefined;

  // called when data received
  var readListener = undefined;

  // are we sending binary data? If so, don't automatically insert breaks for stuff like Ctrl-C
  var sendingBinary = false;
  // For throttled write
  var slowWrite = true;
  var writeData = [];
  var writeTimeout = undefined;

  function init() {
    Espruino.Core.Config.add("BAUD_RATE", {
      section : "Communications",
      name : "Baud Rate",
      description : "When connecting over serial, this is the baud rate that is used. 9600 is the default for Espruino",
      type : {9600:9600,14400:14400,19200:19200,28800:28800,38400:38400,57600:57600,115200:115200},
      defaultValue : 9600,
    });
    Espruino.Core.Config.add("SERIAL_IGNORE", {
     section : "Communications",
     name : "Ignore Serial Ports",
     description : "A '|' separated list of serial port paths to ignore, eg `/dev/ttyS*|/dev/*.SOC`",
     type : "string",
     defaultValue : "/dev/ttyS*|/dev/*.SOC|/dev/*.MALS"
   });

    var devices = Espruino.Core.Serial.devices;
    for (var i=0;i<devices.length;i++) {
      console.log("  - Initialising Serial "+devices[i].name);
      if (devices[i].init)
        devices[i].init();
    }
  }

  var startListening=function(callback) {
    var oldListener = readListener;
    readListener = callback;
    return oldListener;
  };

  /* Calls 'callback(port_list, shouldCallAgain)'
   'shouldCallAgain==true' means that more devices
   may appear later on (eg Bluetooth LE).*/
  var getPorts=function(callback) {
    var ports = [];
    var newPortToDevice = [];
    // get all devices
    var responses = 0;
    var devices = Espruino.Core.Serial.devices;
    if (!devices || devices.length==0) {
         portToDevice = newPortToDevice;
      return callback(ports, false);
    }
    var shouldCallAgain = false;
    devices.forEach(function (device) {
      //console.log("getPorts -->",device.name);
      device.getPorts(function(devicePorts, instantPorts) {
        //console.log("getPorts <--",device.name);
        if (instantPorts===false) shouldCallAgain = true;
        if (devicePorts) {
          devicePorts.forEach(function(port) {
            var ignored = false;
            if (Espruino.Config.SERIAL_IGNORE)
              Espruino.Config.SERIAL_IGNORE.split("|").forEach(function(wildcard) {
                var regexp = "^"+wildcard.replace(/\./g,"\\.").replace(/\*/g,".*")+"$";
                if (port.path.match(new RegExp(regexp)))
                  ignored = true;
              });

            if (!ignored) {
              if (port.usb && port.usb[0]==0x0483 && port.usb[1]==0x5740)
                port.description = "Espruino board";
              ports.push(port);
              newPortToDevice[port.path] = device;
            }
          });
        }
        responses++;
        if (responses == devices.length) {
          portToDevice = newPortToDevice;
          ports.sort(function(a,b) {
            if (a.unimportant && !b.unimportant) return 1;
            if (b.unimportant && !a.unimportant) return -1;
            return 0;
          });
          callback(ports, shouldCallAgain);
        }
      });
    });
  };

  var openSerial=function(serialPort, connectCallback, disconnectCallback) {
    return openSerialInternal(serialPort, connectCallback, disconnectCallback, 2);
  }

  var openSerialInternal=function(serialPort, connectCallback, disconnectCallback, attempts) {
    /* If openSerial is called, we need to have called getPorts first
      in order to figure out which one of the serial_ implementations
      we must call into. */
    if (portToDevice === undefined) {
      portToDevice = []; // stop recursive calls if something errors
      return getPorts(function() {
        openSerialInternal(serialPort, connectCallback, disconnectCallback, attempts);
      });
    }

    if (!(serialPort in portToDevice)) {
      if (serialPort.toLowerCase() in portToDevice) {
        serialPort = serialPort.toLowerCase();
      } else {
        if (attempts>0) {
          console.log("Port "+JSON.stringify(serialPort)+" not found - checking ports again ("+attempts+" attempts left)");
          return getPorts(function() {
            openSerialInternal(serialPort, connectCallback, disconnectCallback, attempts-1);
          });
        } else {
          console.error("Port "+JSON.stringify(serialPort)+" not found");
          return connectCallback(undefined);
        }
      }
    }

    connectionInfo = undefined;
    currentDevice = portToDevice[serialPort];
    currentDevice.open(serialPort, function(cInfo) {
      // CONNECT
      if (!cInfo) {
//        Espruino.Core.Notifications.error("Unable to connect");
        console.error("Unable to open device (connectionInfo="+cInfo+")");
        connectCallback(undefined);
      } else {
        connectionInfo = cInfo;
        connectedPort = serialPort;
        console.log("Connected", cInfo);
        var portInfo = { port:serialPort };
        if (connectionInfo.portName)
          portInfo.portName = connectionInfo.portName;
        Espruino.callProcessor("connected", portInfo, function() {
          connectCallback(cInfo);
        });
      }
    }, function(data) {
      // RECEIEVE DATA
      if (!(data instanceof ArrayBuffer)) console.warn("Serial port implementation is not returning ArrayBuffers");
      if (readListener) readListener(data);
    }, function() {
      currentDevice = undefined;
      if (!connectionInfo) {
        // we got a disconnect when we hadn't connected...
        // Just call connectCallback(undefined), don't bother sending disconnect
        connectCallback(undefined);
        return;
      }
      // DISCONNECT
      connectionInfo = undefined;
      if (writeTimeout!==undefined)
        clearTimeout(writeTimeout);
      writeTimeout = undefined;
      writeData = [];
      sendingBinary = false;

      Espruino.callProcessor("disconnected", undefined, function() {
        disconnectCallback();
      });
    });
  };

  var str2ab=function(str) {
    var buf=new ArrayBuffer(str.length);
    var bufView=new Uint8Array(buf);
    for (var i=0; i<str.length; i++) {
      var ch = str.charCodeAt(i);
      if (ch>=256) {
        console.warn("Attempted to send non-8 bit character - code "+ch);
        ch = "?".charCodeAt(0);
      }
      bufView[i] = ch;
    }
    return buf;
  };

  var closeSerial=function() {
    if (currentDevice) {
      currentDevice.close();
      currentDevice = undefined;
    } else
      console.error("Close called, but serial port not open");
  };

  var isConnected = function() {
    return currentDevice!==undefined;
  };

  var writeSerialWorker = function(isStarting) {
    writeTimeout = undefined; // we've been called

    // if we disconnected while sending, empty queue
    if (currentDevice === undefined) {
      if (writeData[0].callback)
        writeData[0].callback();
      writeData.shift();
      if (writeData.length) setTimeout(function() {
        writeSerialWorker(false);
      }, 1);
      return;
    }

    if (writeData[0].data === "") {
      if (writeData[0].showStatus)
        Espruino.Core.Status.setStatus("Sent");
      if (writeData[0].callback)
        writeData[0].callback();
      writeData.shift(); // remove this empty first element
      if (!writeData.length) return; // anything left to do?
      isStarting = true;
    }

    if (isStarting) {
      var blockSize = 512;
      if (currentDevice.maxWriteLength)
        blockSize = currentDevice.maxWriteLength;
      /* if we're throttling our writes we want to send small
       * blocks of data at once. We still limit the size of
       * sent blocks to 512 because on Mac we seem to lose
       * data otherwise (not on any other platforms!) */
      if (slowWrite) blockSize=19;
      writeData[0].blockSize = blockSize;

      writeData[0].showStatus &= writeData[0].data.length>writeData[0].blockSize;
      if (writeData[0].showStatus) {
        Espruino.Core.Status.setStatus("Sending...", writeData[0].data.length);
        console.log("---> "+JSON.stringify(writeData[0].data));
      }
    }

    // Initial split use previous, or don't
    var d = undefined;
    var split = writeData[0].nextSplit || { start:0, end:writeData[0].data.length, delay:0 };
    // if we get something like Ctrl-C or `reset`, wait a bit for it to complete
    if (!sendingBinary) {
      function findSplitIdx(prev, substr, delay, reason) {
        var match = writeData[0].data.match(substr);
        // not found
        if (match===null) return prev;
        // or previous find was earlier in str
        var end = match.index + match[0].length;
        if (end > prev.end) return prev;
        // found, and earlier
        prev.start = match.index;
        prev.end = end;
        prev.delay = delay;
        prev.match = match[0];
        prev.reason = reason;
        return prev;
      }
      split = findSplitIdx(split, /\x03/, 250, "Ctrl-C"); // Ctrl-C
      split = findSplitIdx(split, /reset\(\);\n/, 250, "reset()"); // Reset
      split = findSplitIdx(split, /load\(\);\n/, 250, "load()"); // Load
      split = findSplitIdx(split, /Modules.addCached\("[^\n]*"\);\n/, 250, "Modules.addCached"); // Adding a module
      split = findSplitIdx(split, /\x10require\("Storage"\).write\([^\n]*\);\n/, 500, "Storage.write"); // Write chunk of data
    }
    // Otherwise split based on block size
    if (!split.match || split.end >= writeData[0].blockSize) {
      if (split.match) writeData[0].nextSplit = split;
      split = { start:0, end:writeData[0].blockSize, delay:0 };
    }
    if (split.match) console.log("Splitting for "+split.reason+", delay "+split.delay);
    // Only send some of the data
    if (writeData[0].data.length>split.end) {
      if (slowWrite && split.delay==0) split.delay=50;
      d = writeData[0].data.substr(0,split.end);
      writeData[0].data = writeData[0].data.substr(split.end);
      if (writeData[0].nextSplit) {
        writeData[0].nextSplit.start -= split.end;
        writeData[0].nextSplit.end -= split.end;
        if (writeData[0].nextSplit.end<=0)
          writeData[0].nextSplit = undefined;
      }
    } else {
      d = writeData[0].data;
      writeData[0].data = "";
      writeData[0].nextSplit = undefined;
    }
    // update status
    if (writeData[0].showStatus)
      Espruino.Core.Status.incrementProgress(d.length);
    // actually write data
    //console.log("Sending block "+JSON.stringify(d)+", wait "+split.delay+"ms");
    currentDevice.write(d, function() {
      // Once written, start timeout
      writeTimeout = setTimeout(function() {
        writeSerialWorker();
      }, split.delay);
    });
  }

   // Throttled serial write
  var writeSerial = function(data, showStatus, callback) {
    if (showStatus===undefined) showStatus=true;

    /* Queue our data to write. If there was previous data and no callback to
    invoke on this data or the previous then just append data. This would happen
    if typing in the terminal for example. */
    if (!callback && writeData.length && !writeData[writeData.length-1].callback) {
      writeData[writeData.length-1].data += data;
    } else {
      writeData.push({data:data,callback:callback,showStatus:showStatus});
      /* if this is our first data, start sending now. Otherwise we're already
      busy sending and will pull data off writeData when ready */
      if (writeData.length==1)
        writeSerialWorker(true);
    }
  };

  // ----------------------------------------------------------
  Espruino.Core.Serial = {
    "devices" : [], // List of devices that can provide a serial API
    "init" : init,
    "getPorts": getPorts,
    "open": openSerial,
    "isConnected": isConnected,
    "startListening": startListening,
    "write": writeSerial,
    "close": closeSerial,
    "isSlowWrite": function() { return slowWrite; },
    "setSlowWrite": function(isOn, force) {
      if ((!force) && Espruino.Config.SERIAL_THROTTLE_SEND) {
        console.log("ForceThrottle option is set - set Slow Write = true");
        isOn = true;
      } else
        console.log("Set Slow Write = "+isOn);
      slowWrite = isOn;
    },
    "setBinary": function(isOn) {
      sendingBinary = isOn;
    }
  };
})();
<|endoftext|>


<commit_before>import React, { Component } from "react";

const withOpeningDock = ComposedComponent => class extends Component {
	constructor() {
		super();
		this.state = {
			builderOpen: false
		};
	}

	toggleConfigurator = () => {
		this.setState({
			builderOpen: !this.state.builderOpen
		});
	}

	render() {
		if (!this.state.builderOpen) {
			return

;
		}
		return (

				<ComposedComponent {...this.props} builderOpen={this.state.builderOpen} />

		);
	}
};

export default withOpeningDock;<commit_msg>enhance builderOpen conditional logic<commit_after>import React, { Component } from "react";

const withOpeningDock = ComposedComponent => class extends Component {
	constructor() {
		super();
		this.state = {
			builderOpen: false
		};
	}

	toggleConfigurator = () => {
		this.setState({
			builderOpen: !this.state.builderOpen
		});
	}

	render() {
		return (
			<React.Fragment>
				{this.state.builderOpen ? <ComposedComponent {...this.props} builderOpen={this.state.builderOpen} /> : null }

			</React.Fragment>
		);
	}
};

export default withOpeningDock;<|endoftext|>


<commit_before>module("vie.js - Apache Stanbol Service");

test("Test stanbol connection", function() {
    var z = new VIE();
    ok(z.StanbolService, "Checking if the Stanbol Service exists.'");
    z.use(new z.StanbolService);
    ok(z.service('stanbol'));
});

test("VIE.js StanbolService - Analyze", function () {

    var elem = $('
This is a small test, where Steve Jobs sings a song.
');
    var z = new VIE();
    ok (z.StanbolService);
    equal(typeof z.StanbolService, "function");
    z.use(new z.StanbolService({url : "http://dev.iks-project.eu:8081", proxyDisabled: true}));
    stop(10000); // 10 second timeout
    z.analyze({element: elem}).using('stanbol').execute().done(function(entities) {

        ok(entities);
        ok(entities.length > 0);
        ok(entities instanceof Array);
        var allEntities = true;
        for(var i=0; i<entities.length; i++){
            var entity = entities[i];
            if (! (entity instanceof Backbone.Model)){
                allEntities = false;
                console.error("VIE.js StanbolService - Analyze: ", entity, "is not a Backbone model!");
            }
        }
        ok(allEntities);
        start();
    })
    .fail(function(f){
        ok(false, f);
        start();
    });
});

test("VIE.js StanbolService - Find", function () {
    var term = "European Union";
    var limit = 10;
    var offset = 0;
    var z = new VIE();
    ok (z.StanbolService);
    equal(typeof z.StanbolService, "function");
    z.use(new z.StanbolService({url : "http://dev.iks-project.eu:8081", proxyDisabled: true}));
    stop(10000); // 10 second timeout
    z.find({term: term, limit: limit, offset: offset})
    .using('stanbol').execute().done(function(entities) {

        ok(entities);
        ok(entities.length > 0);
        ok(entities instanceof Array);
        var allEntities = true;
        for(var i=0; i<entities.length; i++){
            var entity = entities[i];
            if (! (entity instanceof Backbone.Model)){
                allEntities = false;
                console.error("VIE.js StanbolService - Analyze: ", entity, "is not a Backbone model!");
            }
        }
        ok(allEntities);
        start();
    })
    .fail(function(f){
        ok(false, f);
        start();
    });
});

test("VIE.js StanbolService - Load", function () {

    var entity = "<http://dbpedia.org/resource/Barack_Obama>";
    var z = new VIE();
    ok (z.StanbolService);
    equal(typeof z.StanbolService, "function");
    z.use(new z.StanbolService({url : "http://dev.iks-project.eu:8081", proxyDisabled: true}));
    stop(10000); // 10 second timeout
    z.load({entity: entity})
    .using('stanbol').execute().done(function(entities) {
        ok(entities);
        ok(entities.length > 0);
        ok(entities instanceof Array);
        var allEntities = true;
        for(var i=0; i<entities.length; i++){
            var entity = entities[i];
            if (! (entity instanceof Backbone.Model)){
                allEntities = false;
                console.error("VIE.js StanbolService - Analyze: ", entity, "is not a Backbone model!");
            }
        }
        ok(allEntities);
        start();
    })
    .fail(function(f){
        ok(false, f);
        start();
    });
});

<commit_msg>The stanbol full launcher demo instance at dev.iks-project.eu:8081 is now to be reached under dev.iks-project.eu/stanbolfull.<commit_after>module("vie.js - Apache Stanbol Service");

test("Test stanbol connection", function() {
    var z = new VIE();
    ok(z.StanbolService, "Checking if the Stanbol Service exists.'");
    z.use(new z.StanbolService);
    ok(z.service('stanbol'));
});

test("VIE.js StanbolService - Analyze", function () {

    var elem = $('
This is a small test, where Steve Jobs sings a song.
');
    var z = new VIE();
    ok (z.StanbolService);
    equal(typeof z.StanbolService, "function");
    z.use(new z.StanbolService({url : "http://dev.iks-project.eu/stanbolfull", proxyDisabled: true}));
    stop(10000); // 10 second timeout
    z.analyze({element: elem}).using('stanbol').execute().done(function(entities) {

        ok(entities);
        ok(entities.length > 0);
        ok(entities instanceof Array);
        var allEntities = true;
        for(var i=0; i<entities.length; i++){
            var entity = entities[i];
            if (! (entity instanceof Backbone.Model)){
                allEntities = false;
                console.error("VIE.js StanbolService - Analyze: ", entity, "is not a Backbone model!");
            }
        }
        ok(allEntities);
        start();
    })
    .fail(function(f){
        ok(false, f);
        start();
    });
});

test("VIE.js StanbolService - Find", function () {
    var term = "European Union";
    var limit = 10;
    var offset = 0;
    var z = new VIE();
    ok (z.StanbolService);
    equal(typeof z.StanbolService, "function");
    z.use(new z.StanbolService({url : "http://dev.iks-project.eu/stanbolfull", proxyDisabled: true}));
    stop(10000); // 10 second timeout
    z.find({term: term, limit: limit, offset: offset})
    .using('stanbol').execute().done(function(entities) {

        ok(entities);
        ok(entities.length > 0);
        ok(entities instanceof Array);
        var allEntities = true;
        for(var i=0; i<entities.length; i++){
            var entity = entities[i];
            if (! (entity instanceof Backbone.Model)){
                allEntities = false;
                console.error("VIE.js StanbolService - Analyze: ", entity, "is not a Backbone model!");
            }
        }
        ok(allEntities);
        start();
    })
    .fail(function(f){
        ok(false, f);
        start();
    });
});

test("VIE.js StanbolService - Load", function () {

    var entity = "<http://dbpedia.org/resource/Barack_Obama>";
    var z = new VIE();
    ok (z.StanbolService);
    equal(typeof z.StanbolService, "function");
    z.use(new z.StanbolService({url : "http://dev.iks-project.eu/stanbolfull", proxyDisabled: true}));
    stop(10000); // 10 second timeout
    z.load({entity: entity})
    .using('stanbol').execute().done(function(entities) {
        ok(entities);
        ok(entities.length > 0);
        ok(entities instanceof Array);
        var allEntities = true;
        for(var i=0; i<entities.length; i++){
            var entity = entities[i];
            if (! (entity instanceof Backbone.Model)){
                allEntities = false;
                console.error("VIE.js StanbolService - Analyze: ", entity, "is not a Backbone model!");
            }
        }
        ok(allEntities);
        start();
    })
    .fail(function(f){
        ok(false, f);
        start();
    });
});

<|endoftext|>


<commit_before>
define([
  'jquery',
  'underscore',
  'backbone',
  'helpers/app',
  'helpers/conf',
  'text!templates/conf.html',
  'text!templates/add_usertag_modal.html',
  'helpers/nav',
  'helpers/usertag',
], function($, _, Backbone, AppHelper, ConfHelper, ConfTemplate,
            AddUsertagModalTemplate, NavHelper, UserTagHelper){

  var ConfView = Backbone.View.extend ({
    el: '#main',

    initialize: function () {
      NavHelper.initialize ('Ayarlar');
    },

    render: function () {

      $(this.el).append (_.template (ConfTemplate,
                                     { options: ConfHelper.options }));

      // usertag form modal
      // this is a bit messy but modal must be placed in body
      if (!$('#add-usertag-modal').length) {
        var that = this;
        $('body').append (_.template (AddUsertagModalTemplate));
        $('#add-usertag-button').click(function () {
          that.addUserTag();
          return false;
        });
        $('#add-usertag-modal').on('shown.bs.modal', function () {
          $('#add-usertag-username').focus()
        });
      }

      this.loadUserTags();

    },

    events: {
      'click ul.theme a': 'changeTheme',
      'click div.font a': 'changeFont',
      'change input': 'changeOption',
      'change #index-page': 'changeIndex',
      'click #remove-usertag-button': 'removeUserTag',
      'click a[href="#about"]': 'about'
    },

    changeTheme: function (ev) {
      var theme = $(ev.currentTarget).attr ('href').replace (/^#/, '');

      ConfHelper.options.theme = theme;
      ConfHelper.switchTheme ();
      ConfHelper.saveConf ();

      return false;
    },

    changeFont: function (ev) {
      var font = $(ev.currentTarget).attr ('href').replace (/^#/, '');

      ConfHelper.options.font = font;
      ConfHelper.switchFont ();
      ConfHelper.saveConf ();

      $(this.el).find('div.font a').each(function() {
        $(this).removeClass('active');
      });
      $(ev.currentTarget).addClass('active');

      return false;
    },

    changeOption: function (ev) {
      var option = $(ev.currentTarget).attr ('value');
      var val = $(ev.currentTarget).is (':checked');

      // FIXME: poor design. Listening change input is causing this
      if (option == 'channel') {
        var channel = $(ev.currentTarget).attr('data-channel');
        ConfHelper.setChannel(channel, val);
        AppHelper.sidebarView.fillChannelsMenu();
      } else {
        ConfHelper.setOption (option, val);
      }

    },

    changeIndex: function (ev) {

      var newIndex = $(ev.currentTarget).find('option:selected').text();

      if (ConfHelper.options.index != newIndex) {
        ConfHelper.options.index = newIndex;
        ConfHelper.saveConf();
      }
    },

    loadUserTags: function () {
      $('#usertag-list').html('');
      _.map(UserTagHelper.userTags, function(tags, user) {
        var tags_s = '';
        _.each(tags, function(tag) {
          $('#usertag-list').append($('<option>').text(user + ': ' + tag));
        });
      });
    },

    addUserTag: function () {

      var username = $('#add-usertag-username').val();
      var usertag = $('#add-usertag-tag').val();
      if (!username || !usertag) {
        return;
      }

      UserTagHelper.addUserTag(username, usertag);
      this.loadUserTags();

      $('#add-usertag-modal').modal('hide');

    },

    removeUserTag: function (ev) {
      $('#usertag-list').find('option:selected').each(function() {
        var tag = $(this).text().split(': ');
        UserTagHelper.removeUserTag(tag[0], tag[1]);
        $(this).remove();
      });
      return false;
    },

    about: function () {
      AppHelper.welcome(true);
      return false;
    }

  });

  return ConfView;

});
<commit_msg>Stop loder on conf view<commit_after>
define([
  'jquery',
  'underscore',
  'backbone',
  'helpers/app',
  'helpers/conf',
  'text!templates/conf.html',
  'text!templates/add_usertag_modal.html',
  'helpers/nav',
  'helpers/usertag',
], function($, _, Backbone, AppHelper, ConfHelper, ConfTemplate,
            AddUsertagModalTemplate, NavHelper, UserTagHelper){

  var ConfView = Backbone.View.extend ({
    el: '#main',

    initialize: function () {
      NavHelper.initialize ('Ayarlar');

      // FIXME: Navhelper stucking for some reason
      NavHelper.loader(false);
    },

    render: function () {

      $(this.el).append (_.template (ConfTemplate,
                                     { options: ConfHelper.options }));

      // usertag form modal
      // this is a bit messy but modal must be placed in body
      if (!$('#add-usertag-modal').length) {
        var that = this;
        $('body').append (_.template (AddUsertagModalTemplate));
        $('#add-usertag-button').click(function () {
          that.addUserTag();
          return false;
        });
        $('#add-usertag-modal').on('shown.bs.modal', function () {
          $('#add-usertag-username').focus()
        });
      }

      this.loadUserTags();

    },

    events: {
      'click ul.theme a': 'changeTheme',
      'click div.font a': 'changeFont',
      'change input': 'changeOption',
      'change #index-page': 'changeIndex',
      'click #remove-usertag-button': 'removeUserTag',
      'click a[href="#about"]': 'about'
    },

    changeTheme: function (ev) {
      var theme = $(ev.currentTarget).attr ('href').replace (/^#/, '');

      ConfHelper.options.theme = theme;
      ConfHelper.switchTheme ();
      ConfHelper.saveConf ();

      return false;
    },

    changeFont: function (ev) {
      var font = $(ev.currentTarget).attr ('href').replace (/^#/, '');

      ConfHelper.options.font = font;
      ConfHelper.switchFont ();
      ConfHelper.saveConf ();

      $(this.el).find('div.font a').each(function() {
        $(this).removeClass('active');
      });
      $(ev.currentTarget).addClass('active');

      return false;
    },

    changeOption: function (ev) {
      var option = $(ev.currentTarget).attr ('value');
      var val = $(ev.currentTarget).is (':checked');

      // FIXME: poor design. Listening change input is causing this
      if (option == 'channel') {
        var channel = $(ev.currentTarget).attr('data-channel');
        ConfHelper.setChannel(channel, val);
        AppHelper.sidebarView.fillChannelsMenu();
      } else {
        ConfHelper.setOption (option, val);
      }

    },

    changeIndex: function (ev) {

      var newIndex = $(ev.currentTarget).find('option:selected').text();

      if (ConfHelper.options.index != newIndex) {
        ConfHelper.options.index = newIndex;
        ConfHelper.saveConf();
      }
    },

    loadUserTags: function () {
      $('#usertag-list').html('');
      _.map(UserTagHelper.userTags, function(tags, user) {
        var tags_s = '';
        _.each(tags, function(tag) {
          $('#usertag-list').append($('<option>').text(user + ': ' + tag));
        });
      });
    },

    addUserTag: function () {

      var username = $('#add-usertag-username').val();
      var usertag = $('#add-usertag-tag').val();
      if (!username || !usertag) {
        return;
      }

      UserTagHelper.addUserTag(username, usertag);
      this.loadUserTags();

      $('#add-usertag-modal').modal('hide');

    },

    removeUserTag: function (ev) {
      $('#usertag-list').find('option:selected').each(function() {
        var tag = $(this).text().split(': ');
        UserTagHelper.removeUserTag(tag[0], tag[1]);
        $(this).remove();
      });
      return false;
    },

    about: function () {
      AppHelper.welcome(true);
      return false;
    }

  });

  return ConfView;

});
<|endoftext|>


<commit_before>'use strict';

require('jasmine-expect');
var _ = require('lodash');

describe('suggesters', function () {

  var suggesters;

  beforeEach(function () {
    suggesters = require('../../src/suggesters');
  });

  it('should provide a URL for making suggestions', function () {
    expect(suggesters.getSuggestUrl('text')).toEqual('http://data.gramene.org/suggest/genes?');
    expect(suggesters.getSuggestUrl('GO')).toEqual('http://data.gramene.org/search/GO?');
  });

  it('should not provide a URL for anything that\'s not a suggester', function () {
    ['geness', '', undefined, new Date(), Array.prototype].map(function (notAcore) {
      var thrower = function () { suggesters.getSuggestUrl(notAcore) };
      expect(thrower).toThrow();
    });
  });

  it('should filter GO suggestions based on namespace', function () {
    var fParams = suggesters.getSuggestParams('GO_f', 'hello');
    var pParams = suggesters.getSuggestParams('GO_p', 'hello');
    var cParams = suggesters.getSuggestParams('GO_c', 'hello');

    expect(fParams.fq).toEqual("namespace_s:molecular_function");
    expect(pParams.fq).toEqual("namespace_s:biological_process");
    expect(cParams.fq).toEqual("namespace_s:cellular_component");
  })
});
<commit_msg>fix the broken teset<commit_after>'use strict';

require('jasmine-expect');
var _ = require('lodash');

describe('suggesters', function () {

  var suggesters;

  beforeEach(function () {
    suggesters = require('../../src/suggesters');
  });

  it('should provide a URL for making suggestions', function () {
    expect(suggesters.getSuggestUrl('text')).toEqual('http://data.gramene.org/suggest/genes?');
    expect(suggesters.getSuggestUrl('GO_f')).toEqual('http://data.gramene.org/search/GO?');
  });

  it('should not provide a URL for anything that\'s not a suggester', function () {
    ['geness', '', undefined, new Date(), Array.prototype].map(function (notAcore) {
      var thrower = function () { suggesters.getSuggestUrl(notAcore) };
      expect(thrower).toThrow();
    });
  });

  it('should filter GO suggestions based on namespace', function () {
    var fParams = suggesters.getSuggestParams('GO_f', 'hello');
    var pParams = suggesters.getSuggestParams('GO_p', 'hello');
    var cParams = suggesters.getSuggestParams('GO_c', 'hello');

    expect(fParams.fq).toEqual("namespace_s:molecular_function");
    expect(pParams.fq).toEqual("namespace_s:biological_process");
    expect(cParams.fq).toEqual("namespace_s:cellular_component");
  })
});
<|endoftext|>


<commit_before>// vim: set sw=4 ts=4 et:

QUnit.specify('', function () {

    describe('setValue', function () {
        var wrapper = $('#slider'), slider;

        after(function () {
            wrapper.html('');
        });

        describe('when setting a value', function () {
            before(function () {
                slider = new $.Quinn(wrapper);
                slider.setValue(50);
            });

            it('should set the new value', function () {
                assert(slider.model.value).equals(50);
            });

            it('should not permit values larger than the selectable range', function () {
                assert(slider.setValue(101)).equals(100);
                assert(slider.model.value).equals(100);
            });

            it('should not permit values smaller than the selectable range', function () {
                assert(slider.setValue(-1)).equals(0);
                assert(slider.model.value).equals(0);
            });

            it('should run the drag callback', function () {
                var dragRun = false;

                slider = new $.Quinn(wrapper, {
                    drag: function () {
                        dragRun = true;
                    }
                });

                slider.setValue(50);
                assert(dragRun).isTrue();
            });

            it('should run the change callback', function () {
                var changeRun = false;

                slider = new $.Quinn(wrapper, {
                    change: function () {
                        changeRun = true;
                    }
                });

                slider.setValue(50);
                assert(changeRun).isTrue();
            });
        }); // when setting a value

        describe('when the slider is disabled', function () {
            before(function () {
                slider = new $.Quinn(wrapper, { disable: true });
            });

            it('should not change the slider value', function () {
                assert(slider.setValue(50)).equals(false)
                assert(slider.model.value).equals(0);
            });
        }); // when the slider is disabled

        describe('when given no argument', function () {
            before(function () {
                slider = new $.Quinn(wrapper, { value: 50 });
            });

            it('should do nothing', function () {
                assert(slider.setValue()).equals(50);
                assert(slider.model.value).equals(50);
            });
        }); // when given no argument

        describe('when the value does not match the step', function () {
            before(function () {
                slider = new $.Quinn(wrapper, { step: 7 });
            });

            it('should round to the nearest step', function () {
                var values = [ 0, 6, 7, 8, 9, 10, 11 ],
                    rounds = [ 0, 7, 7, 7, 7,  7, 14 ],
                    rounded;

                rounded = _.map(values, function (value) {
                    slider.setValue(value);
                    return slider.model.value;
                });

                assert(rounded).isSameAs(rounds);
            });
        }); // when the value does not match the step

        describe('when the drag callback returns false', function () {
            var changeRun;

            before(function () {
                slider = new $.Quinn(wrapper, {
                    drag:   function () { return false },
                    change: function () { changeRun = true; }
                });
            });

            it('should not change the slider value', function () {
                assert(slider.setValue(5)).equals(0);
                assert(slider.model.value).equals(0);
            });

            it('should not run change', function () {
                slider.setValue(5);
                assert(changeRun).isFalse();
            });
        }); // when the drag callback returns false

        describe('when the change callback returns false', function () {
            before(function () {
                slider = new $.Quinn(wrapper, {
                    change: function () { return false }
                });
            });

            it('should not change the slider value', function () {
                assert(slider.setValue(5)).equals(0);
                assert(slider.model.value).equals(0);
            });
        }); // when the change callback returns false

        describe('when the value is unchanged', function () {
            var dragRun, changeRun;

            before(function () {
                slider = new $.Quinn(wrapper, {
                    drag:   function () { dragRun   = true; },
                    change: function () { changeRun = true; }
                });

                dragRun   = false;
                changeRun = false;

                slider.setValue(0);
            });

            it('should not run drag', function () {
                assert(dragRun).isFalse();
            });

            it('should not run change', function () {
                assert(changeRun).isFalse();
            });
        }); // when the value is unchanged

        describe('when the value is unchanged during a drag operation', function () {
            var dragRun, changeRun, abortRun;

            before(function () {
                slider = new $.Quinn(wrapper, {
                    drag:   function () { dragRun   = true; },
                    change: function () { changeRun = true; },
                    abort:  function () { abortRun  = true; }
                });

                dragRun   = false;
                changeRun = false;

                slider.willChange();
                slider.setTentativeValue(50);
                slider.setTentativeValue(0);
                slider.hasChanged();
            });

            it('should drag', function () {
                assert(dragRun).isTrue();
            });

            it('should not run change', function () {
                assert(changeRun).isFalse();
            });

            it('should run abort', function () {
                assert(abortRun).isTrue();
            });
        }); // when the value is unchanged

        describe('when using the only option', function () {
            before(function () {
                slider = new $.Quinn(wrapper, { value: 40, only: [10, 20, 50] });
            });

            it('should do nothing when given no argument', function () {
                assert(slider.setValue()).equals(50);
                assert(slider.model.value).equals(50);
            });

            it('should set the given value', function () {
                assert(slider.setValue(20)).equals(20);
                assert(slider.model.value).equals(20);

                assert(slider.setValue(10)).equals(10);
                assert(slider.model.value).equals(10);
            });

            it('should set the nearest value when not exact', function () {
                assert(slider.setValue(40)).equals(50);
                assert(slider.model.value).equals(50);
            });
        }); // when using the only option

        describe('when using a range-based slider', function () {
            before(function () {
                slider = new $.Quinn(wrapper, { value: [25, 75] });
            });

            it('should set the new values', function () {
                slider.setValue([10, 90]);
                assert(_.isEqual([10, 90], slider.model.value)).isTrue();
            });

            it('should not permit an integer value', function () {
                assert(_.isEqual(slider.setValue(10), [25, 75])).isTrue();
                assert(_.isEqual([25, 75], slider.model.value)).isTrue();
            });
        });
    });
});
<commit_msg>Fix a test which used the old API.<commit_after>// vim: set sw=4 ts=4 et:

QUnit.specify('', function () {

    describe('setValue', function () {
        var wrapper = $('#slider'), slider;

        after(function () {
            wrapper.html('');
        });

        describe('when setting a value', function () {
            before(function () {
                slider = new $.Quinn(wrapper);
                slider.setValue(50);
            });

            it('should set the new value', function () {
                assert(slider.model.value).equals(50);
            });

            it('should not permit values larger than the selectable range', function () {
                assert(slider.setValue(101)).equals(100);
                assert(slider.model.value).equals(100);
            });

            it('should not permit values smaller than the selectable range', function () {
                assert(slider.setValue(-1)).equals(0);
                assert(slider.model.value).equals(0);
            });

            it('should run the drag callback', function () {
                var dragRun = false;

                slider = new $.Quinn(wrapper, {
                    drag: function () {
                        dragRun = true;
                    }
                });

                slider.setValue(50);
                assert(dragRun).isTrue();
            });

            it('should run the change callback', function () {
                var changeRun = false;

                slider = new $.Quinn(wrapper, {
                    change: function () {
                        changeRun = true;
                    }
                });

                slider.setValue(50);
                assert(changeRun).isTrue();
            });
        }); // when setting a value

        describe('when the slider is disabled', function () {
            before(function () {
                slider = new $.Quinn(wrapper, { disable: true });
            });

            it('should not change the slider value', function () {
                assert(slider.setValue(50)).equals(false)
                assert(slider.model.value).equals(0);
            });
        }); // when the slider is disabled

        describe('when given no argument', function () {
            before(function () {
                slider = new $.Quinn(wrapper, { value: 50 });
            });

            it('should do nothing', function () {
                assert(slider.setValue()).equals(50);
                assert(slider.model.value).equals(50);
            });
        }); // when given no argument

        describe('when the value does not match the step', function () {
            before(function () {
                slider = new $.Quinn(wrapper, { step: 7 });
            });

            it('should round to the nearest step', function () {
                var values = [ 0, 6, 7, 8, 9, 10, 11 ],
                    rounds = [ 0, 7, 7, 7, 7,  7, 14 ],
                    rounded;

                rounded = _.map(values, function (value) {
                    slider.setValue(value);
                    return slider.model.value;
                });

                assert(rounded).isSameAs(rounds);
            });
        }); // when the value does not match the step

        describe('when the drag callback returns false', function () {
            var changeRun;

            before(function () {
                slider = new $.Quinn(wrapper, {
                    drag:   function () { return false },
                    change: function () { changeRun = true; }
                });
            });

            it('should not change the slider value', function () {
                assert(slider.setValue(5)).equals(0);
                assert(slider.model.value).equals(0);
            });

            it('should not run change', function () {
                slider.setValue(5);
                assert(changeRun).isFalse();
            });
        }); // when the drag callback returns false

        describe('when the change callback returns false', function () {
            before(function () {
                slider = new $.Quinn(wrapper, {
                    change: function () { return false }
                });
            });

            it('should not change the slider value', function () {
                assert(slider.setValue(5)).equals(0);
                assert(slider.model.value).equals(0);
            });
        }); // when the change callback returns false

        describe('when the value is unchanged', function () {
            var dragRun, changeRun;

            before(function () {
                slider = new $.Quinn(wrapper, {
                    drag:   function () { dragRun   = true; },
                    change: function () { changeRun = true; }
                });

                dragRun   = false;
                changeRun = false;

                slider.setValue(0);
            });

            it('should not run drag', function () {
                assert(dragRun).isFalse();
            });

            it('should not run change', function () {
                assert(changeRun).isFalse();
            });
        }); // when the value is unchanged

        describe('when the value is unchanged during a drag operation', function () {
            var dragRun, changeRun, abortRun;

            before(function () {
                slider = new $.Quinn(wrapper, {
                    drag:   function () { dragRun   = true; },
                    change: function () { changeRun = true; },
                    abort:  function () { abortRun  = true; }
                });

                dragRun   = false;
                changeRun = false;

                slider.start();
                slider.setTentativeValue(50);
                slider.setTentativeValue(0);
                slider.resolve();
            });

            it('should drag', function () {
                assert(dragRun).isTrue();
            });

            it('should not run change', function () {
                assert(changeRun).isFalse();
            });

            it('should run abort', function () {
                assert(abortRun).isTrue();
            });
        }); // when the value is unchanged

        describe('when using the only option', function () {
            before(function () {
                slider = new $.Quinn(wrapper, { value: 40, only: [10, 20, 50] });
            });

            it('should do nothing when given no argument', function () {
                assert(slider.setValue()).equals(50);
                assert(slider.model.value).equals(50);
            });

            it('should set the given value', function () {
                assert(slider.setValue(20)).equals(20);
                assert(slider.model.value).equals(20);

                assert(slider.setValue(10)).equals(10);
                assert(slider.model.value).equals(10);
            });

            it('should set the nearest value when not exact', function () {
                assert(slider.setValue(40)).equals(50);
                assert(slider.model.value).equals(50);
            });
        }); // when using the only option

        describe('when using a range-based slider', function () {
            before(function () {
                slider = new $.Quinn(wrapper, { value: [25, 75] });
            });

            it('should set the new values', function () {
                slider.setValue([10, 90]);
                assert(_.isEqual([10, 90], slider.model.value)).isTrue();
            });

            it('should not permit an integer value', function () {
                assert(_.isEqual(slider.setValue(10), [25, 75])).isTrue();
                assert(_.isEqual([25, 75], slider.model.value)).isTrue();
            });
        });
    });
});
<|endoftext|>


<commit_before>'use strict';

/* global app */
var Backbone = require('../shims/backbone');
var View = Backbone.View;
var $ = require('../shims/jquery');
var _ = require('lodash');
var ViewSwitcher = require('ampersand-view-switcher');
var templates = require('../lib/templates');

module.exports = View.extend({
  template: templates.body,
  events: {
    'click a[href]:not([rel="download"])': 'handleLinkClick',
    'scroll': 'handleScrolling'
  },

  render: function () {
    var self = this;
    this.$el.html(this.template());

    $(window).scroll(this.handleScrolling.bind(this));
    function getClasses(view) {
      if (typeof(view) !== 'object' || typeof(view.customDocumentClasses) !== 'function') {
        return [];
      }
      return view.customDocumentClasses();
    }

    this.pageSwitcher = new ViewSwitcher(this.$('[role="page-container"]')[0], {
      show: function (newView) {
        document.title = newView.pageTitle || 'Learn Foward';
        window.scrollTo(0, 0);
        var html = $('html');
        _.each(self.documentClasses, function (c) {
          html.removeClass(c);
        });
        self.documentClasses = getClasses(newView);
        _.each(self.documentClasses, function (c) {
          html.addClass(c);
        });

        app.currentPage = newView;
      }
    });

    this.$('.nav a').on('click', function () {
      if (window.innerWidth < 768) {
        self.$('.navbar-toggle').click();
      }
    });

    return this;
  },

  setPage: function (view) {
    this.pageSwitcher.set(view);
  },

  handleLinkClick: function (e) {
    var t = $(e.target);
    var aEl = t.is('a') ? t[0] : t.closest('a')[0];
    var local = window.location.host === aEl.host;
    var path = aEl.pathname.slice(1);

    // If the window location host and target host are the
    // same it's local, else, leave it alone.
    if (local) {
      e.preventDefault();
      app.navigate(path);
    }
  },
  handleScrolling: function () {
    var scrollPos = $(window).scrollTop();
    var state = (scrollPos > 10);
    this.$('.navbar').toggleClass('nav-scrolled', state);
  }
});
<commit_msg>Forgot bout this.<commit_after>'use strict';

/* global app */
var Backbone = require('../shims/backbone');
var View = Backbone.View;
var $ = require('../shims/jquery');
var _ = require('lodash');
var ViewSwitcher = require('ampersand-view-switcher');
var templates = require('../lib/templates');

module.exports = View.extend({
  template: templates.body,
  events: {
    'click a[href]:not([rel="download"])': 'handleLinkClick',
    'scroll': 'handleScrolling'
  },

  render: function () {
    var self = this;
    this.$el.html(this.template());

    $(window).scroll(this.handleScrolling.bind(this));
    function getClasses(view) {
      if (typeof(view) !== 'object' || typeof(view.customDocumentClasses) !== 'function') {
        return [];
      }
      return view.customDocumentClasses();
    }

    this.pageSwitcher = new ViewSwitcher(this.$('[role="page-container"]')[0], {
      show: function (newView) {
        document.title = newView.pageTitle || 'Learn Forward';
        window.scrollTo(0, 0);
        var html = $('html');
        _.each(self.documentClasses, function (c) {
          html.removeClass(c);
        });
        self.documentClasses = getClasses(newView);
        _.each(self.documentClasses, function (c) {
          html.addClass(c);
        });

        app.currentPage = newView;
      }
    });

    this.$('.nav a').on('click', function () {
      if (window.innerWidth < 768) {
        self.$('.navbar-toggle').click();
      }
    });

    return this;
  },

  setPage: function (view) {
    this.pageSwitcher.set(view);
  },

  handleLinkClick: function (e) {
    var t = $(e.target);
    var aEl = t.is('a') ? t[0] : t.closest('a')[0];
    var local = window.location.host === aEl.host;
    var path = aEl.pathname.slice(1);

    // If the window location host and target host are the
    // same it's local, else, leave it alone.
    if (local) {
      e.preventDefault();
      app.navigate(path);
    }
  },
  handleScrolling: function () {
    var scrollPos = $(window).scrollTop();
    var state = (scrollPos > 10);
    this.$('.navbar').toggleClass('nav-scrolled', state);
  }
});
<|endoftext|>


<commit_before>// require('babel-core/register');
// require('babel-polyfill');
require('./build/server.js');

<commit_msg>dummy checkin to trigger build<commit_after>require('./build/server.js');

<|endoftext|>


<commit_before>//https://xanadu1010.wordpress.com/2013/03/09/usando-javascript-para-pegar-valores-enviados-a-pagina-html-via-get/
		function _GET(name)
		{
		  var url   = window.location.search.replace("?", "");
		  var itens = url.split("&");

		  for(var n in itens)
		  {
		    if( itens[n].match(name) )
		    {
		      return decodeURIComponent(itens[n].replace(name+"=", ""));
		    }
		  }
		  return null;
		}
<commit_msg>corrigir erros espacamento get.js<commit_after>//https://xanadu1010.wordpress.com/2013/03/09/usando-javascript-para-pegar-valores-enviados-a-pagina-html-via-get/
function _GET(name)
{
	var url   = window.location.search.replace("?", "");
	var itens = url.split("&");

	for(var n in itens) {
		if( itens[n].match(name) ) {
			return decodeURIComponent(itens[n].replace(name+"=", ""));
		}
	}
	return null;
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Text } from 'react-native';

import styles from '../../styles/styles';
import InPageImage from '../inPageImage';
import AnimalText from '../animalText';
import AnimalTemplate from '../animalTemplate';

const IMAGES = [
  require('../../images/animals/losEvropsky/01.jpg'),
  require('../../images/animals/losEvropsky/02.jpg'),
  require('../../images/animals/losEvropsky/03.jpg'),
];

const THUMBNAILS = [
  require('../../images/animals/losEvropsky/01-thumb.jpg'),
  require('../../images/animals/losEvropsky/02-thumb.jpg'),
  require('../../images/animals/losEvropsky/03-thumb.jpg'),
];

var AnimalDetail = React.createClass({
  render() {
    return (
      <AnimalTemplate firstIndex={[1]} thumbnails={THUMBNAILS} images={IMAGES} navigator={this.props.navigator}>
        <AnimalText>
          Největší příslušník čeledi jelenovitých je los evropský (lat. <Text style={styles.italic}>Alces alces</Text>). Běžně dorůstá délky dvou až tří metrů. Samice váží okolo tří set kilogramů, samec může být až dvakrát těžší a poznáte ho podle parohů. Parohy většinou tvarem připomínají lopaty, ale mohou vypadat i jako parůžky. Pořádné parohy mohou vážit až dvacet kilogramů, avšak každý rok je samec shazuje a poté čeká, až mu narostou nové. Losi se dožívají osmi až patnácti let.
        </AnimalText>
        <AnimalText>
          Jak nejlépe losa popsat? Stavbou je los podobný koni. Na krku, který je kratší než u koní, mu roste hříva. Rozhodně není tak dlouhá a působivá jako u koní.
        </AnimalText>
        <InPageImage indexes={[2]} thumbnails={THUMBNAILS} images={IMAGES} navigator={this.props.navigator} />
        <AnimalText>
          Tlama se u losa a koně podstatně liší. Los má převislý horní pysk. Díky tomu se nám může zdát, že se spíš podobá oslovi. Charakteristickým rysem je pro losa špatný zrak, ale výborný sluch a čich. Kvůli výbornému sluchu je los velmi citlivý na hluk. Z toho důvodu se zdržuje jen v místech, která nejsou silně poznamenána lidskou civilizací. Takových míst postupně ubývá, což se na populaci losů odráží.
        </AnimalText>
        <AnimalText>
          Srst losů je hustší než u ostatních jelenovitých. Je to proto, že losi jsou zvyklí na velmi chladná klimata. Čím chladnější klima, tím hustší srst losovi naroste. Největší výskyt losů je v lesích a v bažinách na severu Evropy, Asie a Ameriky. Kdysi žili hojně i u nás, nyní se však řadí na seznam silně ohrožených zvířat.
        </AnimalText>
        <AnimalText>
          Všimli jste si kopyt? Nejsou obyčejná... Kopyta jsou širší, než jaká známe u koně. Ale proč? Jak již bylo zmíněno, losi žijí i v bažinách. V takových místech potřebují rozložit svou obrovskou hmotnost. Dokážou běžet rychlostí až 50 km/h. Díky jejich širokým kopytům se při běhu nikdy nepropadnou do bahna.
        </AnimalText>
        <InPageImage indexes={[0]} thumbnails={THUMBNAILS} images={IMAGES} navigator={this.props.navigator} />
        <AnimalText>
          Los patří k podřádu přežvýkavců. Požírá listy stromků a sní dokonce i kůru stromů nebo vodní rostliny. Pokud se chce los nažrat trávy, musí kvůli svému krátkému krku pořádně rozkročit nohy, aby dosáhl hlavou na zem.
        </AnimalText>
        <AnimalText>
          Los je tvor samotářský. Samec a samice žijí zpravidla odděleně. V období říje se samci ozývají sténáním, až kvílením, a lákají tak samice. Mnoho samců je v této době agresivní a může zaútočit i na člověka. Samice je březí asi devět měsíců a mívá jedno až tři mláďata. Pokusy o domestikaci byly většinou neúspěšné.
        </AnimalText>
        <AnimalText>

        </AnimalText>
        <AnimalText>
          Zajímavost:
        </AnimalText>
        <AnimalText>
          Autorem nejstarší písemnosti o losech je Gaius Julius Caesar. Ve svém díle Zápisky o válce galské popisuje, jak nejlépe ulovit losa. Caesar tvrdil, že losi spí opření o strom, protože prý nemají klouby a nemohou si lehnout. Stačí prý pokácet strom, o který se los opírá. Los spadne a už se nezvedne. Toto tvrzení ale není pravdivé.
        </AnimalText>
      </AnimalTemplate>
    );
  }
});

module.exports = AnimalDetail;
<commit_msg>Update losEvropsky.adult.js<commit_after>import React, { Component } from 'react';
import { Text } from 'react-native';

import styles from '../../styles/styles';
import InPageImage from '../inPageImage';
import AnimalText from '../animalText';
import AnimalTemplate from '../animalTemplate';

const IMAGES = [
  require('../../images/animals/losEvropsky/01.jpg'),
  require('../../images/animals/losEvropsky/02.jpg'),
  require('../../images/animals/losEvropsky/03.jpg'),
];

const THUMBNAILS = [
  require('../../images/animals/losEvropsky/01-thumb.jpg'),
  require('../../images/animals/losEvropsky/02-thumb.jpg'),
  require('../../images/animals/losEvropsky/03-thumb.jpg'),
];

var AnimalDetail = React.createClass({
  render() {
    return (
      <AnimalTemplate firstIndex={[1]} thumbnails={THUMBNAILS} images={IMAGES} navigator={this.props.navigator}>
        <AnimalText>
          Největší příslušník čeledi jelenovitých je los evropský (lat. <Text style={styles.italic}>Alces alces</Text>). Běžně dorůstá délky dvou až tří metrů. Samice váží okolo tří set kilogramů, samec může být až dvakrát těžší a poznáte ho podle parohů. Parohy většinou tvarem připomínají lopaty, ale mohou vypadat i jako parůžky. Pořádné parohy mohou vážit až dvacet kilogramů, avšak každý rok je samec shazuje a poté čeká, až mu narostou nové. Losi se dožívají osmi až patnácti let.
        </AnimalText>
        <AnimalText>
          Jak nejlépe losa popsat? Stavbou těla je podobný koni. Na krku, který je kratší než u koní, mu roste hříva. Rozhodně však není tak dlouhá a působivá.
        </AnimalText>
        <InPageImage indexes={[2]} thumbnails={THUMBNAILS} images={IMAGES} navigator={this.props.navigator} />
        <AnimalText>
          Tlama se u losa a koně podstatně liší. Los má převislý horní pysk. Díky tomu se nám může zdát, že se spíš podobá oslovi. Charakteristickým rysem je pro něj špatný zrak, ale výborný sluch a čich. Kvůli výbornému sluchu je velmi citlivý na hluk. Z toho důvodu se zdržuje jen v místech, která nejsou silně poznamenána lidskou civilizací. Takových míst postupně ubývá, což se na populaci losů odráží.
        </AnimalText>
        <AnimalText>
          Srst losů je hustší než u ostatních jelenovitých. Je to proto, že losi jsou zvyklí na velmi chladná klimata. Čím chladnější klima, tím hustší srst mu naroste. Největší výskyt těchto zvířat je v lesích a v bažinách na severu Evropy, Asie a Ameriky. Kdysi žili hojně i u nás, nyní se však řadí na seznam silně ohrožených zvířat.
        </AnimalText>
        <AnimalText>
          Všimli jste si jejich kopyt? Nejsou obyčejná... Kopyta jsou širší, než jaká známe u koně. Ale proč? Jak již bylo zmíněno, losi žijí i v bažinách. V takových místech potřebují rozložit svou obrovskou hmotnost, aby se nepropadali do bahna. Dokážou běžet rychlostí až 50 km/h.
        </AnimalText>
        <InPageImage indexes={[0]} thumbnails={THUMBNAILS} images={IMAGES} navigator={this.props.navigator} />
        <AnimalText>
          Losi patří k podřádu přežvýkavců. Požírají listy stromků a sní dokonce i kůru stromů nebo vodní rostliny. Pokud se chtějí nažrat trávy, musí kvůli svému krátkému krku pořádně rozkročit nohy, aby dosáhli hlavou na zem.
        </AnimalText>
        <AnimalText>
          Tito tvorové jsou samotáři. Samec a samice žijí zpravidla odděleně. V období říje se samci ozývají sténáním až kvílením, a lákají tak samice. Mnoho samců je v této době agresivní a může zaútočit i na člověka. Samice jsou březí asi devět měsíců a mívají jedno až tři mláďata. Pokusy o domestikaci byly většinou neúspěšné.
        </AnimalText>
        <AnimalText>

        </AnimalText>
        <AnimalText>
          Zajímavost:
        </AnimalText>
        <AnimalText>
          Autorem nejstarší písemnosti o losech je Gaius Julius Caesar. Ve svém díle Zápisky o válce galské popisuje, jak nejlépe ulovit losa. Caesar tvrdil, že losi spí opření o strom, protože prý nemají klouby a nemohou si lehnout. Stačí prý pokácet strom, o který se los opírá. Los spadne a už se nezvedne. Toto tvrzení ale není pravdivé.
        </AnimalText>
      </AnimalTemplate>
    );
  }
});

module.exports = AnimalDetail;
<|endoftext|>


<commit_before>import Ember from 'ember';

var get = Ember.get;

/*
  Holds a stack of key responder views. With this we can neatly handle
  restoring the previous key responder when some modal UI element is closed.
  There are a few simple rules that governs the usage of the stack:
   - mouse click does .replace (this should also be used for programmatically taking focus when not a modal element)
   - opening a modal UI element does .push
   - closing a modal element does .pop

  Also noteworthy is that a view will be signaled that it loses the key focus
  only when it's popped off the stack, not when something is pushed on top. The
  idea is that when a modal UI element is opened, we know that the previously
  focused view will re-gain the focus as soon as the modal element is closed.
  So if the previously focused view was e.g. in the middle of some edit
  operation, it shouldn't cancel that operation.
*/
var KeyResponder = Ember.ArrayProxy.extend({
  init: function() {
    this.set('content', Ember.A());
    this._super();
  },

  current: Ember.computed.readOnly('lastObject'),
  pushView: function(view, wasTriggeredByFocus) {
    if (!Ember.none(view)) {
      view.trigger('willBecomeKeyResponder', wasTriggeredByFocus);
      this.pushObject(view);
      view.trigger('didBecomeKeyResponder', wasTriggeredByFocus);
    }
    return view;
  },

  popView: function(wasTriggeredByFocus) {
    if (get(this, 'length') > 0) {
      var view = get(this, 'current');
      if (view) {
        view.trigger('willLoseKeyResponder', wasTriggeredByFocus);
      }
      view = this.popObject();
      view.trigger('didLoseKeyResponder', wasTriggeredByFocus);
      return view;
    } else {
      return undefined;
    }
  },

  replaceView: function(view, wasTriggeredByFocus) {
    if (get(this, 'current') !== view) {
      this.popView(wasTriggeredByFocus);
      return this.pushView(view, wasTriggeredByFocus);
    }
  }
});

export default KeyResponder;

export var KEY_EVENTS = {
  8: 'deleteBackward',
  9: 'insertTab',
  13: 'insertNewline',
  27: 'cancel',
  32: 'insertSpace',
  37: 'moveLeft',
  38: 'moveUp',
  39: 'moveRight',
  40: 'moveDown',
  46: 'deleteForward'
};

export var MODIFIED_KEY_EVENTS = {
  8: 'deleteForward',
  9: 'insertBacktab',
  37: 'moveLeftAndModifySelection',
  38: 'moveUpAndModifySelection',
  39: 'moveRightAndModifySelection',
  40: 'moveDownAndModifySelection'
};

var KeyResponderSupportViewMixin = Ember.Mixin.create({
  // Set to true in your view if you want to accept key responder status (which
  // is needed for handling key events)
  acceptsKeyResponder: false,
  canBecomeKeyResponder: Ember.computed('acceptsKeyResponder',
                                        'disabled',
                                        'isVisible', function() {
    return get(this, 'acceptsKeyResponder') &&
          !get(this, 'disabled') &&
           get(this, 'isVisible');
  }).readOnly(),

  init: function() {
    this._super();
    this.on('mouseDown', this, this.becomeKeyResponder);
  },

  /*
    Sets this view as the target of key events. Call this if you need to make
    this happen programmatically.  This gets also called on mouseDown if the
    view handles that, returns true and doesn't have property
    'acceptsKeyResponder'
    set to false. If mouseDown returned true but 'acceptsKeyResponder' is
    false, this call is propagated to the parent view.

    If called with no parameters or with replace = true, the current key
    responder is first popped off the stack and this view is then pushed. See
    comments for Ember.KeyResponderStack above for more insight.
  */
  becomeKeyResponder: function(replace, wasTriggeredByFocus) {
    if (wasTriggeredByFocus === undefined) {
      wasTriggeredByFocus = false;
    }

    var keyResponder = get(this, 'keyResponder');

    if (!keyResponder) {
      return;
    }

    if (get(keyResponder, 'current') === this) {
      return;
    }

    if (get(this, 'canBecomeKeyResponder')) {
      if (replace === undefined || replace === true) {
        return keyResponder.replaceView(this, wasTriggeredByFocus);
      } else {
        return keyResponder.pushView(this, wasTriggeredByFocus);
      }
    } else {
      var parent = get(this, 'parentView');

      if (parent && parent.becomeKeyResponder) {
        return parent.becomeKeyResponder(replace, wasTriggeredByFocus);
      }
    }
  },

  becomeKeyResponderViaFocus: function() {
    return this.becomeKeyResponder(true, true);
  },

  /*
    Resign key responder status by popping the head off the stack. The head
    might or might not be this view, depending on whether user clicked anything
    since this view became the key responder. The new key responder
    will be the next view in the stack, if any.
  */
  resignKeyResponder: function(wasTriggeredByFocus) {
    if (wasTriggeredByFocus === undefined) {
      wasTriggeredByFocus = false;
    }

    var keyResponder = get(this, 'keyResponder');

    if (!keyResponder) {
      return;
    }

    keyResponder.popView(wasTriggeredByFocus);
  },

  resignKeyResponderViaFocus: function() {
    return this.resignKeyResponder(true);
  },

  respondToKeyEvent: function(event) {
    Ember.run(this, function() {
      if (get(this, 'keyResponder.current.canBecomeKeyResponder')) {
        view.interpretKeyEvents(event);
      }
    });
  },

  interpretKeyEvents: function(event) {
    var mapping = event.shiftKey ? MODIFIED_KEY_EVENTS : KEY_EVENTS;
    var eventName = mapping[event.keyCode];

    if (eventName && this.has(eventName)) {
      return this.trigger(eventName, event);
    }

    return false;
  }
});

Ember.View.reopen(KeyResponderSupportViewMixin);
Ember.Component.reopen(KeyResponderSupportViewMixin);

export var KeyResponderInputSupport = Ember.Mixin.create({
  acceptsKeyResponder: true,
  init: function () {
    this._super();
    this.on('focusIn', this, this.becomeKeyResponderViaFocus);
    this.on('focusOut', this, this.resignKeyResponderViaBlur);
  },

  didBecomeKeyResponder: function(wasTriggeredByFocus){
    if (!wasTriggeredByFocus && this._state === 'inDOM') {
      this.$().focus();
    }
  },

  didLoseKeyResponder: function(wasTriggeredByFocus){
    if (!wasTriggeredByFocus && this._state === 'inDOM') {
      this.$().blur();
    }
  }
});

Ember.TextSupport.reopen(KeyResponderInputSupport);
Ember.Checkbox.reopen(KeyResponderInputSupport);
Ember.Select.reopen(KeyResponderInputSupport);
<commit_msg>actually fix the issue<commit_after>import Ember from 'ember';

var get = Ember.get;

/*
  Holds a stack of key responder views. With this we can neatly handle
  restoring the previous key responder when some modal UI element is closed.
  There are a few simple rules that governs the usage of the stack:
   - mouse click does .replace (this should also be used for programmatically taking focus when not a modal element)
   - opening a modal UI element does .push
   - closing a modal element does .pop

  Also noteworthy is that a view will be signaled that it loses the key focus
  only when it's popped off the stack, not when something is pushed on top. The
  idea is that when a modal UI element is opened, we know that the previously
  focused view will re-gain the focus as soon as the modal element is closed.
  So if the previously focused view was e.g. in the middle of some edit
  operation, it shouldn't cancel that operation.
*/
var KeyResponder = Ember.ArrayProxy.extend({
  init: function() {
    this.set('content', Ember.A());
    this._super();
  },

  current: Ember.computed.readOnly('lastObject'),
  pushView: function(view, wasTriggeredByFocus) {
    if (!Ember.none(view)) {
      view.trigger('willBecomeKeyResponder', wasTriggeredByFocus);
      this.pushObject(view);
      view.trigger('didBecomeKeyResponder', wasTriggeredByFocus);
    }
    return view;
  },

  popView: function(wasTriggeredByFocus) {
    if (get(this, 'length') > 0) {
      var view = get(this, 'current');
      if (view) {
        view.trigger('willLoseKeyResponder', wasTriggeredByFocus);
      }
      view = this.popObject();
      view.trigger('didLoseKeyResponder', wasTriggeredByFocus);
      return view;
    } else {
      return undefined;
    }
  },

  replaceView: function(view, wasTriggeredByFocus) {
    if (get(this, 'current') !== view) {
      this.popView(wasTriggeredByFocus);
      return this.pushView(view, wasTriggeredByFocus);
    }
  }
});

export default KeyResponder;

export var KEY_EVENTS = {
  8: 'deleteBackward',
  9: 'insertTab',
  13: 'insertNewline',
  27: 'cancel',
  32: 'insertSpace',
  37: 'moveLeft',
  38: 'moveUp',
  39: 'moveRight',
  40: 'moveDown',
  46: 'deleteForward'
};

export var MODIFIED_KEY_EVENTS = {
  8: 'deleteForward',
  9: 'insertBacktab',
  37: 'moveLeftAndModifySelection',
  38: 'moveUpAndModifySelection',
  39: 'moveRightAndModifySelection',
  40: 'moveDownAndModifySelection'
};

var KeyResponderSupportViewMixin = Ember.Mixin.create({
  // Set to true in your view if you want to accept key responder status (which
  // is needed for handling key events)
  acceptsKeyResponder: false,
  canBecomeKeyResponder: Ember.computed('acceptsKeyResponder',
                                        'disabled',
                                        'isVisible', function() {
    return get(this, 'acceptsKeyResponder') &&
          !get(this, 'disabled') &&
           get(this, 'isVisible');
  }).readOnly(),

  init: function() {
    this._super();
    this.on('mouseDown', this, this.becomeKeyResponder);
  },

  /*
    Sets this view as the target of key events. Call this if you need to make
    this happen programmatically.  This gets also called on mouseDown if the
    view handles that, returns true and doesn't have property
    'acceptsKeyResponder'
    set to false. If mouseDown returned true but 'acceptsKeyResponder' is
    false, this call is propagated to the parent view.

    If called with no parameters or with replace = true, the current key
    responder is first popped off the stack and this view is then pushed. See
    comments for Ember.KeyResponderStack above for more insight.
  */
  becomeKeyResponder: function(replace, wasTriggeredByFocus) {
    if (wasTriggeredByFocus === undefined) {
      wasTriggeredByFocus = false;
    }

    var keyResponder = get(this, 'keyResponder');

    if (!keyResponder) {
      return;
    }

    if (get(keyResponder, 'current') === this) {
      return;
    }

    if (get(this, 'canBecomeKeyResponder')) {
      if (replace === undefined || replace === true) {
        return keyResponder.replaceView(this, wasTriggeredByFocus);
      } else {
        return keyResponder.pushView(this, wasTriggeredByFocus);
      }
    } else {
      var parent = get(this, 'parentView');

      if (parent && parent.becomeKeyResponder) {
        return parent.becomeKeyResponder(replace, wasTriggeredByFocus);
      }
    }
  },

  becomeKeyResponderViaFocus: function() {
    return this.becomeKeyResponder(true, true);
  },

  /*
    Resign key responder status by popping the head off the stack. The head
    might or might not be this view, depending on whether user clicked anything
    since this view became the key responder. The new key responder
    will be the next view in the stack, if any.
  */
  resignKeyResponder: function(wasTriggeredByFocus) {
    if (wasTriggeredByFocus === undefined) {
      wasTriggeredByFocus = false;
    }

    var keyResponder = get(this, 'keyResponder');

    if (!keyResponder) {
      return;
    }

    keyResponder.popView(wasTriggeredByFocus);
  },

  resignKeyResponderViaFocus: function() {
    return this.resignKeyResponder(true);
  },

  respondToKeyEvent: function(event) {
    Ember.run(this, function() {
      if (get(this, 'keyResponder.current.canBecomeKeyResponder')) {
        get(this, 'keyResponder.current').interpretKeyEvents(event);
      }
    });
  },

  interpretKeyEvents: function(event) {
    var mapping = event.shiftKey ? MODIFIED_KEY_EVENTS : KEY_EVENTS;
    var eventName = mapping[event.keyCode];

    if (eventName && this.has(eventName)) {
      return this.trigger(eventName, event);
    }

    return false;
  }
});

Ember.View.reopen(KeyResponderSupportViewMixin);
Ember.Component.reopen(KeyResponderSupportViewMixin);

export var KeyResponderInputSupport = Ember.Mixin.create({
  acceptsKeyResponder: true,
  init: function () {
    this._super();
    this.on('focusIn', this, this.becomeKeyResponderViaFocus);
    this.on('focusOut', this, this.resignKeyResponderViaBlur);
  },

  didBecomeKeyResponder: function(wasTriggeredByFocus){
    if (!wasTriggeredByFocus && this._state === 'inDOM') {
      this.$().focus();
    }
  },

  didLoseKeyResponder: function(wasTriggeredByFocus){
    if (!wasTriggeredByFocus && this._state === 'inDOM') {
      this.$().blur();
    }
  }
});

Ember.TextSupport.reopen(KeyResponderInputSupport);
Ember.Checkbox.reopen(KeyResponderInputSupport);
Ember.Select.reopen(KeyResponderInputSupport);
<|endoftext|>


<commit_before>
var c;
var ctx;

var WIDTH = 800, HEIGHT = 300;

function init() {
    c = document.getElementById("mainCanvas");
    c.width = WIDTH;
    c.height = HEIGHT;
    ctx = c.getContext("2d");
}

function line(x1, y1, x2, y2) {
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
}

var lineGapHeight = 20;

function drawStaff(x, y, length) {
    for (var i = 0; i < 5; i++) {
        line(x, y, x + length, y);
        y += lineGapHeight;
    }
}

init();
drawStaff(25, 25, 750);
drawStaff(25, 150, 750);
<commit_msg>add function to draw quarter, half, and whole notes<commit_after>
var c;
var ctx;

var WIDTH = 800, HEIGHT = 300;

function init() {
    c = document.getElementById("mainCanvas");
    c.width = WIDTH;
    c.height = HEIGHT;
    ctx = c.getContext("2d");
}

function line(x1, y1, x2, y2) {
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
}

var lineGapHeight = 20;

function drawStaff(x, y, length) {
    for (var i = 0; i < 5; i++) {
        line(x, y, x + length, y);
        y += lineGapHeight;
    }
}

// scaled so that duration 1 -> quarter note, 2 -> half note, etc.
function drawNote(x, y, duration) {
    ctx.save();
    ctx.translate(x, y);
    ctx.scale(1.3, 1);

    ctx.beginPath();
    ctx.arc(0, 0, 6, 0, Math.PI*2);
    ctx.closePath();

    if (duration == 1) {
        ctx.fill();
        ctx.moveTo(6, 0);
        ctx.lineTo(6, -30);
        ctx.stroke();
    } else if (duration == 2) {
        ctx.stroke();
        ctx.moveTo(6, 0);
        ctx.lineTo(6, -30);
        ctx.stroke();
    } else if (duration == 4) {
        ctx.stroke();
    }

    ctx.restore();
}

init();
drawStaff(25, 25, 750);
drawStaff(25, 150, 750);
drawNote(25, 25, 4);
<|endoftext|>