<commit_before>// Defines a set of WS2812 LED Pixels for use

// TODO:
//
// Pixels can be arranged into different structures // NICE TO HAVE
// Do we want to call it strip and pixels?
// Do we have a grid which can be 1D, 2D or 3D and any size
// Pixels needs to have a length, various deets on where it is (clock etc)
// Pixels can be on a single pin or separate ones (possible with I2C as well)
// Deal with different pixel types
// Keyframing // NICE TO HAVE
// Pixel grid should be able to:
//      - Set pixels in a range from X->Y a colour
//
//
require("es6-collections");

var ColorString = require("color-string"); // used for color parsing
var events = require("events");
var util = require("util");

// create a helper to output an int so messages can be shorter
ColorString.colorValue = function colorValue (colors) {
    // colors are assumed to be an array of [r, g, b] bytes
    // colorValue returns a packed value able to be pushed to firmata rather than
    // text values.

    return ((colors[0] << 16) + (colors[1] << 8) + (colors[2]));
}

// CONSTANTS
var START_SYSEX =   0xF0,
STRING_DATA =       0x71,
END_SYSEX =         0xF7,
FIRMATA_7BIT_MASK = 0x7F,
PIXEL_COMMAND =     0x51,
PIXEL_OFF =         0x00,
PIXEL_CONFIG =      0x01,
PIXEL_SHOW =        0x02,
PIXEL_SET_PIXEL =   0x03,
PIXEL_SET_STRIP =   0x04;

var PIN_DEFAULT = 6; // use this if not supplied

var I2C_DEFAULT =   0x42;

var Controllers = {
    FIRMATA: {
        initialize: {
            value: function(opts) {

                var strip_length = opts.length || 6; // just an arbitrary val
                var data_pin = opts.data || DEFAULT_PIN;
                var firmata = opts.firmata || opts.board.io;

                if (firmata == undefined) {
                    throw "Either a firmata object or board object is required";
                }

                var pixels = [];

                for (var i=0; i< strip_length; i++) {
                    pixels.push(new Pixel({
                        addr: i,
                        firmata: firmata,
                        controller: "FIRMATA"
                    }) );
                }

                if (opts.board != undefined && opts.board.io.name != "Firmata") {
                    throw "Node Pixel FIRMATA controller only supports firmata boards";
                    return;
                }

                strips.set(this, {
                    pixels: pixels,
                    data: 6,
                    firmata: firmata,
                });

                // now send the config message with length and data point.
                var data   = [];

                data[0] = START_SYSEX;
                data[1] = PIXEL_COMMAND;
                data[2] = PIXEL_CONFIG;
                data[3] = data_pin;
                data[4] = strip_length & FIRMATA_7BIT_MASK;
                data[5] = (strip_length >> 7) & FIRMATA_7BIT_MASK;
                data[6] = END_SYSEX;

                firmata.sp.write(new Buffer(data), function(error, res) {
                    var err = null;
                    if (error) {
                        err = error;
                        this.emit("error", err);
                    }
                    this.emit("ready", err);

                }.bind(this) );
            },
        },
        show: {
            value: function() {

                // call the frame on the strip.
                var strip = strips.get(this);

                var data   = [];
                data[0] = START_SYSEX;
                data[1] = PIXEL_COMMAND;
                data[2] = PIXEL_SHOW;
                data[3] = END_SYSEX;

                // now just write that to the serialport and it should show the frame.
                strip.firmata.sp.write(new Buffer(data));
            },
        },
        strip_color: {
            value: function(color) {
                // colour work is already done this just sets it the appropriate
                // way.
                var strip = strips.get(this);
                var data   = [];

                data[0] = START_SYSEX;
                data[1] = PIXEL_COMMAND;
                data[2] = PIXEL_SET_STRIP;
                data[3] = color & FIRMATA_7BIT_MASK;
                data[4] = (color >> 7) & FIRMATA_7BIT_MASK;
                data[5] = (color >> 14) & FIRMATA_7BIT_MASK;
                data[6] = (color >> 21) & FIRMATA_7BIT_MASK;
                data[7] = END_SYSEX;

                strip.firmata.sp.write(new Buffer(data));
            },
        },
    },
    I2CBACKPACK: {
        initialize: {
            value: function(opts) {

                var strip_length = opts.length || 6; // just an arbitrary val

                var io = opts.firmata || opts.board.io;
                var i2caddr = opts.address || I2C_DEFAULT;
                if (io == undefined) {
                    throw "An IO object is required to I2C controller";
                }

                var pixels = [];

                for (var i=0; i< strip_length; i++) {
                    pixels.push(new Pixel({
                        addr: i,
                        io: io,
                        controller: "I2CBACKPACK",
                        i2c_address: i2caddr,
                    }) );
                }

                strips.set(this, {
                    pixels: pixels,
                    io: io,
                    i2c_address: i2caddr,
                });

                // send the I2C config message.
                io.i2cConfig();
                process.nextTick(function() {
                    this.emit("ready", null)
                }.bind(this) );
            },
        },
        show: {
            value: function() {

                var strip = strips.get(this);
                strip.io.i2cWrite(strip.i2c_address, [PIXEL_SHOW]);
            },
        },
        strip_color: {
            value: function(color) {
                var strip = strips.get(this);
                var data   = [];

                data[0] = PIXEL_SET_STRIP;

                data[1] = color & FIRMATA_7BIT_MASK;
                data[2] = (color >> 7) & FIRMATA_7BIT_MASK;
                data[3] = (color >> 14) & FIRMATA_7BIT_MASK;
                data[4] = (color >> 21) & FIRMATA_7BIT_MASK;

                strip.io.i2cWrite(strip.i2c_address, data);
            },
        },
    },
};

var strips = new WeakMap();

function Strip(opts) {

    // opts contains an object with.
    // data: data pin for the pixel strip
    // board: johnny five board object.
    // controller: controller type to use
    // firmata: actual firmata object if preferred
    // length: length of the pixel strip.

    if (!(this instanceof Strip)) {
        return new Strip(opts);
    }

    var controller;

    if (typeof opts.controller === "string") {
        controller = Controllers[opts.controller];
    } else {
        controller = opts.controller || Controllers["FIRMATA"];
    }

    Object.defineProperties(this, controller);

    if (typeof this.initialize === "function") {
        this.initialize(opts);
    }

}

util.inherits(Strip, events.EventEmitter);

Strip.prototype.pixel = function(addr) {
    var strip = strips.get(this);

    return strip.pixels[addr];
};

Strip.prototype.colour = Strip.prototype.color = function(color, opts) {
    // sets the color of the entire strip
    // use a particular form to set the color either
    // color = hex value or named colors
    // or set color null and set opt which is an object as {rgb: [rx, gx, bx]}
    // values where x is an 8-bit value (0-255);
    var strip = strips.get(this);

    var stripcolor = null;

    if (color) {
        // use text to determine the color
        stripcolor = ColorString.getRgb(color) || null;

    } else if (opts) {
        // use rgb array to determine color
        stripcolor = opts.rgb || null;
    }

    if (stripcolor != null) {
        // fill out the values for the pixels and then update the strip

        for (var i = 0; i < strip.pixels.length; i++) {
            strip.pixels[i].color(color, {sendmsg: false});
        }

        color = ColorString.colorValue(stripcolor);

        this.strip_color(color);

    } else {
        console.log("color supplied couldn't be parsed: " + stripcolor);
    }
}

Strip.prototype.stripLength = function() {
    // gets the number of pixels in the strip
    var strip = strips.get(this);
    return (strip.pixels.length);
}

var pixels = new WeakMap();

// controllers for the pixel side as well.
var Pixel_Controllers = {
    FIRMATA: {
        initialize: {
            value: function(opts) {
                // initialises the base object

                var pixel = {
                    addr: opts.addr,
                    color: {
                        r: 0, g: 0, b: 0, hexcode: "#000000", color: "black", rgb: [0,0,0],
                    },
                    firmata: opts.firmata,
                };

                return pixel;
            },
        },
        pixel_color: {
            value: function(color) {
                // sets the actual pixel colour
                var pixel = pixels.get(this);

                var data   = [];

                data.push(START_SYSEX);
                data.push(PIXEL_COMMAND);
                data.push(PIXEL_SET_PIXEL);
                data.push(pixel.addr & FIRMATA_7BIT_MASK);
                data.push((pixel.addr >> 7) & FIRMATA_7BIT_MASK);
                data.push(color & FIRMATA_7BIT_MASK);
                data.push((color >> 7) & FIRMATA_7BIT_MASK);
                data.push((color >> 14) & FIRMATA_7BIT_MASK);
                data.push((color >> 21) & FIRMATA_7BIT_MASK);
                data.push(END_SYSEX);

                pixel.firmata.sp.write(new Buffer(data));
            },
        },
    },
    I2CBACKPACK: {
        initialize: {
            value: function(opts) {
                // initialises the base object

                var pixel = {
                    addr: opts.addr,
                    color: {
                        r: 0, g: 0, b: 0, hexcode: "#000000", color: "black", rgb: [0,0,0],
                    },
                    io: opts.io,
                    i2c_address: opts.i2c_address,
                };

                return pixel;
            },
        },
        pixel_color: {
            value: function(color) {
                // sets the actual pixel colour
                var pixel = pixels.get(this);

                var data   = [];

                data.push(PIXEL_SET_PIXEL);
                data.push(pixel.addr & FIRMATA_7BIT_MASK);
                data.push((pixel.addr >> 7) & FIRMATA_7BIT_MASK);
                data.push(color & FIRMATA_7BIT_MASK);
                data.push((color >> 7) & FIRMATA_7BIT_MASK);
                data.push((color >> 14) & FIRMATA_7BIT_MASK);
                data.push((color >> 21) & FIRMATA_7BIT_MASK);

                pixel.io.i2cWrite(pixel.i2c_address, data);
            },
        },
    },
};

function Pixel(opts) {

    if (!(this instanceof Pixel)) {
        return new Pixel(opts);
    }

    var controller;

    if (typeof opts.controller === "string") {
        controller = Pixel_Controllers[opts.controller];
    } else {
        controller = opts.controller || Pixel_Controllers["FIRMATA"];
    }

    Object.defineProperties(this, controller);

    pixels.set(this, this.initialize(opts));
}

Pixel.prototype.colour = Pixel.prototype.color = function(color, opts) {
    // use a particular form to set the color either
    // color = hex value or named colors
    // or set color null and set opt which is an object as {r:x, g:x, b:x}
    // values where x is an 8-bit value (0-255);
    // opts can contain _sendmsg_ as bool. If set to false message won't be
    // sent to firmata - useful for strip level updates to keep message choke down

    var pixel = pixels.get(this);

    var options = opts || {};
    var sendmsg = true;
    if (options.sendmsg != undefined) { sendmsg = options.sendmsg; }

    var pixelcolor = null;
    if (color) {
        // get the color based on a string
        pixelcolor = ColorString.getRgb(color) || null;
    } else if (opts) {
        // set using rgb value
        pixelcolor = options.rgb || null;
    } else {
        return pixel.color;
    }

    if (pixelcolor != null) {
        // fill out the values for the pixel and then send the message to update
        // it on the strip

        with (pixel.color) {
            r = pixelcolor[0];
            g = pixelcolor[1];
            b = pixelcolor[2];
            hexcode = ColorString.hexString(pixelcolor);
            color = ColorString.keyword(pixelcolor);
            rgb = pixelcolor;
        }

        color = ColorString.colorValue(pixelcolor);
        if (sendmsg) {
            this.pixel_color(color);
        }
    } else {
        console.log("color supplied couldn't be parsed: " + pixelcolor);
    }
};

module.exports = { Strip: Strip};
<commit_msg>Modified to abstract the write port away on the firmata object<commit_after>// Defines a set of WS2812 LED Pixels for use

// TODO:
//
// Pixels can be arranged into different structures // NICE TO HAVE
// Do we want to call it strip and pixels?
// Do we have a grid which can be 1D, 2D or 3D and any size
// Pixels needs to have a length, various deets on where it is (clock etc)
// Pixels can be on a single pin or separate ones (possible with I2C as well)
// Deal with different pixel types
// Keyframing // NICE TO HAVE
// Pixel grid should be able to:
//      - Set pixels in a range from X->Y a colour
//
//
require("es6-collections");

var ColorString = require("color-string"); // used for color parsing
var events = require("events");
var util = require("util");

// create a helper to output an int so messages can be shorter
ColorString.colorValue = function colorValue (colors) {
    // colors are assumed to be an array of [r, g, b] bytes
    // colorValue returns a packed value able to be pushed to firmata rather than
    // text values.

    return ((colors[0] << 16) + (colors[1] << 8) + (colors[2]));
}

// CONSTANTS
var START_SYSEX =   0xF0,
STRING_DATA =       0x71,
END_SYSEX =         0xF7,
FIRMATA_7BIT_MASK = 0x7F,
PIXEL_COMMAND =     0x51,
PIXEL_OFF =         0x00,
PIXEL_CONFIG =      0x01,
PIXEL_SHOW =        0x02,
PIXEL_SET_PIXEL =   0x03,
PIXEL_SET_STRIP =   0x04;

var PIN_DEFAULT = 6; // use this if not supplied

var I2C_DEFAULT =   0x42;

var Controllers = {
    FIRMATA: {
        initialize: {
            value: function(opts) {

                var strip_length = opts.length || 6; // just an arbitrary val
                var data_pin = opts.data || DEFAULT_PIN;
                var firmata = opts.firmata || opts.board.io;

                if (firmata == undefined) {
                    throw "Either a firmata or board object is required";
                    return;
                }

                // figure out where we are writing to
                var port = firmata.sp || firmata.write;

                if (port === undefined) {
                    throw "Node Pixel FIRMATA controller only supports firmata IO that can write out";
                    return;
                }

                var pixels = [];

                for (var i=0; i< strip_length; i++) {
                    pixels.push(new Pixel({
                        addr: i,
                        firmata: firmata,
                        port: port,
                        controller: "FIRMATA"
                    }) );
                }

                /** debating if this is still needed
                if (opts.board != undefined && opts.board.io.name != "Firmata") {
                    throw "Node Pixel FIRMATA controller only supports firmata boards";
                    return;
                }**/

                strips.set(this, {
                    pixels: pixels,
                    data: 6,
                    firmata: firmata,
                    port: port,
                });

                // now send the config message with length and data point.
                var data   = [];

                data[0] = START_SYSEX;
                data[1] = PIXEL_COMMAND;
                data[2] = PIXEL_CONFIG;
                data[3] = data_pin;
                data[4] = strip_length & FIRMATA_7BIT_MASK;
                data[5] = (strip_length >> 7) & FIRMATA_7BIT_MASK;
                data[6] = END_SYSEX;

                port.write(new Buffer(data), function(error, res) {
                    var err = null;
                    if (error) {
                        err = error;
                        this.emit("error", err);
                    }
                    this.emit("ready", err);

                }.bind(this) );
            },
        },
        show: {
            value: function() {

                // call the frame on the strip.
                var strip = strips.get(this);

                var data   = [];
                data[0] = START_SYSEX;
                data[1] = PIXEL_COMMAND;
                data[2] = PIXEL_SHOW;
                data[3] = END_SYSEX;

                // now just write that to the port and it should show the frame.
                strip.port.write(new Buffer(data));
            },
        },
        strip_color: {
            value: function(color) {
                // colour work is already done this just sets it the appropriate
                // way.
                var strip = strips.get(this);
                var data   = [];

                data[0] = START_SYSEX;
                data[1] = PIXEL_COMMAND;
                data[2] = PIXEL_SET_STRIP;
                data[3] = color & FIRMATA_7BIT_MASK;
                data[4] = (color >> 7) & FIRMATA_7BIT_MASK;
                data[5] = (color >> 14) & FIRMATA_7BIT_MASK;
                data[6] = (color >> 21) & FIRMATA_7BIT_MASK;
                data[7] = END_SYSEX;

                strip.port.write(new Buffer(data));
            },
        },
    },
    I2CBACKPACK: {
        initialize: {
            value: function(opts) {

                var strip_length = opts.length || 6; // just an arbitrary val

                var io = opts.firmata || opts.board.io;
                var i2caddr = opts.address || I2C_DEFAULT;
                if (io == undefined) {
                    throw "An IO object is required to I2C controller";
                }

                var pixels = [];

                for (var i=0; i< strip_length; i++) {
                    pixels.push(new Pixel({
                        addr: i,
                        io: io,
                        controller: "I2CBACKPACK",
                        i2c_address: i2caddr,
                    }) );
                }

                strips.set(this, {
                    pixels: pixels,
                    io: io,
                    i2c_address: i2caddr,
                });

                // send the I2C config message.
                io.i2cConfig();
                process.nextTick(function() {
                    this.emit("ready", null)
                }.bind(this) );
            },
        },
        show: {
            value: function() {

                var strip = strips.get(this);
                strip.io.i2cWrite(strip.i2c_address, [PIXEL_SHOW]);
            },
        },
        strip_color: {
            value: function(color) {
                var strip = strips.get(this);
                var data   = [];

                data[0] = PIXEL_SET_STRIP;

                data[1] = color & FIRMATA_7BIT_MASK;
                data[2] = (color >> 7) & FIRMATA_7BIT_MASK;
                data[3] = (color >> 14) & FIRMATA_7BIT_MASK;
                data[4] = (color >> 21) & FIRMATA_7BIT_MASK;

                strip.io.i2cWrite(strip.i2c_address, data);
            },
        },
    },
};

var strips = new WeakMap();

function Strip(opts) {

    // opts contains an object with.
    // data: data pin for the pixel strip
    // board: johnny five board object.
    // controller: controller type to use
    // firmata: actual firmata object if preferred
    // length: length of the pixel strip.

    if (!(this instanceof Strip)) {
        return new Strip(opts);
    }

    var controller;

    if (typeof opts.controller === "string") {
        controller = Controllers[opts.controller];
    } else {
        controller = opts.controller || Controllers["FIRMATA"];
    }

    Object.defineProperties(this, controller);

    if (typeof this.initialize === "function") {
        this.initialize(opts);
    }

}

util.inherits(Strip, events.EventEmitter);

Strip.prototype.pixel = function(addr) {
    var strip = strips.get(this);

    return strip.pixels[addr];
};

Strip.prototype.colour = Strip.prototype.color = function(color, opts) {
    // sets the color of the entire strip
    // use a particular form to set the color either
    // color = hex value or named colors
    // or set color null and set opt which is an object as {rgb: [rx, gx, bx]}
    // values where x is an 8-bit value (0-255);
    var strip = strips.get(this);

    var stripcolor = null;

    if (color) {
        // use text to determine the color
        stripcolor = ColorString.getRgb(color) || null;

    } else if (opts) {
        // use rgb array to determine color
        stripcolor = opts.rgb || null;
    }

    if (stripcolor != null) {
        // fill out the values for the pixels and then update the strip

        for (var i = 0; i < strip.pixels.length; i++) {
            strip.pixels[i].color(color, {sendmsg: false});
        }

        color = ColorString.colorValue(stripcolor);

        this.strip_color(color);

    } else {
        console.log("color supplied couldn't be parsed: " + stripcolor);
    }
}

Strip.prototype.stripLength = function() {
    // gets the number of pixels in the strip
    var strip = strips.get(this);
    return (strip.pixels.length);
}

var pixels = new WeakMap();

// controllers for the pixel side as well.
var Pixel_Controllers = {
    FIRMATA: {
        initialize: {
            value: function(opts) {
                // initialises the base object

                var pixel = {
                    addr: opts.addr,
                    color: {
                        r: 0, g: 0, b: 0, hexcode: "#000000", color: "black", rgb: [0,0,0],
                    },
                    firmata: opts.firmata,
                    port: opts.port
                };

                return pixel;
            },
        },
        pixel_color: {
            value: function(color) {
                // sets the actual pixel colour
                var pixel = pixels.get(this);

                var data   = [];

                data.push(START_SYSEX);
                data.push(PIXEL_COMMAND);
                data.push(PIXEL_SET_PIXEL);
                data.push(pixel.addr & FIRMATA_7BIT_MASK);
                data.push((pixel.addr >> 7) & FIRMATA_7BIT_MASK);
                data.push(color & FIRMATA_7BIT_MASK);
                data.push((color >> 7) & FIRMATA_7BIT_MASK);
                data.push((color >> 14) & FIRMATA_7BIT_MASK);
                data.push((color >> 21) & FIRMATA_7BIT_MASK);
                data.push(END_SYSEX);

                pixel.port.write(new Buffer(data));
            },
        },
    },
    I2CBACKPACK: {
        initialize: {
            value: function(opts) {
                // initialises the base object

                var pixel = {
                    addr: opts.addr,
                    color: {
                        r: 0, g: 0, b: 0, hexcode: "#000000", color: "black", rgb: [0,0,0],
                    },
                    io: opts.io,
                    i2c_address: opts.i2c_address,
                };

                return pixel;
            },
        },
        pixel_color: {
            value: function(color) {
                // sets the actual pixel colour
                var pixel = pixels.get(this);

                var data   = [];

                data.push(PIXEL_SET_PIXEL);
                data.push(pixel.addr & FIRMATA_7BIT_MASK);
                data.push((pixel.addr >> 7) & FIRMATA_7BIT_MASK);
                data.push(color & FIRMATA_7BIT_MASK);
                data.push((color >> 7) & FIRMATA_7BIT_MASK);
                data.push((color >> 14) & FIRMATA_7BIT_MASK);
                data.push((color >> 21) & FIRMATA_7BIT_MASK);

                pixel.io.i2cWrite(pixel.i2c_address, data);
            },
        },
    },
};

function Pixel(opts) {

    if (!(this instanceof Pixel)) {
        return new Pixel(opts);
    }

    var controller;

    if (typeof opts.controller === "string") {
        controller = Pixel_Controllers[opts.controller];
    } else {
        controller = opts.controller || Pixel_Controllers["FIRMATA"];
    }

    Object.defineProperties(this, controller);

    pixels.set(this, this.initialize(opts));
}

Pixel.prototype.colour = Pixel.prototype.color = function(color, opts) {
    // use a particular form to set the color either
    // color = hex value or named colors
    // or set color null and set opt which is an object as {r:x, g:x, b:x}
    // values where x is an 8-bit value (0-255);
    // opts can contain _sendmsg_ as bool. If set to false message won't be
    // sent to firmata - useful for strip level updates to keep message choke down

    var pixel = pixels.get(this);

    var options = opts || {};
    var sendmsg = true;
    if (options.sendmsg != undefined) { sendmsg = options.sendmsg; }

    var pixelcolor = null;
    if (color) {
        // get the color based on a string
        pixelcolor = ColorString.getRgb(color) || null;
    } else if (opts) {
        // set using rgb value
        pixelcolor = options.rgb || null;
    } else {
        return pixel.color;
    }

    if (pixelcolor != null) {
        // fill out the values for the pixel and then send the message to update
        // it on the strip

        with (pixel.color) {
            r = pixelcolor[0];
            g = pixelcolor[1];
            b = pixelcolor[2];
            hexcode = ColorString.hexString(pixelcolor);
            color = ColorString.keyword(pixelcolor);
            rgb = pixelcolor;
        }

        color = ColorString.colorValue(pixelcolor);
        if (sendmsg) {
            this.pixel_color(color);
        }
    } else {
        console.log("color supplied couldn't be parsed: " + pixelcolor);
    }
};

module.exports = { Strip: Strip};
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router'
import { UserBadge, LockButton } from 'components'
import { signOut } from 'store/user'
import { openModal } from 'store/layout'

const mapStateToProps = ({ user, location }) => ({
  user,
  pathname: location.pathname
})

const mapDispatchToProps = { signOut, openModal }

const propTypes = {
  user: PropTypes.object.isRequired,
  pathname: PropTypes.string.isRequired,
  openModal: PropTypes.func.isRequired,
  signOut: PropTypes.func.isRequired
}

export const Header = ({ user, signOut, openModal, pathname }) => {
  const { signedIn } = user

  // Brand and toggle get grouped for better mobile display
  const brandAndToggle = (

      <button type="button" className="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        Toggle navigation

      </button>
      Magic Cards Manager

  )

  const navigationLinks = (

        <Link to="all-cards" className={pathname === 'all-cards' ? 'active' : ''}>
          All cards
        </Link>

        <Link to="my-cards" className={pathname === 'my-cards' ? 'active' : ''}>
          My cards
        </Link>

  )

  const authenticationLinks = (

         openModal('sign in')}>
          Sign In

         openModal('sign up')}>
          Sign Up

  )

  // Collect the nav links, forms, and other content for toggling
  const userDropdown = (

          <UserBadge />

<Link to="profile">Profile</Link>

<Link to="settings">Settings</Link>

Sign out

  )

  return (

        {brandAndToggle}

          {signedIn && <LockButton />}
          {navigationLinks}
          {signedIn ? userDropdown : authenticationLinks}

  )
}

Header.propTypes = propTypes

export default connect(mapStateToProps, mapDispatchToProps)(Header)
<commit_msg>Navigation links are now hidden for non logged in users<commit_after>import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router'
import { UserBadge, LockButton } from 'components'
import { signOut } from 'store/user'
import { openModal } from 'store/layout'

const mapStateToProps = ({ user, location }) => ({
  user,
  pathname: location.pathname
})

const mapDispatchToProps = { signOut, openModal }

const propTypes = {
  user: PropTypes.object.isRequired,
  pathname: PropTypes.string.isRequired,
  openModal: PropTypes.func.isRequired,
  signOut: PropTypes.func.isRequired
}

const Header = ({ user, signOut, openModal, pathname }) => {
  const { signedIn } = user

  // Brand and toggle get grouped for better mobile display
  const brandAndToggle = (

      <button type="button" className="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        Toggle navigation

      </button>
      Magic Cards Manager

  )

  const navigationLinks = (

        <Link to="all-cards" className={pathname === 'all-cards' ? 'active' : ''}>
          All cards
        </Link>

        <Link to="my-cards" className={pathname === 'my-cards' ? 'active' : ''}>
          My cards
        </Link>

  )

  const authenticationLinks = (

         openModal('sign in')}>
          Sign In

         openModal('sign up')}>
          Sign Up

  )

  // Collect the nav links, forms, and other content for toggling
  const userDropdown = (

          <UserBadge />

<Link to="profile">Profile</Link>

<Link to="settings">Settings</Link>

Sign out

  )

  return (

        {brandAndToggle}

          {signedIn && <LockButton />}
          {signedIn && navigationLinks}
          {signedIn ? userDropdown : authenticationLinks}

  )
}

Header.propTypes = propTypes

export default connect(mapStateToProps, mapDispatchToProps)(Header)
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var leanHighlightRules = function() {

    var keywordControls = (
        [ "add_rewrite", "alias", "as", "assume", "attribute",
          "begin", "by", "calc", "calc_refl", "calc_subst", "calc_trans", "check",
          "classes", "coercions", "conjecture", "constants", "context",
          "corollary", "else", "end", "environment", "eval", "example",
          "exists", "exit", "export", "exposing", "extends", "fields", "find_decl",
          "forall", "from", "fun", "have", "help", "hiding", "if",
          "import", "in", "infix", "infixl", "infixr", "instances",
          "let", "local", "match", "namespace", "notation", "obtain", "obtains",
          "omit", "opaque", "open", "options", "parameter", "parameters", "postfix",
          "precedence", "prefix", "premise", "premises", "print", "private", "proof",
          "protected", "qed", "raw", "renaming", "section", "set_option",
          "show", "tactic_hint", "take", "then", "universe",
          "universes", "using", "variable", "variables", "with"].join("|")
    );

    var nameProviders = (
        "\\b" + ["inductive", "structure", "record", "theorem", "axiom",
         "axioms", "lemma", "hypothesis", "definition", "constant"].join("|") + "\\b"
    );

    var storageType = (
        ["Prop", "Type", "Type'", "Type₊", "Type₁", "Type₂", "Type₃"].join("|")
    );

    var storageModifiers = (
        "\\[(" +
            ["abbreviations", "all-transparent", "begin-end-hints", "class", "classes", "coercion",
             "coercions", "declarations", "decls", "instance", "irreducible",
             "multiple-instances", "notation", "notations", "parsing-only", "persistent",
             "reduce-hints", "reducible", "tactic-hints", "visible", "wf", "whnf"
            ].join("|") +
            ")\\]"
    );

    var keywordOperators = (
        [].join("|")
    );

    var keywordMapper = this.$keywords = this.createKeywordMapper({
        "keyword.control" : keywordControls,
        "storage.type" : storageType,
        "keyword.operator" : keywordOperators,
        "variable.language": "sorry",
    }, "identifier");

    var identifierRe = "[A-Za-z_\u03b1-\u03ba\u03bc-\u03fb\u1f00-\u1ffe\u2100-\u214f][A-Za-z0-9_'\u03b1-\u03ba\u03bc-\u03fb\u1f00-\u1ffe\u2070-\u2079\u207f-\u2089\u2090-\u209c\u2100-\u214f]*";
    var operatorRe = new RegExp(["#", "@", "->", "∼", "↔", "/", "==", "=", ":=", "<->",
                                 "/\\", "\\/", "∧", "∨", "≠", "<", ">", "≤", "≥", "¬",
                                 "<=", ">=", "⁻¹", "⬝", "▸", "\\+", "\\*", "-", "/",
                                 "λ", "→", "∃", "∀", ":="].join("|"));
    // regexp must not have capturing parentheses. Use (?:) instead.
    // regexps are ordered -> the first match is used

    this.$rules = {
        "start" : [
            {
                token : "comment", // single line comment "--"
                regex : "--.*$"
            },
            DocCommentHighlightRules.getStartRule("doc-start"),
            {
                token : "comment", // multi line comment "/-"
                regex : "\\/-",
                next : "comment"
            }, {
                stateName: "qqstring",
                token : "string.start", regex : '"', next : [
                    {token : "string.end", regex : '"', next : "start"},
                    {token : "constant.language.escape", regex : /\\[n"\\]/},
                    {defaultToken: "string"}
                ]
            }, {
                token : "keyword.control", regex : nameProviders, next : [
                    {token : "variable.language", regex : identifierRe, next : "start"} ]
            }, {
                token : "constant.numeric", // hex
                regex : "0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
            }, {
                token : "constant.numeric", // float
                regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
            }, {
                token : "storage.modifier",
                regex : storageModifiers
            }, {
                token : keywordMapper,
                regex : identifierRe
            }, {
                token : "operator",
                regex : operatorRe
            }, {
              token : "punctuation.operator",
              regex : "\\?|\\:|\\,|\\;|\\."
            }, {
                token : "paren.lparen",
                regex : "[[({]"
            }, {
                token : "paren.rparen",
                regex : "[\\])}]"
            }, {
                token : "text",
                regex : "\\s+"
            }
        ],
        "comment" : [ {token: "comment", regex: "-/", next: "start"},
                      {defaultToken: "comment"} ]
    };

    this.embedRules(DocCommentHighlightRules, "doc-",
        [ DocCommentHighlightRules.getEndRule("start") ]);
    this.normalizeRules();
};

oop.inherits(leanHighlightRules, TextHighlightRules);

exports.leanHighlightRules = leanHighlightRules;
});
<commit_msg>fix(ace/mode/lean_highlight_rules.js): fix axioms and constants<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var leanHighlightRules = function() {

    var keywordControls = (
        [ "add_rewrite", "alias", "as", "assume", "attribute", "axioms",
          "begin", "by", "calc", "calc_refl", "calc_subst", "calc_trans", "check",
          "classes", "coercions", "conjecture", "context",
          "corollary", "else", "end", "environment", "eval", "example",
          "exists", "exit", "export", "exposing", "extends", "fields", "find_decl",
          "forall", "from", "fun", "have", "help", "hiding", "if",
          "import", "in", "infix", "infixl", "infixr", "instances",
          "let", "local", "match", "namespace", "notation", "obtain", "obtains",
          "omit", "opaque", "open", "options", "parameter", "parameters", "postfix",
          "precedence", "prefix", "premise", "premises", "print", "private", "proof",
          "protected", "qed", "raw", "renaming", "section", "set_option",
          "show", "tactic_hint", "take", "then", "universe",
          "universes", "using", "variable", "variables", "with"].join("|")
    );

    var nameProviders = (
        ["inductive\\b", "structure\\b", "record\\b", "theorem\\b", "axiom\\b",
         "lemma\\b", "hypothesis\\b", "definition\\b", "constant\\b"].join("|")
    );

    var storageType = (
        ["Prop", "Type", "Type'", "Type₊", "Type₁", "Type₂", "Type₃"].join("|")
    );

    var storageModifiers = (
        "\\[(" +
            ["abbreviations", "all-transparent", "begin-end-hints", "class", "classes", "coercion",
             "coercions", "declarations", "decls", "instance", "irreducible",
             "multiple-instances", "notation", "notations", "parsing-only", "persistent",
             "reduce-hints", "reducible", "tactic-hints", "visible", "wf", "whnf"
            ].join("|") +
            ")\\]"
    );

    var keywordOperators = (
        [].join("|")
    );

    var keywordMapper = this.$keywords = this.createKeywordMapper({
        "keyword.control" : keywordControls,
        "storage.type" : storageType,
        "keyword.operator" : keywordOperators,
        "variable.language": "sorry",
    }, "identifier");

    var identifierRe = "[A-Za-z_\u03b1-\u03ba\u03bc-\u03fb\u1f00-\u1ffe\u2100-\u214f][A-Za-z0-9_'\u03b1-\u03ba\u03bc-\u03fb\u1f00-\u1ffe\u2070-\u2079\u207f-\u2089\u2090-\u209c\u2100-\u214f]*";
    var operatorRe = new RegExp(["#", "@", "->", "∼", "↔", "/", "==", "=", ":=", "<->",
                                 "/\\", "\\/", "∧", "∨", "≠", "<", ">", "≤", "≥", "¬",
                                 "<=", ">=", "⁻¹", "⬝", "▸", "\\+", "\\*", "-", "/",
                                 "λ", "→", "∃", "∀", ":="].join("|"));
    // regexp must not have capturing parentheses. Use (?:) instead.
    // regexps are ordered -> the first match is used

    this.$rules = {
        "start" : [
            {
                token : "comment", // single line comment "--"
                regex : "--.*$"
            },
            DocCommentHighlightRules.getStartRule("doc-start"),
            {
                token : "comment", // multi line comment "/-"
                regex : "\\/-",
                next : "comment"
            }, {
                stateName: "qqstring",
                token : "string.start", regex : '"', next : [
                    {token : "string.end", regex : '"', next : "start"},
                    {token : "constant.language.escape", regex : /\\[n"\\]/},
                    {defaultToken: "string"}
                ]
            }, {
                token : "keyword.control", regex : 'constants\\b', next : [
                    {token : "variable.language", regex : identifierRe + '[^:]*', next : "start"} ]
            }, {
                token : "keyword.control", regex : nameProviders, next : [
                    {token : "variable.language", regex : identifierRe, next : "start"} ]
            }, {
                token : "constant.numeric", // hex
                regex : "0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
            }, {
                token : "constant.numeric", // float
                regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
            }, {
                token : "storage.modifier",
                regex : storageModifiers
            }, {
                token : keywordMapper,
                regex : identifierRe
            }, {
                token : "operator",
                regex : operatorRe
            }, {
              token : "punctuation.operator",
              regex : "\\?|\\:|\\,|\\;|\\."
            }, {
                token : "paren.lparen",
                regex : "[[({]"
            }, {
                token : "paren.rparen",
                regex : "[\\])}]"
            }, {
                token : "text",
                regex : "\\s+"
            }
        ],
        "comment" : [ {token: "comment", regex: "-/", next: "start"},
                      {defaultToken: "comment"} ]
    };

    this.embedRules(DocCommentHighlightRules, "doc-",
        [ DocCommentHighlightRules.getEndRule("start") ]);
    this.normalizeRules();
};

oop.inherits(leanHighlightRules, TextHighlightRules);

exports.leanHighlightRules = leanHighlightRules;
});
<|endoftext|>


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

const fs = require('fs');
const path = require('path');
const {FFOX, CHROMIUM, WEBKIT, MAC} = require('./utils').testOptions(browserType);

describe('Download', function() {
  beforeEach(async(state) => {
    state.server.setRoute('/download', (req, res) => {
      res.setHeader('Content-Type', 'application/octet-stream');
      res.setHeader('Content-Disposition', 'attachment');
      res.end(`Hello world`);
    });
    state.server.setRoute('/downloadWithFilename', (req, res) => {
      res.setHeader('Content-Type', 'application/octet-stream');
      res.setHeader('Content-Disposition', 'attachment; filename=file.txt');
      res.end(`Hello world`);
    });
  });

  it('should report downloads with acceptDownloads: false', async({page, server}) => {
    await page.setContent(`<a href="${server.PREFIX}/downloadWithFilename">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    let error;
    expect(download.url()).toBe(`${server.PREFIX}/downloadWithFilename`);
    expect(download.suggestedFilename()).toBe(`file.txt`);
    await download.path().catch(e => error = e);
    expect(await download.failure()).toContain('acceptDownloads');
    expect(error.message).toContain('acceptDownloads: true');
  });
  it('should report downloads with acceptDownloads: true', async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const path = await download.path();
    expect(fs.existsSync(path)).toBeTruthy();
    expect(fs.readFileSync(path).toString()).toBe('Hello world');
    await page.close();
  });
  it.fail(WEBKIT && MAC)('should report non-navigation downloads', async({browser, server}) => {
    // Mac WebKit embedder does not download in this case, although Safari does.
    server.setRoute('/download', (req, res) => {
      res.setHeader('Content-Type', 'application/octet-stream');
      res.end(`Hello world`);
    });

    const page = await browser.newPage({ acceptDownloads: true });
    await page.goto(server.EMPTY_PAGE);
    await page.setContent(`<a download="file.txt" href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    expect(download.suggestedFilename()).toBe(`file.txt`);
    const path = await download.path();
    expect(fs.existsSync(path)).toBeTruthy();
    expect(fs.readFileSync(path).toString()).toBe('Hello world');
    await page.close();
  });
  it(`should report download path within page.on('download', …) handler for Files`, async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    const onDownloadPath = new Promise((res) => {
      page.on('download', dl => {
        dl.path().then(res);
      });
    });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    await page.click('a');
    const path = await onDownloadPath;
    expect(fs.readFileSync(path).toString()).toBe('Hello world');
    await page.close();
  })
  it(`should report download path within page.on('download', …) handler for Blobs`, async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    const onDownloadPath = new Promise((res) => {
      page.on('download', dl => {
        dl.path().then(res);
      });
    });
    await page.goto(server.PREFIX + '/download-blob.html');
    await page.click('a');
    const path = await onDownloadPath;
    expect(fs.readFileSync(path).toString()).toBe('Hello world');
    await page.close();
  })
  it.skip(FFOX).fail(WEBKIT)('should report alt-click downloads', async({browser, server}) => {
    // Firefox does not download on alt-click by default.
    // Our WebKit embedder does not download on alt-click, although Safari does.
    server.setRoute('/download', (req, res) => {
      res.setHeader('Content-Type', 'application/octet-stream');
      res.end(`Hello world`);
    });

    const page = await browser.newPage({ acceptDownloads: true });
    await page.goto(server.EMPTY_PAGE);
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a', { modifiers: ['Alt']})
    ]);
    const path = await download.path();
    expect(fs.existsSync(path)).toBeTruthy();
    expect(fs.readFileSync(path).toString()).toBe('Hello world');
    await page.close();
  });
  it('should report new window downloads', async({browser, server}) => {
    // TODO: - the test fails in headful Chromium as the popup page gets closed along
    // with the session before download completed event arrives.
    // - WebKit doesn't close the popup page
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a target=_blank href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const path = await download.path();
    expect(fs.existsSync(path)).toBeTruthy();
    await page.close();
  });
  it('should delete file', async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const path = await download.path();
    expect(fs.existsSync(path)).toBeTruthy();
    await download.delete();
    expect(fs.existsSync(path)).toBeFalsy();
    await page.close();
  });
  it('should expose stream', async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const stream = await download.createReadStream();
    let content = '';
    stream.on('data', data => content += data.toString());
    await new Promise(f => stream.on('end', f));
    expect(content).toBe('Hello world');
    stream.close();
    await page.close();
  });
  it('should delete downloads on context destruction', async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download1 ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const [ download2 ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const path1 = await download1.path();
    const path2 = await download2.path();
    expect(fs.existsSync(path1)).toBeTruthy();
    expect(fs.existsSync(path2)).toBeTruthy();
    await page.context().close();
    expect(fs.existsSync(path1)).toBeFalsy();
    expect(fs.existsSync(path2)).toBeFalsy();
  });
  it('should delete downloads on browser gone', async ({ server, browserType, defaultBrowserOptions }) => {
    const browser = await browserType.launch(defaultBrowserOptions);
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download1 ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const [ download2 ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const path1 = await download1.path();
    const path2 = await download2.path();
    expect(fs.existsSync(path1)).toBeTruthy();
    expect(fs.existsSync(path2)).toBeTruthy();
    await browser.close();
    expect(fs.existsSync(path1)).toBeFalsy();
    expect(fs.existsSync(path2)).toBeFalsy();
    expect(fs.existsSync(path.join(path1, '..'))).toBeFalsy();
  });
});
<commit_msg>test: update download test failure expectation (#2225)<commit_after>/**
 * Copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const fs = require('fs');
const path = require('path');
const {FFOX, CHROMIUM, WEBKIT, MAC, WIN} = require('./utils').testOptions(browserType);

describe('Download', function() {
  beforeEach(async(state) => {
    state.server.setRoute('/download', (req, res) => {
      res.setHeader('Content-Type', 'application/octet-stream');
      res.setHeader('Content-Disposition', 'attachment');
      res.end(`Hello world`);
    });
    state.server.setRoute('/downloadWithFilename', (req, res) => {
      res.setHeader('Content-Type', 'application/octet-stream');
      res.setHeader('Content-Disposition', 'attachment; filename=file.txt');
      res.end(`Hello world`);
    });
  });

  it('should report downloads with acceptDownloads: false', async({page, server}) => {
    await page.setContent(`<a href="${server.PREFIX}/downloadWithFilename">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    let error;
    expect(download.url()).toBe(`${server.PREFIX}/downloadWithFilename`);
    expect(download.suggestedFilename()).toBe(`file.txt`);
    await download.path().catch(e => error = e);
    expect(await download.failure()).toContain('acceptDownloads');
    expect(error.message).toContain('acceptDownloads: true');
  });
  it('should report downloads with acceptDownloads: true', async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const path = await download.path();
    expect(fs.existsSync(path)).toBeTruthy();
    expect(fs.readFileSync(path).toString()).toBe('Hello world');
    await page.close();
  });
  it.fail(WEBKIT && WIN)('should report non-navigation downloads', async({browser, server}) => {
    // Mac WebKit embedder does not download in this case, although Safari does.
    server.setRoute('/download', (req, res) => {
      res.setHeader('Content-Type', 'application/octet-stream');
      res.end(`Hello world`);
    });

    const page = await browser.newPage({ acceptDownloads: true });
    await page.goto(server.EMPTY_PAGE);
    await page.setContent(`<a download="file.txt" href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    expect(download.suggestedFilename()).toBe(`file.txt`);
    const path = await download.path();
    expect(fs.existsSync(path)).toBeTruthy();
    expect(fs.readFileSync(path).toString()).toBe('Hello world');
    await page.close();
  });
  it(`should report download path within page.on('download', …) handler for Files`, async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    const onDownloadPath = new Promise((res) => {
      page.on('download', dl => {
        dl.path().then(res);
      });
    });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    await page.click('a');
    const path = await onDownloadPath;
    expect(fs.readFileSync(path).toString()).toBe('Hello world');
    await page.close();
  })
  it(`should report download path within page.on('download', …) handler for Blobs`, async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    const onDownloadPath = new Promise((res) => {
      page.on('download', dl => {
        dl.path().then(res);
      });
    });
    await page.goto(server.PREFIX + '/download-blob.html');
    await page.click('a');
    const path = await onDownloadPath;
    expect(fs.readFileSync(path).toString()).toBe('Hello world');
    await page.close();
  })
  it.skip(FFOX).fail(WEBKIT)('should report alt-click downloads', async({browser, server}) => {
    // Firefox does not download on alt-click by default.
    // Our WebKit embedder does not download on alt-click, although Safari does.
    server.setRoute('/download', (req, res) => {
      res.setHeader('Content-Type', 'application/octet-stream');
      res.end(`Hello world`);
    });

    const page = await browser.newPage({ acceptDownloads: true });
    await page.goto(server.EMPTY_PAGE);
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a', { modifiers: ['Alt']})
    ]);
    const path = await download.path();
    expect(fs.existsSync(path)).toBeTruthy();
    expect(fs.readFileSync(path).toString()).toBe('Hello world');
    await page.close();
  });
  it('should report new window downloads', async({browser, server}) => {
    // TODO: - the test fails in headful Chromium as the popup page gets closed along
    // with the session before download completed event arrives.
    // - WebKit doesn't close the popup page
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a target=_blank href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const path = await download.path();
    expect(fs.existsSync(path)).toBeTruthy();
    await page.close();
  });
  it('should delete file', async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const path = await download.path();
    expect(fs.existsSync(path)).toBeTruthy();
    await download.delete();
    expect(fs.existsSync(path)).toBeFalsy();
    await page.close();
  });
  it('should expose stream', async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const stream = await download.createReadStream();
    let content = '';
    stream.on('data', data => content += data.toString());
    await new Promise(f => stream.on('end', f));
    expect(content).toBe('Hello world');
    stream.close();
    await page.close();
  });
  it('should delete downloads on context destruction', async({browser, server}) => {
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download1 ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const [ download2 ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const path1 = await download1.path();
    const path2 = await download2.path();
    expect(fs.existsSync(path1)).toBeTruthy();
    expect(fs.existsSync(path2)).toBeTruthy();
    await page.context().close();
    expect(fs.existsSync(path1)).toBeFalsy();
    expect(fs.existsSync(path2)).toBeFalsy();
  });
  it('should delete downloads on browser gone', async ({ server, browserType, defaultBrowserOptions }) => {
    const browser = await browserType.launch(defaultBrowserOptions);
    const page = await browser.newPage({ acceptDownloads: true });
    await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
    const [ download1 ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const [ download2 ] = await Promise.all([
      page.waitForEvent('download'),
      page.click('a')
    ]);
    const path1 = await download1.path();
    const path2 = await download2.path();
    expect(fs.existsSync(path1)).toBeTruthy();
    expect(fs.existsSync(path2)).toBeTruthy();
    await browser.close();
    expect(fs.existsSync(path1)).toBeFalsy();
    expect(fs.existsSync(path2)).toBeFalsy();
    expect(fs.existsSync(path.join(path1, '..'))).toBeFalsy();
  });
});
<|endoftext|>


<commit_before>
function InfoPanel(id, title, header, headerComments, toolbar) {

  var currentObj = this;
  this.id = id;
  this.header = header;
  this.headerComments = headerComments;
  this.isVisible = true;
  this.showAll = false;
  this.defaultTags = [ "TSTART", "TSTOP", "TIMEUNIT", "TIMESYS", "DURATION", "FRMTIME",
                       "DATE-OBS", "DATE-END", "OBJECT", "OBSERVER", "TELESCOP", "INSTRUME",
                       "OBS_ID", "OBS_MODE", "EXP_ID"];

  this.$html = $('
' +
                   '<button class="btn btn-default btnShowAll"></button>' +
                   '<button class="btn btn-default btnHide"></button>' +
                   '
' + title + ':
' +
                   '

' +
                 '
');

  this.container = this.$html.find(".properties");

  if (!isNull(toolbar)){
    this.btnShow = $('<button class="btn  btn-default btnShow ' + this.id + '"> ' + title + '</button>');
    this.btnShow.click(function(event){
      if (currentObj.btnShow.hasClass("plotHidden")) {
        currentObj.show();
      } else {
        currentObj.hide();
      }
    });
    toolbar.find(".container").append(this.btnShow);

    this.btnHide = this.$html.find(".btnHide");
    this.btnHide.click(function(event){
       currentObj.hide();
    });

    this.btnShowAll = this.$html.find(".btnShowAll");
    this.btnShowAll.click(function(event){
      currentObj.showAll = !currentObj.showAll;
      currentObj.redraw();
    });

  } else {
    this.$html.find(".btnHide").hide();
    this.$html.find(".btnShowAll").hide();
  }

  this.show = function (){
    currentObj.isVisible = true;
    currentObj.$html.show();
    currentObj.btnShow.removeClass("plotHidden");
    currentObj.btnShow.find("i").switchClass( "fa-eye-slash", "fa-eye");
    currentObj.redraw();
  }

  this.hide = function (){
    currentObj.isVisible = false;
    currentObj.$html.hide();
    currentObj.btnShow.addClass("plotHidden");
    currentObj.btnShow.find("i").switchClass( "fa-eye", "fa-eye-slash");
  }

  this.getPropertyHtml = function(tag, value, comment) {
    return $('
' +
              '' + tag + '	' +
              '' + value + '	' +
              '' + comment + '	' +
            '
');
  }

  this.redraw = function() {
    this.container.html("");

    var keys = [];
    for (key in this.header) {
      if (this.defaultTags.includes(key) || this.showAll) {
        keys.push(key);
      }
    }

    if (keys.length > 0) {
      keys.sort ();

      for (i in keys){
        var tag = keys[i];
        this.container.append(this.getPropertyHtml(tag, this.header[tag], this.headerComments[tag]));
      }
    } else {
      this.container.append('
No default header tags found!
');
    }

  }

  this.redraw();

  log ("new infoPanel id: " + this.id);

  return this;
}
<commit_msg>DAVE-95: Add MJD offset to general info section in header<commit_after>
function InfoPanel(id, title, header, headerComments, toolbar) {

  var currentObj = this;
  this.id = id;
  this.header = header;
  this.headerComments = headerComments;
  this.isVisible = true;
  this.showAll = false;
  this.defaultTags = [ "TSTART", "TSTOP", "TIMEUNIT", "TIMESYS", "DURATION", "FRMTIME",
                       "DATE-OBS", "DATE-END", "OBJECT", "OBSERVER", "TELESCOP", "INSTRUME",
                       "OBS_ID", "OBS_MODE", "EXP_ID", "MJDREF", "MJDREFF", "MJDREFI"];

  this.$html = $('
' +
                   '<button class="btn btn-default btnShowAll"></button>' +
                   '<button class="btn btn-default btnHide"></button>' +
                   '
' + title + ':
' +
                   '

' +
                 '
');

  this.container = this.$html.find(".properties");

  if (!isNull(toolbar)){
    this.btnShow = $('<button class="btn  btn-default btnShow ' + this.id + '"> ' + title + '</button>');
    this.btnShow.click(function(event){
      if (currentObj.btnShow.hasClass("plotHidden")) {
        currentObj.show();
      } else {
        currentObj.hide();
      }
    });
    toolbar.find(".container").append(this.btnShow);

    this.btnHide = this.$html.find(".btnHide");
    this.btnHide.click(function(event){
       currentObj.hide();
    });

    this.btnShowAll = this.$html.find(".btnShowAll");
    this.btnShowAll.click(function(event){
      currentObj.showAll = !currentObj.showAll;
      currentObj.redraw();
    });

  } else {
    this.$html.find(".btnHide").hide();
    this.$html.find(".btnShowAll").hide();
  }

  this.show = function (){
    currentObj.isVisible = true;
    currentObj.$html.show();
    currentObj.btnShow.removeClass("plotHidden");
    currentObj.btnShow.find("i").switchClass( "fa-eye-slash", "fa-eye");
    currentObj.redraw();
  }

  this.hide = function (){
    currentObj.isVisible = false;
    currentObj.$html.hide();
    currentObj.btnShow.addClass("plotHidden");
    currentObj.btnShow.find("i").switchClass( "fa-eye", "fa-eye-slash");
  }

  this.getPropertyHtml = function(tag, value, comment) {
    return $('
' +
              '' + tag + '	' +
              '' + value + '	' +
              '' + comment + '	' +
            '
');
  }

  this.redraw = function() {
    this.container.html("");

    var keys = [];
    for (key in this.header) {
      if (this.defaultTags.includes(key) || this.showAll) {
        keys.push(key);
      }
    }

    if (keys.length > 0) {
      keys.sort ();

      for (i in keys){
        var tag = keys[i];
        this.container.append(this.getPropertyHtml(tag, this.header[tag], this.headerComments[tag]));
      }
    } else {
      this.container.append('
No default header tags found!
');
    }

  }

  this.redraw();

  log ("new infoPanel id: " + this.id);

  return this;
}
<|endoftext|>


<commit_before>(function Calcite () {

var C = {
  version: '0.0.1'
};

// ┌───────────────┐
// │ DOM utilities │
// └───────────────┘

var dom = C.utils = {};

// ┌──────────────────────┐
// │ DOM event management │
// └──────────────────────┘

// returns standard interaction event, later will add touch support
dom.event = function () {
  return "click";
};

// add a callback function to an event on an element
dom.addEvent = function (el, event, fn) {
  if (el.addEventListener) {
    return el.addEventListener(event, fn, false);
  }
  if (el.attachEvent) {
    return el.attachEvent('on' + event, fn);
  }
};

// remove an event and its bindings
dom.removeEvent = function (el, event, fn) {
  if (el.removeEventListener) {
    return el.removeEventListener(event, fn, false);
  }
  if (el.detachEvent) {
    return el.detachEvent('on' + event,  fn);
  }
};

// get the target element of an event
dom.eventTarget = function (event) {
  if (!event.target) {
    return event.srcElement;
  }
  if (event.target) {
    return event.target;
  }
};

// prevent default behavior of an event
dom.preventDefault = function (event) {
  if (event.preventDefault) {
    return event.preventDefault();
  }
  if (event.returnValue) {
    event.returnValue = false;
  }
};

// stop and event from bubbling up the DOM tree
dom.stopPropagation = function (event) {
  event = event || window.event;
  if (event.stopPropagation) {
    return event.stopPropagation();
  }
  if (event.cancelBubble) {
    event.cancelBubble = true;
  }
};

// ┌────────────────────┐
// │ class manipulation │
// └────────────────────┘

// check if an element has a specific class
dom.hasClass = function (elem, className) {
  var exp = new RegExp(' ' + className + ' ');
  if (exp.test(' ' + elem.className + ' ')) {
    return true;
  }

  return false;
};

// add one or more classes to an element
dom.addClass = function (elem, classes) {
  classes = classes.split(' ');

  for (var i = 0; i < classes.length; i++) {
    if (!dom.hasClass(elem, classes[i])) {
      elem.className += ' ' + classes[i];
    }
  }
};

// remove one or more classes from an element
dom.removeClass = function (elem, classes) {
  classes = classes.split(' ');

  for (var i = 0; i < classes.length; i++) {
    var newClass = ' ' + elem.className.replace( /[\t\r\n]/g, ' ') + ' ';

    if (dom.hasClass(elem, classes[i])) {
      while (newClass.indexOf(' ' + classes[i] + ' ') >= 0) {
        newClass = newClass.replace(' ' + classes[i] + ' ', ' ');
      }

      elem.className = newClass.replace(/^\s+|\s+$/g, '');
    }
  }
};

// ┌───────────────┐
// │ DOM traversal │
// └───────────────┘

// returns closest element up the DOM tree matching a given class
dom.closest = function (className, context) {
  var result, current;
  for (current = context; current; current = current.parentNode) {
    if (current.nodeType === 1 && dom.hasClass(current, className)) {
      result = current;
      break;
    }
  }
  return current;
};

// get an attribute for an element
dom.getAttr = function(el, attr) {
  if (el.getAttribute) {
    return el.getAttribute(attr);
  }

  var result;
  var attrs = el.attributes;

  for (var i = 0; i < attrs.length; i++) {
    if (attrs[i].nodeName === attr) {
      result = attrs[i].nodeValue;
    }
  }

  return result;
};

// ┌───────────────┐
// │ array helpers │
// └───────────────┘

// return the index of an object in an array with optional offset
dom.indexOf = function (obj, arr, offset) {
  var i = offset || 0;

  if (arr.indexOf) {
    return arr.indexOf(obj, i);
  }

  for (i; i < arr.length; i++) {
    if (arr[i] === obj) {
      return i;
    }
  }

  return -1;
};

// make an object into an array
dom.makeArray = function (object) {
  var array = [];
  for (var i = 0; i < object.length; i++) {
    array.push(object[i]);
  }
  return array;
};

// ┌───────────────────┐
// │ feature detection │
// └───────────────────┘
// detect features like touch, ie, etc.

// detect touch, could be improved for more coverage
dom.isTouch = function () {
  if (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0)) {
    return true;
  }
  return false;
};

// ┌───────────────┐
// │ JS Patterns   │
// └───────────────┘
// javascript logic for ui patterns

// ┌─────────┐
// │ Example │
// └─────────┘
// description of the example

C.example = function () {
  // write any logic for the 'example' ui to function
};

// ┌─────────────────────┐
// │ Initialize Calcite  │
// └─────────────────────┘
// start up Calcite and attach all the patterns
// optionally pass an array of patterns you'd like to watch

C.init = function (patterns) {

  if (patterns) {
    for (var i = 0; i < patterns.length; i++) {
      H[patterns[i]]();
    }
  } else {
    H.tabs();
  }

  // add a touch class to the body
  if ( dom.isTouch() ) {
    dom.addClass(document.body, 'Calcite-touch');
  }
};

// ┌───────────────────┐
// │ Expose Calcite.js │
// └───────────────────┘
// implementation borrowed from Leaflet

function expose () {
  var oldC = window.C;

  C.noConflict = function () {
    window.C = oldC;
    return this;
  };

  window.C = C;
}

// define Calcite for Node module pattern loaders, including Browserify
if (typeof module === 'object' && typeof module.exports === 'object') {
  module.exports = C;
}

// define Calcite as an AMD module
else if (typeof define === 'function' && define.amd) {
  define(C);
}

// define Calcite as a global H variable, saving the original H to restore later if needed
else {
  expose();
}

})();<commit_msg>audit js<commit_after>(function Calcite () {

var calcite = {
  version: '0.0.5'
};

// ┌───────────────┐
// │ DOM utilities │
// └───────────────┘

calcite.dom = {};

// ┌──────────────────────┐
// │ DOM event management │
// └──────────────────────┘

// returns standard interaction event, later will add touch support
dom.event = function () {
  return "click";
};

// add a callback function to an event on an element
dom.addEvent = function (el, event, fn) {
  if (el.addEventListener) {
    return el.addEventListener(event, fn, false);
  }
  if (el.attachEvent) {
    return el.attachEvent('on' + event, fn);
  }
};

// remove an event and its bindings
dom.removeEvent = function (el, event, fn) {
  if (el.removeEventListener) {
    return el.removeEventListener(event, fn, false);
  }
  if (el.detachEvent) {
    return el.detachEvent('on' + event,  fn);
  }
};

// get the target element of an event
dom.eventTarget = function (event) {
  if (!event.target) {
    return event.srcElement;
  }
  if (event.target) {
    return event.target;
  }
};

// prevent default behavior of an event
dom.preventDefault = function (event) {
  if (event.preventDefault) {
    return event.preventDefault();
  }
  if (event.returnValue) {
    event.returnValue = false;
  }
};

// stop and event from bubbling up the DOM tree
dom.stopPropagation = function (event) {
  event = event || window.event;
  if (event.stopPropagation) {
    return event.stopPropagation();
  }
  if (event.cancelBubble) {
    event.cancelBubble = true;
  }
};

// ┌────────────────────┐
// │ class manipulation │
// └────────────────────┘

// check if an element has a specific class
dom.hasClass = function (elem, className) {
  var exp = new RegExp(' ' + className + ' ');
  if (exp.test(' ' + elem.className + ' ')) {
    return true;
  }

  return false;
};

// add one or more classes to an element
dom.addClass = function (elem, classes) {
  classes = classes.split(' ');

  for (var i = 0; i < classes.length; i++) {
    if (!dom.hasClass(elem, classes[i])) {
      elem.className += ' ' + classes[i];
    }
  }
};

// remove one or more classes from an element
dom.removeClass = function (elem, classes) {
  classes = classes.split(' ');

  for (var i = 0; i < classes.length; i++) {
    var newClass = ' ' + elem.className.replace( /[\t\r\n]/g, ' ') + ' ';

    if (dom.hasClass(elem, classes[i])) {
      while (newClass.indexOf(' ' + classes[i] + ' ') >= 0) {
        newClass = newClass.replace(' ' + classes[i] + ' ', ' ');
      }

      elem.className = newClass.replace(/^\s+|\s+$/g, '');
    }
  }
};

// ┌───────────────┐
// │ DOM traversal │
// └───────────────┘

// returns closest element up the DOM tree matching a given class
dom.closest = function (className, context) {
  var result, current;
  for (current = context; current; current = current.parentNode) {
    if (current.nodeType === 1 && dom.hasClass(current, className)) {
      result = current;
      break;
    }
  }
  return current;
};

// get an attribute for an element
dom.getAttr = function(el, attr) {
  if (el.getAttribute) {
    return el.getAttribute(attr);
  }

  var result;
  var attrs = el.attributes;

  for (var i = 0; i < attrs.length; i++) {
    if (attrs[i].nodeName === attr) {
      result = attrs[i].nodeValue;
    }
  }

  return result;
};

// ┌───────────────┐
// │ array helpers │
// └───────────────┘

// return the index of an object in an array with optional offset
dom.indexOf = function (obj, arr, offset) {
  var i = offset || 0;

  if (arr.indexOf) {
    return arr.indexOf(obj, i);
  }

  for (i; i < arr.length; i++) {
    if (arr[i] === obj) {
      return i;
    }
  }

  return -1;
};

// make an object into an array
dom.makeArray = function (object) {
  var array = [];
  for (var i = 0; i < object.length; i++) {
    array.push(object[i]);
  }
  return array;
};

// ┌───────────────────┐
// │ feature detection │
// └───────────────────┘
// detect features like touch, ie, etc.

// detect touch, could be improved for more coverage
dom.isTouch = function () {
  if (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0)) {
    return true;
  }
  return false;
};

// ┌───────────────┐
// │ JS Patterns   │
// └───────────────┘
// javascript logic for ui patterns

// ┌─────────┐
// │ Example │
// └─────────┘
// description of the example

// calcite.example = function () {
//   // write any logic for the 'example' ui to function
// };

// ┌─────────────────────┐
// │ Initialize Calcite  │
// └─────────────────────┘
// start up Calcite and attach all the patterns
// optionally pass an array of patterns you'd like to watch

calcite.init = function (patterns) {
  if (patterns) {
    for (var i = 0; i < patterns.length; i++) {
      calcite[patterns[i]]();
    }
  } else {
    calcite.tabs();
  }

  // add a touch class to the body
  if ( dom.isTouch() ) {
    dom.addClass(document.body, 'calcite-touch');
  }
};

// ┌───────────────────┐
// │ Expose Calcite.js │
// └───────────────────┘
// implementation borrowed from Leaflet

// define calcite as a global variable, saving the original to restore later if needed
function expose () {
  var oldCalcite = window.calcite;

  calcite.noConflict = function () {
    window.calcite = oldCalcite;
    return this;
  };

  window.calcite = calcite;
}

// No NPM/AMD for now because it just causes issues
// @TODO: bust them into AMD & NPM distros

// // define Calcite for CommonJS module pattern loaders (NPM, Browserify)
// if (typeof module === 'object' && typeof module.exports === 'object') {
//   module.exports = calcite;
// }

// // define Calcite as an AMD module
// else if (typeof define === 'function' && define.amd) {
//   define(calcite);
// }

expose();

})();
<|endoftext|>