<commit_before>import { directive } from 'lit-html/lit-html.js'

/*
 * Set a default value if the provided value is undefined
 */
// export const defaultValue = (value, defaultVal) => directive(part => {
//     if (value === undefined || value === 'undefined') {
//         value = defaultVal
//     }

//     part.setValue(value)
// })

export const defaultValue = directive((value, defaultVal) => part => {
  if (value === undefined || value === 'undefined') {
      value = defaultVal
  }

  part.setValue(value)
})
<commit_msg>chore(directive): Remove unused code<commit_after>import { directive } from 'lit-html/lit-html.js'

/*
 * Set a default value if the provided value is undefined
 */
export const defaultValue = directive((value, defaultVal) => part => {
  if (value === undefined || value === 'undefined') {
      value = defaultVal
  }

  part.setValue(value)
})
<|endoftext|>


<commit_before>import React, {useState, useEffect} from 'react'
import {Text, Container, Flex, Spinner, Stack} from '@sanity/ui'
import {versionedClient} from './versionedClient'

const checkCors = () =>
  Promise.all([
    versionedClient.request({uri: '/ping', withCredentials: false}).then(() => true),
    versionedClient
      .request({uri: '/users/me', withCredentials: false})
      .then(() => true)
      .catch(() => false),
  ])
    .then((res) => ({
      isCorsError: res[0] && !res[1],
      pingResponded: res[0],
    }))
    .catch((error) => ({error}))

function CorsWrapper({result, children}) {
  const response = result && result.error && result.error.response
  const message = response && response.body && response.body.message
  if (!message) {
    return <>{children}</>
  }

  return (

      <Text>Error message:</Text>

        {response.body.message}

      {children}

  )
}

export default function CorsCheck() {
  const [state, setState] = useState({isLoading: true})

  useEffect(() => {
    checkCors().then((res) =>
      setState({
        result: res,
        isLoading: false,
      })
    )
  }, [])

  const {isLoading, result} = state
  const origin =
    window.location.origin ||
    window.location.href.replace(new RegExp(`${window.location.pathname}$`), '')

  if (isLoading) {
    return (
      <Container width={4} padding={4} height="fill">
        <Flex align="center" justify="center" height="fill">
          <Text>
            <Spinner />
          </Text>
        </Flex>
      </Container>
    )
  }

  const tld = versionedClient.config().apiHost.replace(/.*?sanity\.([a-z]+).*/, '$1')
  const projectId = versionedClient.config().projectId
  const corsUrl = `https://manage.sanity.${tld}/projects/${projectId}/settings/api`
  const response = result.error && result.error.response

  if (response) {
    const is404 = response.statusCode === 404
    const errType = response.body.attributes && response.body.attributes.type
    if (is404 && errType === 'project') {
      return (
        <Stack space={4}>
          <Text accent>{response.body.message || response.statusCode}</Text>
          <Text accent>
            Double-check that your sanity.json points to the right project ID!
          </Text>
        </Stack>
      )
    }
  }

  if (result.isCorsError) {
    return (
      <CorsWrapper result={state.result}>
        <Text accent>
          It looks like the error is being caused by the current origin ({origin}) not
          being allowed for this project. If you are a project administrator or developer, you can
          head to{' '}

            the project management
          {' '}
          interface. Add the origin under the{' '}

            CORS Origins
          {' '}
          section. Do remember to allow credentials!
        </Text>
      </CorsWrapper>
    )
  }

  if (result.pingResponded) {
    return (
      <CorsWrapper result={state.result}>
        <Text accent>
          Our diagnostics cannot quite determine why this happened. If it was a network glitch you
          could try hitting the Retry button below. If you are working as a
          developer on this project, you could also have a look at the browser's dev console and see
          if any issues are listed there.
        </Text>
      </CorsWrapper>
    )
  }

  return (
    <CorsWrapper result={state.result}>
      <Text accent>
        It might be that your internet connection is unstable or down. You could try hitting the{' '}
        Retry button to see if it was just a temporary glitch.
      </Text>
    </CorsWrapper>
  )
}
<commit_msg>fix(default-login): fix issue with CORS check Spinner misaligning<commit_after>import React, {useState, useEffect} from 'react'
import {Text, Container, Flex, Spinner, Stack} from '@sanity/ui'
import {versionedClient} from './versionedClient'

const checkCors = () =>
  Promise.all([
    versionedClient.request({uri: '/ping', withCredentials: false}).then(() => true),
    versionedClient
      .request({uri: '/users/me', withCredentials: false})
      .then(() => true)
      .catch(() => false),
  ])
    .then((res) => ({
      isCorsError: res[0] && !res[1],
      pingResponded: res[0],
    }))
    .catch((error) => ({error}))

function CorsWrapper({result, children}) {
  const response = result && result.error && result.error.response
  const message = response && response.body && response.body.message
  if (!message) {
    return <>{children}</>
  }

  return (

      <Text>Error message:</Text>

        {response.body.message}

      {children}

  )
}

export default function CorsCheck() {
  const [state, setState] = useState({isLoading: true})

  useEffect(() => {
    checkCors().then((res) =>
      setState({
        result: res,
        isLoading: false,
      })
    )
  }, [])

  const {isLoading, result} = state
  const origin =
    window.location.origin ||
    window.location.href.replace(new RegExp(`${window.location.pathname}$`), '')

  if (isLoading) {
    return (
      <Container width={4} height="fill">
        <Flex justify="center" height="fill">
          <Spinner />
        </Flex>
      </Container>
    )
  }

  const tld = versionedClient.config().apiHost.replace(/.*?sanity\.([a-z]+).*/, '$1')
  const projectId = versionedClient.config().projectId
  const corsUrl = `https://manage.sanity.${tld}/projects/${projectId}/settings/api`
  const response = result.error && result.error.response

  if (response) {
    const is404 = response.statusCode === 404
    const errType = response.body.attributes && response.body.attributes.type
    if (is404 && errType === 'project') {
      return (
        <Stack space={4}>
          <Text accent>{response.body.message || response.statusCode}</Text>
          <Text accent>
            Double-check that your sanity.json points to the right project ID!
          </Text>
        </Stack>
      )
    }
  }

  if (result.isCorsError) {
    return (
      <CorsWrapper result={state.result}>
        <Text accent>
          It looks like the error is being caused by the current origin ({origin}) not
          being allowed for this project. If you are a project administrator or developer, you can
          head to{' '}

            the project management
          {' '}
          interface. Add the origin under the{' '}

            CORS Origins
          {' '}
          section. Do remember to allow credentials!
        </Text>
      </CorsWrapper>
    )
  }

  if (result.pingResponded) {
    return (
      <CorsWrapper result={state.result}>
        <Text accent>
          Our diagnostics cannot quite determine why this happened. If it was a network glitch you
          could try hitting the Retry button below. If you are working as a
          developer on this project, you could also have a look at the browser's dev console and see
          if any issues are listed there.
        </Text>
      </CorsWrapper>
    )
  }

  return (
    <CorsWrapper result={state.result}>
      <Text accent>
        It might be that your internet connection is unstable or down. You could try hitting the{' '}
        Retry button to see if it was just a temporary glitch.
      </Text>
    </CorsWrapper>
  )
}
<|endoftext|>


<commit_before>'use strict';
var assert     = require('assert');
var http       = require('http');
var restler    = require('restler');
var _          = require('lodash');
var mockConfig = require('../mockConfig').getNoProxyConfig();
var deride     = require('deride');
var fs         = require('fs');
var RegistryManager = require('../../lib/registryManager').RegistryManager;

describe('Routing Configuration (routes)', function() {
  var server,
      endpoint = 'http://127.0.0.1:9615';

  before(function(done) {
    var registryManager = new RegistryManager(mockConfig);
    var mockRegistryManager = deride.wrap(registryManager);

    mockRegistryManager.setup
      .getModuleIndex
      .toCallbackWith([undefined, JSON.parse(fs.readFileSync(__dirname + '/../data/sample-requests/mkdirp'))]);

    var routes = new require('../../lib/routes')
      .Routes(mockConfig, mockRegistryManager);
    server = http.createServer(routes.requestHandler);
    server.listen(9615, done);
  });

  after(function(done) {
    server.close(done);
  });

  var urls = [
    { url: 'readable-stream', code: 200 },
    { url: 'readable_stream', code: 200 },
    { url: 'r34dable_stream', code: 200 },
    { url: 'readable-stream/0.1.0', code: 200 },
    { url: 'readable-stream/0.3.4', code: 200 },
    { url: 'readable-stream/12.1.0', code: 404 },
    { url: 'readable-stream/12.1.20', code: 404 },
    { url: 'readable-stream/-/readable-stream-1.0.27-1.tgz', code: 200 },
    { url: 'readable-stream/-/readable-stream.tgz', code: 404 },
    { url: 'readable-stream/-/readable-stream.zip', code: 404 },
    { url: 'readable-stream/readable-stream.tgz', code: 404 }
  ];

  _.forEach(urls, function(url) {
    it('Should return status ' + url.code + ' for ' + url.url, function(done) {
      restler.get(endpoint + '/' + url.url)
      .on('complete', function(result, res) {
        assert.equal(result instanceof Error, false, result.toString());
        assert.equal(res.statusCode, url.code);
        done();
      });
    });
  });

});

<commit_msg>Renamed some of the test data to make it obvious its mocked<commit_after>'use strict';
var assert     = require('assert');
var http       = require('http');
var restler    = require('restler');
var _          = require('lodash');
var mockConfig = require('../mockConfig').getNoProxyConfig();
var deride     = require('deride');
var fs         = require('fs');
var RegistryManager = require('../../lib/registryManager').RegistryManager;

describe('Routing Configuration (routes)', function() {
  var server,
      endpoint = 'http://127.0.0.1:9615';

  before(function(done) {
    var registryManager = new RegistryManager(mockConfig);
    var mockRegistryManager = deride.wrap(registryManager);

    mockRegistryManager.setup
      .getModuleIndex
      .toCallbackWith([undefined, JSON.parse(fs.readFileSync(__dirname + '/../data/sample-requests/mkdirp'))]);

    var routes = new require('../../lib/routes')
      .Routes(mockConfig, mockRegistryManager);
    server = http.createServer(routes.requestHandler);
    server.listen(9615, done);
  });

  after(function(done) {
    server.close(done);
  });

  var urls = [
    { url: 'some-module', code: 200 },
    { url: 'some_module', code: 200 },
    { url: 's0m3_m0dul3', code: 200 },
    { url: 'some-module/0.1.0', code: 200 },
    { url: 'some-module/0.3.4', code: 200 },
    { url: 'some-module/12.1.0', code: 404 },
    { url: 'some-module/12.1.20', code: 404 },
    { url: 'some-module/-/some-module-1.0.27-1.tgz', code: 200 },
    { url: 'some-module/-/some-module.tgz', code: 404 },
    { url: 'some-module/-/some-module.zip', code: 404 },
    { url: 'some-module/some-module.tgz', code: 404 }
  ];

  _.forEach(urls, function(url) {
    it('Should return status ' + url.code + ' for ' + url.url, function(done) {
      restler.get(endpoint + '/' + url.url)
      .on('complete', function(result, res) {
        assert.equal(result instanceof Error, false, result.toString());
        assert.equal(res.statusCode, url.code);
        done();
      });
    });
  });

});

<|endoftext|>


<commit_before>// -------------------------------------------------------------------------- \\
// File: ScrollView.js                                                        \\
// Module: ContainerViews                                                     \\
// Requires: Core, Foundation, View                                           \\
// Author: Neil Jenkins                                                       \\
// License: © 2010-2014 FastMail Pty Ltd. All rights reserved.                \\
// -------------------------------------------------------------------------- \\

"use strict";

( function ( NS ) {

var ScrollAnimation = NS.Class({

    Extends: NS.Animation,

    duration: 250,

    prepare: function ( coordinates ) {
        var object = this.object,
            startX = this.startX = object.get( 'scrollLeft' ),
            startY = this.startY = object.get( 'scrollTop' ),
            endX = this.endX = coordinates.x || 0,
            endY = this.endY = coordinates.y || 0,
            deltaX = this.deltaX = endX - startX,
            deltaY = this.deltaY = endY - startY;

        return !!( deltaX || deltaY );
    },

    drawFrame: function ( position ) {
        var x = position < 1 ?
                this.startX + ( position * this.deltaX ) : this.endX,
            y = position < 1 ?
                this.startY + ( position * this.deltaY ) : this.endY;
        this.object._scrollTo( x, y );
    }
});

/**
    Class: O.ScrollView

    Extends: O.View

    An O.ScrollView instance is a fixed size container, which can be scrolled if
    its contents overflows the bounds of the view. By default, a scrollbar will
    only be shown for vertical overflow. Set the <O.ScrollView#showScrollbarX>
    property to `true` to show a scrollbar on horizontal overflow as well.
*/
var ScrollView = NS.Class({

    Extends: NS.View,

    /**
        Property: O.ScrollView#className
        Type: String
        Default: 'ScrollView'

        Overrides default in <O.View#className>.
    */
    className: 'ScrollView',

    /**
        Property: O.ScrollView#showScrollbarX
        Type: Boolean
        Default: false

        Show a scrollbar if the content horizontally overflows the bounds of the
        DOM element representing this view?
    */
    showScrollbarX: false,

    /**
        Property: O.ScrollView#showScrollbarY
        Type: Boolean
        Default: true

        Show a scrollbar if the content vertically overflows the bounds of the
        DOM element representing this view?
    */
    showScrollbarY: true,

    /**
        Property: O.ScrollView#positioning
        Type: String
        Default: 'absolute'

        Overrides default in <O.View#positioning>.
   */
    positioning: 'absolute',

    /**
        Property: O.ScrollView#layout
        Type: Object
        Default:
                {
                    top: 0,
                    left: 0,
                    width: '100%',
                    height: '100%'
                }

        Overrides default in <O.View#layout>.
    */
    layout: NS.View.LAYOUT_FILL_PARENT,

    /**
        Property: O.ScrollView#layerStyles
        Type: Object

        Sets the overflow styles to show the scrollbars.
    */
    layerStyles: function () {
        var styles = NS.View.prototype.layerStyles.call( this );
        styles.overflowX = this.get( 'showScrollbarX' ) ? 'auto' : 'hidden';
        styles.overflowY = this.get( 'showScrollbarY' ) ? 'auto' : 'hidden';
        return styles;
    }.property( 'layout', 'allowTextSelection', 'positioning',
        'showScrollbarX', 'showScrollbarY' ),

    /**
        Property: O.ScrollView#keys
        Type: Object
        Default: {}

        Keyboard shortcuts to scroll the view. A map of keyboard shortcut to the
        method name to call on the O.ScrollView instance. These shortcuts will
        automatically be activated/deactivated when the view is added/removed
        to/from the document.

        For example, on the main scroll view for you content, you might set:

            {
                'pagedown': 'scrollPage',
                'pageup': 'reverseScrollPage',
                'space': 'scrollPage',
                'shift-space': 'reverseScrollPage',
                'down': 'scrollLine',
                'up': 'reverseScrollLine'
            }
    */
    keys: {},

    didCreateLayer: function ( layer ) {
        this.scrollLayer = layer;
    },

    didEnterDocument: function () {
        this.get( 'scrollLayer' ).addEventListener( 'scroll', this, false );

        // Add keyboard shortcuts:
        var keys = this.get( 'keys' ),
            shortcuts = NS.ViewEventsController.kbShortcuts,
            key;
        for ( key in keys ) {
            shortcuts.register( key, this, keys[ key ] );
        }

        return ScrollView.parent.didEnterDocument.call( this );
    },

    willLeaveDocument: function () {
        // Remove keyboard shortcuts:
        var keys = this.get( 'keys' ),
            shortcuts = NS.ViewEventsController.kbShortcuts,
            key;
        for ( key in keys ) {
            shortcuts.deregister( key, this, keys[ key ] );
        }

        this.get( 'scrollLayer' ).removeEventListener( 'scroll', this, false );

        return ScrollView.parent.willLeaveDocument.call( this );
    },

    _restoreScroll: function () {
        // Scroll is reset to 0 in some browsers whenever it is removed from the
        // DOM, so we need to set it to what it should be.
        if ( this.get( 'isInDocument' ) ) {
            var layer = this.get( 'scrollLayer' );
            layer.scrollLeft = this.get( 'scrollLeft' );
            layer.scrollTop = this.get( 'scrollTop' );
        }
    }.queue( 'render' ).observes( 'isInDocument' ),

    /**
        Property: O.ScrollView#scrollAnimation
        Type: O.Animation

        An <O.Animation> object to animate scrolling on this object. Normally
        you will not need to interact with this directly, but just set the
        `withAnimation` argument to `true` when you call O.ScrollView#scrollTo.
        However, if you wish to change the duration or easing method, you can do
        so by setting it on this object.
    */
    scrollAnimation: function ( ) {
        return new ScrollAnimation({
            object: this
        });
    }.property(),

    /**
        Method: O.ScrollView#scrollPage

        Scrolls the view down by the view height - 50px.
    */
    scrollPage: function () {
        return this.scrollBy( 0, this.get( 'pxHeight' ) - 50, true );
    },

    /**
        Method: O.ScrollView#reverseScrollPage

        Scrolls the view up by the view height - 50px.
    */
    reverseScrollPage: function () {
        return this.scrollBy( 0, 50 - this.get( 'pxHeight' ), true );
    },

    /**
        Method: O.ScrollView#scrollLine

        Scrolls the view down by 40px.
    */
    scrollLine: function () {
        return this.scrollBy( 0, 40 );
    },

    /**
        Method: O.ScrollView#reverseScrollLine

        Scrolls the view up by 40px.
    */
    reverseScrollLine: function () {
        return this.scrollBy( 0, -40 );
    },

    /**
        Method: O.ScrollView#scrollBy

        Scroll the view by the given number of pixels (use negative values to
        scroll up/left).

        Parameters:
            x             - {Number} The number of pixels to scroll right.
            y             - {Number} The number of pixels to scroll down.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {Boolean} Did the view actually scroll (false if already at end)?
    */
    scrollBy: function ( x, y, withAnimation ) {
        var left = this.get( 'scrollLeft' ),
            top = this.get( 'scrollTop' );
        x += left;
        y += top;

        this.scrollTo( x, y, withAnimation );

        return top !== this.get( 'scrollTop' ) ||
            left !== this.get( 'scrollLeft' );
    },

    /**
        Method: O.ScrollView#scrollToView

        Scroll the view to show a sub-view in the top left of the view.

        Parameters:
            view          - {View} The sub-view to scroll to.
            offset        - {Object} (optional) If supplied, must contain
                            numerical `x` and `y` properties which give the
                            number of pixels to offset the subview from the top
                            left of the scroll view.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {O.ScrollView} Returns self.
    */
    scrollToView: function ( view, offset, withAnimation ) {
        var position = view.getPositionRelativeTo( this );
        return this.scrollTo(
            position.left + ( offset && offset.x || 0 ),
            position.top + ( offset && offset.y || 0 ),
            withAnimation
        );
    },

    /**
        Method: O.ScrollView#scrollBy

        Scroll the view to a given position, where (0,0) represents the scroll
        view fully .

        Parameters:
            x             - {Number} The number of pixels to set the horizontal
                            scroll-position to.
            y             - {Number} The number of pixels to set the vertical
                            scroll-position to.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {O.ScrollView} Returns self.
    */
    scrollTo: function ( x, y, withAnimation ) {
        // Can't have negative scroll values.
        if ( x < 0 ) { x = 0; }
        if ( y < 0 ) { y = 0; }

        var scrollAnimation = this.get( 'scrollAnimation' );
        scrollAnimation.stop();

        if ( withAnimation ) {
            scrollAnimation.animate({
                x: x,
                y: y
            });
        } else {
            this.beginPropertyChanges()
                .set( 'scrollLeft', x )
                .set( 'scrollTop', y )
            .endPropertyChanges()
            .propertyNeedsRedraw( this, 'scroll' );
        }
        return this;
    },

    /**
        Method (private): O.ScrollView#_scrollTo

        Set the new values and immediately redraw. Fast path for animation.
    */
    _scrollTo: function ( x, y ) {
        this.set( 'scrollLeft', x )
            .set( 'scrollTop', y );
        this.redrawScroll();
    },

    /**
        Method: O.ScrollView#redrawScroll

        Redraws the scroll position in the layer to match the view's state.
    */
    redrawScroll: function () {
        var layer = this.get( 'scrollLayer' ),
            x = this.get( 'scrollLeft' ),
            y = this.get( 'scrollTop' );
        layer.scrollLeft = x;
        layer.scrollTop = y;
        // In case we've gone past the end.
        if ( x || y ) {
            NS.RunLoop.queueFn( 'after', this.syncBackScroll, this );
        }
    },

    /**
        Method: O.ScrollView#syncBackScroll

        Parameters:
            event - {Event} (optional) The scroll event object.

        Updates the view properties when the layer scrolls.
    */
    syncBackScroll: function ( event ) {
        if ( this._needsRedraw ) {
            return;
        }
        var layer = this.get( 'scrollLayer' ),
            x = layer.scrollLeft,
            y = layer.scrollTop;
        this.beginPropertyChanges()
            .set( 'scrollLeft', x )
            .set( 'scrollTop', y )
            .endPropertyChanges();
        if ( event ) {
            event.stopPropagation();
            // Don't interpret tap to stop scroll as a real tap.
            if ( NS.Tap ) {
                NS.Tap.cancel();
            }
        }
    }.on( 'scroll' )
});

if ( NS.UA.isIOS ) {
    ScrollView.implement({
        isFixedDimensions: function () {
            var positioning = this.get( 'positioning' );
            return positioning === 'absolute' || positioning === 'fixed';
        }.property( 'positioning' ),

        draw: function ( layer, Element, el ) {
            var contents, wrapper, children;
            wrapper = this.scrollLayer = el( 'div', {
                style: 'position:relative;height:100%;overflow:auto;' +
                    '-webkit-overflow-scrolling:touch;'
            }, [
                contents = el( 'div.ScrollViewContents', {
                    style: 'position:relative;' +
                        ( this.get( 'showScrollbarX' ) ?
                            '' : 'overflow:hidden;min-height:100%;' )
                }),
                this.get( 'isFixedDimensions' ) ? el( 'div', {
                    style: 'position:absolute;top:100%;left: 0px;' +
                        'width:1px;height:1px;'
                }) : null
            ]);
            layer.appendChild( wrapper );
            children = ScrollView.parent.draw.call( this, layer, Element, el );
            if ( children ) {
                Element.appendChildren( contents, children );
            }
        },

        preventRootScroll: function ( event ) {
            if ( !this.get( 'isFixedDimensions' ) ) {
                var layer = this.get( 'layer' );
                if ( layer.scrollHeight <= layer.offsetHeight ) {
                    event.preventDefault();
                }
            }
        }.on( 'touchmove' ),

        insertView: function ( view, relativeTo, where ) {
            if ( !relativeTo && this.get( 'isRendered' ) &&
                    where !== 'before' && where !== 'after' ) {
                relativeTo = this.get( 'scrollLayer' ).firstChild;
            }
            return ScrollView.parent.insertView.call(
                this, view, relativeTo, where );
        }
    });
}

NS.ScrollView = ScrollView;

}( this.O ) );
<commit_msg>ScrollView fixes for iOS8.<commit_after>// -------------------------------------------------------------------------- \\
// File: ScrollView.js                                                        \\
// Module: ContainerViews                                                     \\
// Requires: Core, Foundation, View                                           \\
// Author: Neil Jenkins                                                       \\
// License: © 2010-2014 FastMail Pty Ltd. All rights reserved.                \\
// -------------------------------------------------------------------------- \\

"use strict";

( function ( NS ) {

var ScrollAnimation = NS.Class({

    Extends: NS.Animation,

    duration: 250,

    prepare: function ( coordinates ) {
        var object = this.object,
            startX = this.startX = object.get( 'scrollLeft' ),
            startY = this.startY = object.get( 'scrollTop' ),
            endX = this.endX = coordinates.x || 0,
            endY = this.endY = coordinates.y || 0,
            deltaX = this.deltaX = endX - startX,
            deltaY = this.deltaY = endY - startY;

        return !!( deltaX || deltaY );
    },

    drawFrame: function ( position ) {
        var x = position < 1 ?
                this.startX + ( position * this.deltaX ) : this.endX,
            y = position < 1 ?
                this.startY + ( position * this.deltaY ) : this.endY;
        this.object._scrollTo( x, y );
    }
});

/**
    Class: O.ScrollView

    Extends: O.View

    An O.ScrollView instance is a fixed size container, which can be scrolled if
    its contents overflows the bounds of the view. By default, a scrollbar will
    only be shown for vertical overflow. Set the <O.ScrollView#showScrollbarX>
    property to `true` to show a scrollbar on horizontal overflow as well.
*/
var ScrollView = NS.Class({

    Extends: NS.View,

    /**
        Property: O.ScrollView#className
        Type: String
        Default: 'ScrollView'

        Overrides default in <O.View#className>.
    */
    className: 'ScrollView',

    /**
        Property: O.ScrollView#showScrollbarX
        Type: Boolean
        Default: false

        Show a scrollbar if the content horizontally overflows the bounds of the
        DOM element representing this view?
    */
    showScrollbarX: false,

    /**
        Property: O.ScrollView#showScrollbarY
        Type: Boolean
        Default: true

        Show a scrollbar if the content vertically overflows the bounds of the
        DOM element representing this view?
    */
    showScrollbarY: true,

    /**
        Property: O.ScrollView#positioning
        Type: String
        Default: 'absolute'

        Overrides default in <O.View#positioning>.
   */
    positioning: 'absolute',

    /**
        Property: O.ScrollView#layout
        Type: Object
        Default:
                {
                    top: 0,
                    left: 0,
                    width: '100%',
                    height: '100%'
                }

        Overrides default in <O.View#layout>.
    */
    layout: NS.View.LAYOUT_FILL_PARENT,

    /**
        Property: O.ScrollView#layerStyles
        Type: Object

        Sets the overflow styles to show the scrollbars.
    */
    layerStyles: function () {
        var styles = NS.View.prototype.layerStyles.call( this );
        styles.overflowX = this.get( 'showScrollbarX' ) ? 'auto' : 'hidden';
        styles.overflowY = this.get( 'showScrollbarY' ) ? 'auto' : 'hidden';
        return styles;
    }.property( 'layout', 'allowTextSelection', 'positioning',
        'showScrollbarX', 'showScrollbarY' ),

    /**
        Property: O.ScrollView#keys
        Type: Object
        Default: {}

        Keyboard shortcuts to scroll the view. A map of keyboard shortcut to the
        method name to call on the O.ScrollView instance. These shortcuts will
        automatically be activated/deactivated when the view is added/removed
        to/from the document.

        For example, on the main scroll view for you content, you might set:

            {
                'pagedown': 'scrollPage',
                'pageup': 'reverseScrollPage',
                'space': 'scrollPage',
                'shift-space': 'reverseScrollPage',
                'down': 'scrollLine',
                'up': 'reverseScrollLine'
            }
    */
    keys: {},

    didCreateLayer: function ( layer ) {
        this.scrollLayer = layer;
    },

    didEnterDocument: function () {
        this.get( 'scrollLayer' ).addEventListener( 'scroll', this, false );

        // Add keyboard shortcuts:
        var keys = this.get( 'keys' ),
            shortcuts = NS.ViewEventsController.kbShortcuts,
            key;
        for ( key in keys ) {
            shortcuts.register( key, this, keys[ key ] );
        }

        return ScrollView.parent.didEnterDocument.call( this );
    },

    willLeaveDocument: function () {
        // Remove keyboard shortcuts:
        var keys = this.get( 'keys' ),
            shortcuts = NS.ViewEventsController.kbShortcuts,
            key;
        for ( key in keys ) {
            shortcuts.deregister( key, this, keys[ key ] );
        }

        this.get( 'scrollLayer' ).removeEventListener( 'scroll', this, false );

        return ScrollView.parent.willLeaveDocument.call( this );
    },

    _restoreScroll: function () {
        // Scroll is reset to 0 in some browsers whenever it is removed from the
        // DOM, so we need to set it to what it should be.
        if ( this.get( 'isInDocument' ) ) {
            var layer = this.get( 'scrollLayer' );
            layer.scrollLeft = this.get( 'scrollLeft' );
            layer.scrollTop = this.get( 'scrollTop' );
        }
    }.queue( 'render' ).observes( 'isInDocument' ),

    /**
        Property: O.ScrollView#scrollAnimation
        Type: O.Animation

        An <O.Animation> object to animate scrolling on this object. Normally
        you will not need to interact with this directly, but just set the
        `withAnimation` argument to `true` when you call O.ScrollView#scrollTo.
        However, if you wish to change the duration or easing method, you can do
        so by setting it on this object.
    */
    scrollAnimation: function ( ) {
        return new ScrollAnimation({
            object: this
        });
    }.property(),

    /**
        Method: O.ScrollView#scrollPage

        Scrolls the view down by the view height - 50px.
    */
    scrollPage: function () {
        return this.scrollBy( 0, this.get( 'pxHeight' ) - 50, true );
    },

    /**
        Method: O.ScrollView#reverseScrollPage

        Scrolls the view up by the view height - 50px.
    */
    reverseScrollPage: function () {
        return this.scrollBy( 0, 50 - this.get( 'pxHeight' ), true );
    },

    /**
        Method: O.ScrollView#scrollLine

        Scrolls the view down by 40px.
    */
    scrollLine: function () {
        return this.scrollBy( 0, 40 );
    },

    /**
        Method: O.ScrollView#reverseScrollLine

        Scrolls the view up by 40px.
    */
    reverseScrollLine: function () {
        return this.scrollBy( 0, -40 );
    },

    /**
        Method: O.ScrollView#scrollBy

        Scroll the view by the given number of pixels (use negative values to
        scroll up/left).

        Parameters:
            x             - {Number} The number of pixels to scroll right.
            y             - {Number} The number of pixels to scroll down.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {Boolean} Did the view actually scroll (false if already at end)?
    */
    scrollBy: function ( x, y, withAnimation ) {
        var left = this.get( 'scrollLeft' ),
            top = this.get( 'scrollTop' );
        x += left;
        y += top;

        this.scrollTo( x, y, withAnimation );

        return top !== this.get( 'scrollTop' ) ||
            left !== this.get( 'scrollLeft' );
    },

    /**
        Method: O.ScrollView#scrollToView

        Scroll the view to show a sub-view in the top left of the view.

        Parameters:
            view          - {View} The sub-view to scroll to.
            offset        - {Object} (optional) If supplied, must contain
                            numerical `x` and `y` properties which give the
                            number of pixels to offset the subview from the top
                            left of the scroll view.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {O.ScrollView} Returns self.
    */
    scrollToView: function ( view, offset, withAnimation ) {
        var position = view.getPositionRelativeTo( this );
        return this.scrollTo(
            position.left + ( offset && offset.x || 0 ),
            position.top + ( offset && offset.y || 0 ),
            withAnimation
        );
    },

    /**
        Method: O.ScrollView#scrollBy

        Scroll the view to a given position, where (0,0) represents the scroll
        view fully .

        Parameters:
            x             - {Number} The number of pixels to set the horizontal
                            scroll-position to.
            y             - {Number} The number of pixels to set the vertical
                            scroll-position to.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {O.ScrollView} Returns self.
    */
    scrollTo: function ( x, y, withAnimation ) {
        // Can't have negative scroll values.
        if ( x < 0 ) { x = 0; }
        if ( y < 0 ) { y = 0; }

        var scrollAnimation = this.get( 'scrollAnimation' );
        scrollAnimation.stop();

        if ( withAnimation ) {
            scrollAnimation.animate({
                x: x,
                y: y
            });
        } else {
            this.beginPropertyChanges()
                .set( 'scrollLeft', x )
                .set( 'scrollTop', y )
            .endPropertyChanges()
            .propertyNeedsRedraw( this, 'scroll' );
        }
        return this;
    },

    /**
        Method (private): O.ScrollView#_scrollTo

        Set the new values and immediately redraw. Fast path for animation.
    */
    _scrollTo: function ( x, y ) {
        this.set( 'scrollLeft', x )
            .set( 'scrollTop', y );
        this.redrawScroll();
    },

    /**
        Method: O.ScrollView#redrawScroll

        Redraws the scroll position in the layer to match the view's state.
    */
    redrawScroll: function () {
        var layer = this.get( 'scrollLayer' ),
            x = this.get( 'scrollLeft' ),
            y = this.get( 'scrollTop' );
        layer.scrollLeft = x;
        layer.scrollTop = y;
        // In case we've gone past the end.
        if ( x || y ) {
            NS.RunLoop.queueFn( 'after', this.syncBackScroll, this );
        }
    },

    /**
        Method: O.ScrollView#syncBackScroll

        Parameters:
            event - {Event} (optional) The scroll event object.

        Updates the view properties when the layer scrolls.
    */
    syncBackScroll: function ( event ) {
        if ( this._needsRedraw ) {
            return;
        }
        var layer = this.get( 'scrollLayer' ),
            x = layer.scrollLeft,
            y = layer.scrollTop;
        this.beginPropertyChanges()
            .set( 'scrollLeft', x )
            .set( 'scrollTop', y )
            .endPropertyChanges();
        if ( event ) {
            event.stopPropagation();
            // Don't interpret tap to stop scroll as a real tap.
            if ( NS.Tap ) {
                NS.Tap.cancel();
            }
        }
    }.on( 'scroll' )
});

if ( NS.UA.isIOS ) {
    ScrollView.implement({
        isFixedDimensions: function () {
            var positioning = this.get( 'positioning' );
            return positioning === 'absolute' || positioning === 'fixed';
        }.property( 'positioning' ),

        draw: function ( layer, Element, el ) {
            var isFixedDimensions = this.get( 'isFixedDimensions' ),
                scrollFixerHeight = 1,
                contentMargin = '',
                wrapper = null,
                safariVersion = NS.UA.safari,
                children;

            // Render the children.
            children = ScrollView.parent.draw.call( this, layer, Element, el );

            // Trick 1: The dual overflow:scroll view.
            // By default, iOS Safari will scroll the containing scroll view
            // if you are at the top/bottom of an overflow:scroll view. This
            // means it scrolls the window instead of bouncing your scroll view.
            // The dual overflow:scroll fixes this in iOS < 8. You only need
            // this in Safari: if in a UIWebView you can disable the natural
            // scrolling of the window.
            if ( 0 < safariVersion && safariVersion < 8 ) {
                wrapper = this.scrollLayer = el( 'div', {
                    style: 'position:relative;height:100%;overflow:auto;' +
                        '-webkit-overflow-scrolling:touch;'
                });
                layer.appendChild( wrapper );
                layer = wrapper;
            }

            // Trick 2: Never leave the scroll view at the ends.
            // As Trick 1 doesn't work in Safari on iOS8, we have to use a more
            // crude method: ensure the scrollHeight is at least pxHeight + 2,
            // then make sure scrollTop is never at the absolute end, so there
            // is always room to scroll in both directions. We add an extra 1px
            // margin to the top/bottom of the content so at scrollTop=1px, it
            // looks like it should.
            if ( safariVersion >= 8 ) {
                scrollFixerHeight = 2;
                contentMargin = 'margin:1px 0;';
                this.on( 'scroll', this, '_setNotAtEnd' )
                    .addObserverForKey( 'isInDocument', this, '_setNotAtEnd' );
            }

            // Append the actual children of the scroll view. The children are
            // wrapped in a div to allow pull-to-refresh to easily shift
            // everything down, and so we can tweak margins to compensate for
            // Trick 2.
            layer.appendChild(
                el( 'div.ScrollViewContents', {
                    style: 'position:relative;' + contentMargin +
                        ( this.get( 'showScrollbarX' ) ?
                            '' : 'overflow:hidden;min-height:100%;' )
                }, [ children ] )
            );

            // Trick 3: Ensuring the view scrolls.
            // Following platform conventions, we assume a fixed height
            // ScrollView should always scroll, regardless of whether the
            // content is taller than the view, whereas a variable height
            // ScrollView just needs to scroll if the content requires it.
            // Therefore, if it's a fixed height view, we add an extra
            // invisible div permanently 1px below the height, so it always
            // has scrollable content.
            if ( isFixedDimensions ) {
                layer.appendChild(
                    el( 'div', {
                        style: 'position:absolute;top:100%;left:0px;' +
                            'width:1px;height:' + scrollFixerHeight + 'px;'
                    })
                );
            }
        },

        _setNotAtEnd: function () {
            if ( this.get( 'isInDocument' ) ) {
                var scrollTop = this.get( 'scrollTop' ),
                    scrollLeft = this.get( 'scrollLeft' );
                if ( !scrollTop ) {
                    this.scrollTo( scrollLeft, 1 );
                } else if ( scrollTop + this.get( 'pxHeight' ) ===
                        this.get( 'layer' ).scrollHeight ) {
                    this.scrollTo( scrollLeft, scrollTop - 1 );
                }
            }
        }.queue( 'after' ),

        preventRootScroll: function ( event ) {
            if ( !this.get( 'isFixedDimensions' ) ) {
                var layer = this.get( 'layer' );
                if ( layer.scrollHeight <= layer.offsetHeight ) {
                    event.preventDefault();
                }
            }
        }.on( 'touchmove' ),

        insertView: function ( view, relativeTo, where ) {
            if ( !relativeTo && this.get( 'isRendered' ) &&
                    where !== 'before' && where !== 'after' ) {
                relativeTo = this.get( 'scrollLayer' ).firstChild;
            }
            return ScrollView.parent.insertView.call(
                this, view, relativeTo, where );
        }
    });
}

NS.ScrollView = ScrollView;

}( this.O ) );
<|endoftext|>


<commit_before>require("./polyfill");

var sourceMapSupport = require("source-map-support");
var roadrunner       = require("roadrunner");
var util             = require("./util");
var to5              = require("./index");
var fs               = require("fs");
var _                = require("lodash");

sourceMapSupport.install({
  retrieveSourceMap: function (source) {
    var map = maps && maps[source];
    if (map) {
      return {
        url: null,
        map: map
      };
    } else {
      return null;
    }
  }
});

//

var blacklist  = [];

var blacklistTest = function (transformer, code) {
  try {
    if (_.isFunction(code)) {
      code();
    } else {
      new Function(code);
    }
    blacklist.push(transformer);
  } catch (err) {
    if (err.name !== "SyntaxError") throw err;
  }
};

blacklistTest("arrayComprehension", "var foo = [for (foo of bar) foo * foo];");
blacklistTest("generatorComprehension", "var foo = (for (foo of bar) foo * foo)");
blacklistTest("arrowFunctions", "var foo = x => x * x;");
blacklistTest("classes", "class Foo {}");
blacklistTest("computedPropertyNames", "var foo = { [foo]: bar };");
blacklistTest("constants", function () {
  try {
    new Function("const foo = 'foo';\nfoo = 'wow';");
  } catch (err) {
    return; // constants are supported
  }
  throw new SyntaxError;
});
blacklistTest("defaultParamaters", "var foo = function (bar = 0) {};");
blacklistTest("destructuring", "var { x, y } = { x: 0, y: 0 };");
blacklistTest("forOf", "for (var foo of bar) {}");
blacklistTest("generators", "function* foo() {}\nasync function bar() {}"); // generators/async functions delegated to same transformer
blacklistTest("letScoping", "let foo = 0;");
blacklistTest("modules", 'import foo from "from";');
blacklistTest("propertyMethodAssignment", "{ get foo() {} }");
blacklistTest("propertyNameShorthand", "var foo = { x, y };");
blacklistTest("restParameters", "function foo(...bar) {}");
blacklistTest("spread", "foo(...bar);");
blacklistTest("templateLiterals", "var foo = `foo`;");
blacklistTest("unicodeRegex", function () { new RegExp("foo", "u"); });

//

var transformOpts = {};
var ignoreRegex   = /node_modules/;
var onlyRegex;
var whitelist     = [];
var cache;
var exts          = {};
var maps          = {};
var old           = require.extensions[".js"];

var mtime = function (filename) {
  return +fs.statSync(filename).mtime;
};

var loader = function (m, filename) {
  if ((ignoreRegex && ignoreRegex.test(filename)) || (onlyRegex && !onlyRegex.test(filename))) {
    return old.apply(this, arguments);
  }

  var result;

  if (cache) {
    var cached = cache[filename];
    if (cached && cached.mtime === mtime(filename)) {
      result = cached;
    }
  }

  result = result || to5.transformFileSync(filename, _.extend({
    whitelist: whitelist,
    blacklist: blacklist,
    sourceMap: true,
    ast:       false
  }, transformOpts));

  if (cache) {
    result.mtime = mtime(filename);
    cache[filename] = result;
  }

  maps[filename] = result.map;

  m._compile(result.code, filename);
};

var hookExtensions = function (_exts) {
  _.each(exts, function (old, ext) {
    require.extensions[ext] = old;
  });

  exts = {};

  _.each(_exts, function (ext) {
    exts[ext] = require.extensions[ext];
    require.extensions[ext] = loader;
  });
};

hookExtensions(util.canCompile.EXTENSIONS);

module.exports = function (opts) {
  // normalise options
  opts = opts || {};
  if (_.isRegExp(opts)) opts = { ignore: opts };
  if (opts.ignoreRegex != null) opts.ignore = opts.ignoreRegex;

  if (opts.only != null) onlyRegex = util.regexify(opts.only);
  if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);

  if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));

  if (opts.cache) cache = opts.cache;
  if (opts.cache === false) cache = null;
  if (opts.cache === true) {
    roadrunner.load();
    roadrunner.setup();
    cache = roadrunner.get("6to5");
  }

  _.extend(transformOpts, opts);
};
<commit_msg>remove register blacklist tests<commit_after>require("./polyfill");

var sourceMapSupport = require("source-map-support");
var roadrunner       = require("roadrunner");
var util             = require("./util");
var to5              = require("./index");
var fs               = require("fs");
var _                = require("lodash");

sourceMapSupport.install({
  retrieveSourceMap: function (source) {
    var map = maps && maps[source];
    if (map) {
      return {
        url: null,
        map: map
      };
    } else {
      return null;
    }
  }
});

var transformOpts = {};
var ignoreRegex   = /node_modules/;
var onlyRegex;
var whitelist     = [];
var cache;
var exts          = {};
var maps          = {};
var old           = require.extensions[".js"];

var mtime = function (filename) {
  return +fs.statSync(filename).mtime;
};

var loader = function (m, filename) {
  if ((ignoreRegex && ignoreRegex.test(filename)) || (onlyRegex && !onlyRegex.test(filename))) {
    return old.apply(this, arguments);
  }

  var result;

  if (cache) {
    var cached = cache[filename];
    if (cached && cached.mtime === mtime(filename)) {
      result = cached;
    }
  }

  result = result || to5.transformFileSync(filename, _.extend({
    whitelist: whitelist,
    sourceMap: true,
    ast:       false
  }, transformOpts));

  if (cache) {
    result.mtime = mtime(filename);
    cache[filename] = result;
  }

  maps[filename] = result.map;

  m._compile(result.code, filename);
};

var hookExtensions = function (_exts) {
  _.each(exts, function (old, ext) {
    require.extensions[ext] = old;
  });

  exts = {};

  _.each(_exts, function (ext) {
    exts[ext] = require.extensions[ext];
    require.extensions[ext] = loader;
  });
};

hookExtensions(util.canCompile.EXTENSIONS);

module.exports = function (opts) {
  // normalise options
  opts = opts || {};
  if (_.isRegExp(opts)) opts = { ignore: opts };
  if (opts.ignoreRegex != null) opts.ignore = opts.ignoreRegex;

  if (opts.only != null) onlyRegex = util.regexify(opts.only);
  if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);

  if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));

  if (opts.cache) cache = opts.cache;
  if (opts.cache === false) cache = null;
  if (opts.cache === true) {
    roadrunner.load();
    roadrunner.setup();
    cache = roadrunner.get("6to5");
  }

  _.extend(transformOpts, opts);
};
<|endoftext|>


<commit_before>'use strict';
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var mountFolder = function (connect, dir) {
    return connect.static(require('path').resolve(dir));
};

module.exports = function (grunt) {
    // load all grunt tasks
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    // configurable paths
    var yeomanConfig = {
        app: 'app',
        dist: 'dist'
    };

    grunt.initConfig({
        yeoman: yeomanConfig,
        watch: {
            coffee: {
                files: ['<%%= yeoman.app %>/scripts/*.coffee'],
                tasks: ['coffee:dist']
            },
            coffeeTest: {
                files: ['test/spec/*.coffee'],
                tasks: ['coffee:test']
            },
            compass: {
                files: ['<%%= yeoman.app %>/styles/*.{scss,sass}'],
                tasks: ['compass']
            },
            livereload: {
                files: [
                    '<%%= yeoman.app %>/*.html',
                    '{.tmp,<%%= yeoman.app %>}/styles/*.css',
                    '{.tmp,<%%= yeoman.app %>}/scripts/*.js',
                    '<%%= yeoman.app %>/images/*.{png,jpg,jpeg}'
                ],
                tasks: ['livereload']
            }
        },
        connect: {
            options: {
                port: 9000,
                // Change this to '0.0.0.0' to access the server from outside.
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    middleware: function (connect) {
                        return [
                            lrSnippet,
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, 'app')
                        ];
                    }
                }
            },
            test: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, 'test')
                        ];
                    }
                }
            },
            dist: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, 'dist')
                        ];
                    }
                }
            }
        },
        open: {
            server: {
                url: 'http://localhost:<%%= connect.options.port %>'
            }
        },
        clean: {
            dist: ['.tmp', '<%%= yeoman.dist %>/*'],
            server: '.tmp'
        },
        jshint: {
            options: {
                jshintrc: '.jshintrc'
            },
            all: [
                'Gruntfile.js',
                '<%%= yeoman.app %>/scripts/*.js',
                'test/spec/*.js'
            ]
        },
        mocha: {
            all: {
                options: {
                    run: true,
                    urls: ['http://localhost:<%%= connect.options.port %>/index.html']
                }
            }
        },
        coffee: {
            dist: {
                files: {
                    '.tmp/scripts/coffee.js': '<%%= yeoman.app %>/scripts/*.coffee'
                }
            },
            test: {
                files: [{
                    expand: true,
                    cwd: '.tmp/spec',
                    src: '*.coffee',
                    dest: 'test/spec'
                }]
            }
        },
        compass: {
            options: {
                sassDir: '<%%= yeoman.app %>/styles',
                cssDir: '.tmp/styles',
                imagesDir: '<%%= yeoman.app %>/images',
                javascriptsDir: '<%%= yeoman.app %>/scripts',
                fontsDir: '<%%= yeoman.app %>/styles/fonts',
                importPath: 'app/components',
                relativeAssets: true
            },
            dist: {},
            server: {
                options: {
                    debugInfo: true
                }
            }
        },
        // not used since Uglify task does concat,
        // but still available if needed
        /*concat: {
            dist: {}
        },*/
        <% if (includeRequireJS) { %>requirejs: {
            dist: {
                // Options: https://github.com/jrburke/r.js/blob/master/build/example.build.js
                options: {
                    // `name` and `out` is set by grunt-usemin
                    baseUrl: 'app/scripts',
                    optimize: 'none',
                    // TODO: Figure out how to make sourcemaps work with grunt-usemin
                    // https://github.com/yeoman/grunt-usemin/issues/30
                    //generateSourceMaps: true,
                    // required to support SourceMaps
                    // http://requirejs.org/docs/errors.html#sourcemapcomments
                    preserveLicenseComments: false,
                    useStrict: true,
                    wrap: true,
                    //uglify2: {} // https://github.com/mishoo/UglifyJS2
                    mainConfigFile: 'app/scripts/main.js'
                }
            }
        },<% } else { %>
        uglify: {
            dist: {
                files: {
                    '<%%= yeoman.dist %>/scripts/main.js': [
                        '.tmp/scripts/*.js',
                        '<%%= yeoman.app %>/scripts/*.js'
                    ],
                }
            }
        },<% } %>
        useminPrepare: {
            html: '<%%= yeoman.app %>/index.html',
            options: {
                dest: '<%%= yeoman.dist %>'
            }
        },
        usemin: {
            html: ['<%%= yeoman.dist %>/*.html'],
            css: ['<%%= yeoman.dist %>/styles/*.css'],
            options: {
                dirs: ['<%%= yeoman.dist %>']
            }
        },
        imagemin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%%= yeoman.app %>/images',
                    src: '*.{png,jpg,jpeg}',
                    dest: '<%%= yeoman.dist %>/images'
                }]
            }
        },
        cssmin: {
            dist: {
                files: {
                    '<%%= yeoman.dist %>/styles/main.css': [
                        '.tmp/styles/*.css',
                        '<%%= yeoman.app %>/styles/*.css'
                    ]
                }
            }
        },
        htmlmin: {
            dist: {
                options: {
                    /*removeCommentsFromCDATA: true,
                    // https://github.com/yeoman/grunt-usemin/issues/44
                    //collapseWhitespace: true,
                    collapseBooleanAttributes: true,
                    removeAttributeQuotes: true,
                    removeRedundantAttributes: true,
                    useShortDoctype: true,
                    removeEmptyAttributes: true,
                    removeOptionalTags: true*/
                },
                files: [{
                    expand: true,
                    cwd: '<%%= yeoman.app %>',
                    src: '*.html',
                    dest: '<%%= yeoman.dist %>'
                }]
            }
        },
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%%= yeoman.app %>',
                    dest: '<%%= yeoman.dist %>',
                    src: [
                        '*.{ico,txt}',
                        '.htaccess'
                    ]
                }]
            }
        },
        bower: {
            rjsConfig: 'app/scripts/main.js',
            indent: '    '
        }
    });

    grunt.renameTask('regarde', 'watch');
    // remove when mincss task is renamed
    grunt.renameTask('mincss', 'cssmin');

    grunt.registerTask('server', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['open', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'coffee:dist',
            'compass:server',
            'livereload-start',
            'connect:livereload',
            'open',
            'watch'
        ]);
    });

    grunt.registerTask('test', [
        'clean:server',
        'coffee',
        'compass',
        'connect:test',
        'mocha'
    ]);

    grunt.registerTask('build', [
        'clean:dist',
        'jshint',
        'test',
        'coffee',
        'compass:dist',
        'useminPrepare',<% if (includeRequireJS) { %>
        'requirejs',<% } %>
        'imagemin',
        'cssmin',
        'htmlmin',
        'concat',
        'uglify',
        'copy',
        'usemin'
    ]);

    grunt.registerTask('default', ['build']);
};
<commit_msg>Remove cssmin rename<commit_after>'use strict';
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var mountFolder = function (connect, dir) {
    return connect.static(require('path').resolve(dir));
};

module.exports = function (grunt) {
    // load all grunt tasks
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    // configurable paths
    var yeomanConfig = {
        app: 'app',
        dist: 'dist'
    };

    grunt.initConfig({
        yeoman: yeomanConfig,
        watch: {
            coffee: {
                files: ['<%%= yeoman.app %>/scripts/*.coffee'],
                tasks: ['coffee:dist']
            },
            coffeeTest: {
                files: ['test/spec/*.coffee'],
                tasks: ['coffee:test']
            },
            compass: {
                files: ['<%%= yeoman.app %>/styles/*.{scss,sass}'],
                tasks: ['compass']
            },
            livereload: {
                files: [
                    '<%%= yeoman.app %>/*.html',
                    '{.tmp,<%%= yeoman.app %>}/styles/*.css',
                    '{.tmp,<%%= yeoman.app %>}/scripts/*.js',
                    '<%%= yeoman.app %>/images/*.{png,jpg,jpeg}'
                ],
                tasks: ['livereload']
            }
        },
        connect: {
            options: {
                port: 9000,
                // Change this to '0.0.0.0' to access the server from outside.
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    middleware: function (connect) {
                        return [
                            lrSnippet,
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, 'app')
                        ];
                    }
                }
            },
            test: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, 'test')
                        ];
                    }
                }
            },
            dist: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, 'dist')
                        ];
                    }
                }
            }
        },
        open: {
            server: {
                url: 'http://localhost:<%%= connect.options.port %>'
            }
        },
        clean: {
            dist: ['.tmp', '<%%= yeoman.dist %>/*'],
            server: '.tmp'
        },
        jshint: {
            options: {
                jshintrc: '.jshintrc'
            },
            all: [
                'Gruntfile.js',
                '<%%= yeoman.app %>/scripts/*.js',
                'test/spec/*.js'
            ]
        },
        mocha: {
            all: {
                options: {
                    run: true,
                    urls: ['http://localhost:<%%= connect.options.port %>/index.html']
                }
            }
        },
        coffee: {
            dist: {
                files: {
                    '.tmp/scripts/coffee.js': '<%%= yeoman.app %>/scripts/*.coffee'
                }
            },
            test: {
                files: [{
                    expand: true,
                    cwd: '.tmp/spec',
                    src: '*.coffee',
                    dest: 'test/spec'
                }]
            }
        },
        compass: {
            options: {
                sassDir: '<%%= yeoman.app %>/styles',
                cssDir: '.tmp/styles',
                imagesDir: '<%%= yeoman.app %>/images',
                javascriptsDir: '<%%= yeoman.app %>/scripts',
                fontsDir: '<%%= yeoman.app %>/styles/fonts',
                importPath: 'app/components',
                relativeAssets: true
            },
            dist: {},
            server: {
                options: {
                    debugInfo: true
                }
            }
        },
        // not used since Uglify task does concat,
        // but still available if needed
        /*concat: {
            dist: {}
        },*/
        <% if (includeRequireJS) { %>requirejs: {
            dist: {
                // Options: https://github.com/jrburke/r.js/blob/master/build/example.build.js
                options: {
                    // `name` and `out` is set by grunt-usemin
                    baseUrl: 'app/scripts',
                    optimize: 'none',
                    // TODO: Figure out how to make sourcemaps work with grunt-usemin
                    // https://github.com/yeoman/grunt-usemin/issues/30
                    //generateSourceMaps: true,
                    // required to support SourceMaps
                    // http://requirejs.org/docs/errors.html#sourcemapcomments
                    preserveLicenseComments: false,
                    useStrict: true,
                    wrap: true,
                    //uglify2: {} // https://github.com/mishoo/UglifyJS2
                    mainConfigFile: 'app/scripts/main.js'
                }
            }
        },<% } else { %>
        uglify: {
            dist: {
                files: {
                    '<%%= yeoman.dist %>/scripts/main.js': [
                        '.tmp/scripts/*.js',
                        '<%%= yeoman.app %>/scripts/*.js'
                    ],
                }
            }
        },<% } %>
        useminPrepare: {
            html: '<%%= yeoman.app %>/index.html',
            options: {
                dest: '<%%= yeoman.dist %>'
            }
        },
        usemin: {
            html: ['<%%= yeoman.dist %>/*.html'],
            css: ['<%%= yeoman.dist %>/styles/*.css'],
            options: {
                dirs: ['<%%= yeoman.dist %>']
            }
        },
        imagemin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%%= yeoman.app %>/images',
                    src: '*.{png,jpg,jpeg}',
                    dest: '<%%= yeoman.dist %>/images'
                }]
            }
        },
        cssmin: {
            dist: {
                files: {
                    '<%%= yeoman.dist %>/styles/main.css': [
                        '.tmp/styles/*.css',
                        '<%%= yeoman.app %>/styles/*.css'
                    ]
                }
            }
        },
        htmlmin: {
            dist: {
                options: {
                    /*removeCommentsFromCDATA: true,
                    // https://github.com/yeoman/grunt-usemin/issues/44
                    //collapseWhitespace: true,
                    collapseBooleanAttributes: true,
                    removeAttributeQuotes: true,
                    removeRedundantAttributes: true,
                    useShortDoctype: true,
                    removeEmptyAttributes: true,
                    removeOptionalTags: true*/
                },
                files: [{
                    expand: true,
                    cwd: '<%%= yeoman.app %>',
                    src: '*.html',
                    dest: '<%%= yeoman.dist %>'
                }]
            }
        },
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%%= yeoman.app %>',
                    dest: '<%%= yeoman.dist %>',
                    src: [
                        '*.{ico,txt}',
                        '.htaccess'
                    ]
                }]
            }
        },
        bower: {
            rjsConfig: 'app/scripts/main.js',
            indent: '    '
        }
    });

    grunt.renameTask('regarde', 'watch');

    grunt.registerTask('server', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['open', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'coffee:dist',
            'compass:server',
            'livereload-start',
            'connect:livereload',
            'open',
            'watch'
        ]);
    });

    grunt.registerTask('test', [
        'clean:server',
        'coffee',
        'compass',
        'connect:test',
        'mocha'
    ]);

    grunt.registerTask('build', [
        'clean:dist',
        'jshint',
        'test',
        'coffee',
        'compass:dist',
        'useminPrepare',<% if (includeRequireJS) { %>
        'requirejs',<% } %>
        'imagemin',
        'cssmin',
        'htmlmin',
        'concat',
        'uglify',
        'copy',
        'usemin'
    ]);

    grunt.registerTask('default', ['build']);
};
<|endoftext|>


<commit_before>'use strict';

var BN = require('./bn');
var Point = require('./point');
var Signature = require('./signature');
var PublicKey = require('../publickey');
var Random = require('./random');
var Hash = require('./hash');
var BufferUtil = require('../util/buffer');
var _ = require('lodash');
var $ = require('../util/preconditions');

var Schnorr = function Schnorr(obj) {
  if (!(this instanceof Schnorr)) {
    return new Schnorr(obj);
  }
  if (obj) {
    this.set(obj);
  }
};

/* jshint maxcomplexity: 9 */
Schnorr.prototype.set = function(obj) {
    this.hashbuf = obj.hashbuf || this.hashbuf;
    this.endian = obj.endian || this.endian; //the endianness of hashbuf
    this.privkey = obj.privkey || this.privkey;
    this.pubkey = obj.pubkey || (this.privkey ? this.privkey.publicKey : this.pubkey);
    this.sig = obj.sig || this.sig;
    this.verified = obj.verified || this.verified;
    return this;
};

Schnorr.prototype.privkey2pubkey = function() {
    this.pubkey = this.privkey.toPublicKey();
};

Schnorr.prototype.sign = function() {
    var hashbuf = this.hashbuf;
    var privkey = this.privkey;
    var d = privkey.bn;

    $.checkState(hashbuf && privkey && d, new Error('invalid parameters'));
    $.checkState(BufferUtil.isBuffer(hashbuf) && hashbuf.length === 32, new Error('hashbuf must be a 32 byte buffer'));

    var e = BN.fromBuffer(hashbuf, this.endian ? {
      endian: this.endian
    } : undefined);

    var obj = this._findSignature(d, e);
    obj.compressed = this.pubkey.compressed;

    this.sig = new Signature(obj);
    return this;
};

Schnorr.prototype._findSignature = function(d, e) {
    // d is the private key;
    // e is the message to be signed

    var dPrime, D, P, N, G, R, k;
    N = Point.getN();
    G = Point.getG();
    dPrime = d;
    D = d;

    $.checkState(!d.lte(0), new Error('privkey out of field of curve'));
    $.checkState(!d.gte(N), new Error('privkey out of field of curve'));
    P = G.mul(dPrime);

    if((P.hasSquare())) {
      console.log("private key", d);
      D = d;
    } else {
      D = N.sub(dPrime);
    }

    let secretKeyMessageConcat =  Buffer.concat([D.toBuffer(), e.toBuffer()]);
    //console.log("secretKeyMessageConcat", secretKeyMessageConcat);
    let secretKeyMessageConcatBIPSchnorrHash = taggedHash("BIPSchnorrDerive", secretKeyMessageConcat);
    //console.log(secretKeyMessageConcatBIPSchnorrHash, "SecretKeyMessageConcatBIPSchnorrDeriveHash");
    let k0 = (BN.fromBuffer(secretKeyMessageConcatBIPSchnorrHash).umod(N));

    // k should be of type number here.
    $.checkState(!k0.eqn(0), new Error('Failure. This happens only with negligible probability.'));

    R = G.mul(k0);

    // Find deterministic k
    if(R.hasSquare()) {
      k = k0;
    } else {
      k = N.sub(k0);
    }

    let concatBytes = Buffer.concat([R.getX().toBuffer(), P.getX().toBuffer(), e.toBuffer()]);
    let pointConcat= taggedHash("BIPSchnorr", concatBytes);
    let eSig = BN.fromBuffer(pointConcat).mod(N);

    let a = (eSig.mul(D)).add(k);
    let half_sig = a.mod(N);

    let sig = Buffer.concat([R.getX().toBuffer(), half_sig.toBuffer()]);

    let r = sig.slice(0, 32);
    let s = sig.slice(32, 64);

    return {
      r: BN.fromBuffer(r),
      s: BN.fromBuffer(s)
    };
  };

  Schnorr.prototype.sigError = function() {
    if (!BufferUtil.isBuffer(this.hashbuf) || this.hashbuf.length !== 32) {
      return 'hashbuf must be a 32 byte buffer';
    }

    var sigBuf = this.sig.toBuffer();

    console.log("this.sig", this.sig)
    console.log("sigBuf length", sigBuf.length);

    // if(sigBuf.length !== 64 || sigBuf.length !==65) {
    //   return 'signature must be a 64 byte or 65 byte array';
    // }

    // if(this.pubkey.toBuffer().length !== 32 || this.pubkey.toBuffer().length !== 33 ) {
    //   return 'public key must be a 32 bytes';
    // }

    var pubkeyObj = this.pubkey.toObject();

    var P = pubkeyPointfromX(BN.fromString(pubkeyObj.x, 'hex'));
    var publicKey = PublicKey(P, { compressed: true } );
    console.log(publicKey);
    var G = Point.getG();

    if(P.isInfinity()) return true;

    var r = this.sig.r;
    var s = this.sig.s;

    let p = new BN('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 'hex');
    let n = Point.getN();

    if(r.gte(p) || s.gte(n)) {
      console.log("Failed >= condition");
      return true;
    }

    let hash = taggedHash("BIPSchnorr", Buffer.concat([r.toBuffer(), this.pubkey.toBuffer().slice(1,33), this.hashbuf]));
    let e = BN.fromBuffer(hash, 'big').umod(n);

    let sG = G.mul(s);
    let eP = P.mul(new BN(n.sub(e)));
    let R = sG.add(eP);

    if(R.isInfinity() || !R.hasSquare() || !R.getX().eq(r)) {
      return true;
    }
    return false;
  };

  Schnorr.prototype.verify = function() {
    if (!this.sigError()) {
      this.verified = true;
    } else {
      this.verified = false;
    }
    return this;
  };

  /**
  * @param {tag | string}
  * @param {bytesSecretKeyMessage | Buffer} buffer to be hashed
  */
  function taggedHash(tag,bytesSecretKeyMessage) {
    let tagHash = Hash.sha256(Buffer.from(tag, 'utf-8'));
    // console.log("tagHash", tagHash);
    return Hash.sha256(Buffer.concat([tagHash, tagHash, bytesSecretKeyMessage]));
  }

  Schnorr.sign = function(hashbuf, privkey, endian) {
    return Schnorr().set({
      hashbuf: hashbuf,
      endian: endian,
      privkey: privkey
    }).sign().sig;
  };

  Schnorr.verify = function(hashbuf, sig, pubkey, endian) {
    return Schnorr().set({
      hashbuf: hashbuf,
      endian: endian,
      sig: sig,
      pubkey: pubkey
    }).verify().verified;
  };

  /**
   *
   * @param {*} x | BN, public key curve
   * @return undefined | Point(x,y) point for public key.
   */
  function pubkeyPointfromX(x) {
    let p = new BN('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 'hex');
    if (x.gte(p)) {
      return undefined;
    }
    let ySq = modPow(x,new BN(3),p).add(new BN(7)).mod(p);
    let y = modPow(ySq, p.add(new BN(1)).div(new BN(4)), p);
    if (!modPow(y, new BN(2), p).eq(ySq)) {
      return undefined;
    }
    return new Point(x, y);
  }

  /**
   * use Red reduction for faster calculation modular exponentiation
   * @param {*} base BN
   * @param {*} exponent BN
   * @param {*} moduloDivisor BN
   * @return (base^power) % moduloDivisor
   */
  function modPow(base, power, moduloDivisor) {
    let redMultiplier = base.toRed(BN.red(moduloDivisor));
    return redMultiplier.redPow(power).fromRed();
  }

  module.exports = Schnorr;

<commit_msg>correct schnorr sigError with right r,s indices<commit_after>'use strict';

var BN = require('./bn');
var Point = require('./point');
var Signature = require('./signature');
var PublicKey = require('../publickey');
var Random = require('./random');
var Hash = require('./hash');
var BufferUtil = require('../util/buffer');
var _ = require('lodash');
var $ = require('../util/preconditions');

var Schnorr = function Schnorr(obj) {
  if (!(this instanceof Schnorr)) {
    return new Schnorr(obj);
  }
  if (obj) {
    this.set(obj);
  }
};

/* jshint maxcomplexity: 9 */
Schnorr.prototype.set = function(obj) {
    this.hashbuf = obj.hashbuf || this.hashbuf;
    this.endian = obj.endian || this.endian; //the endianness of hashbuf
    this.privkey = obj.privkey || this.privkey;
    this.pubkey = obj.pubkey || (this.privkey ? this.privkey.publicKey : this.pubkey);
    this.sig = obj.sig || this.sig;
    this.verified = obj.verified || this.verified;
    return this;
};

Schnorr.prototype.privkey2pubkey = function() {
    this.pubkey = this.privkey.toPublicKey();
};

Schnorr.prototype.sign = function() {
    var hashbuf = this.hashbuf;
    var privkey = this.privkey;
    var d = privkey.bn;

    $.checkState(hashbuf && privkey && d, new Error('invalid parameters'));
    $.checkState(BufferUtil.isBuffer(hashbuf) && hashbuf.length === 32, new Error('hashbuf must be a 32 byte buffer'));

    var e = BN.fromBuffer(hashbuf, this.endian ? {
      endian: this.endian
    } : undefined);

    var obj = this._findSignature(d, e);
    obj.compressed = this.pubkey.compressed;
    obj.isSchnorr = true;

    this.sig = new Signature(obj);
    return this;
};

// Changed to use the fool
Schnorr.prototype._findSignature = function(d, e) {
    // d is the private key;
    // e is the message to be signed

    var dPrime, D, P, N, G, R, k;
    N = Point.getN();
    G = Point.getG();
    dPrime = d;
    D = d;

    $.checkState(!d.lte(0), new Error('privkey out of field of curve'));
    $.checkState(!d.gte(N), new Error('privkey out of field of curve'));
    P = G.mul(dPrime);

    if((P.hasSquare())) {
      D = d;
    } else {
      D = N.sub(dPrime);
    }

    let secretKeyMessageConcat =  Buffer.concat([D.toBuffer(), e.toBuffer()]);
    let secretKeyMessageConcatBIPSchnorrHash = taggedHash("BIPSchnorrDerive", secretKeyMessageConcat);
    let k0 = (BN.fromBuffer(secretKeyMessageConcatBIPSchnorrHash).umod(N));

    // k should be of type number here.
    $.checkState(!k0.eqn(0), new Error('Failure. This happens only with negligible probability.'));

    R = G.mul(k0);

    // Find deterministic k
    if(R.hasSquare()) {
      k = k0;
    } else {
      k = N.sub(k0);
    }

    let concatBytes = Buffer.concat([R.getX().toBuffer(), P.getX().toBuffer(), e.toBuffer()]);
    let pointConcat= taggedHash("BIPSchnorr", concatBytes);
    let eSig = BN.fromBuffer(pointConcat).mod(N);

    let a = (eSig.mul(D)).add(k);
    let half_sig = a.mod(N);

    let sig = Buffer.concat([R.getX().toBuffer(), half_sig.toBuffer()]);

    let r = sig.slice(0, 32);
    let s = sig.slice(32, 64);

    console.log("r", r);

    console.log("s", s)

    return {
      r: BN.fromBuffer(r),
      s: BN.fromBuffer(s)
    };
  };

  Schnorr.prototype.sigError = function() {
    if (!BufferUtil.isBuffer(this.hashbuf) || this.hashbuf.length !== 32) {
      return 'hashbuf must be a 32 byte buffer';
    }

    var sigBuf = this.sig.toBuffer();

    // if(sigBuf.length !== 64 || sigBuf.length !==65) {
    //   return 'signature must be a 64 byte or 65 byte array';
    // }

    // if(this.pubkey.toBuffer().length !== 32 || this.pubkey.toBuffer().length !== 33 ) {
    //   return 'public key must be a 32 bytes';
    // }

    var pubkeyObj = this.pubkey.toObject();

    var P = pubkeyPointfromX(BN.fromString(pubkeyObj.x, 'hex'));
    var publicKey = PublicKey(P, { compressed: true } );
    var G = Point.getG();

    if(P.isInfinity()) return true;

    var r = this.sig.r;
    var s = this.sig.s;

    let p = new BN('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 'hex');
    let n = Point.getN();

    if(r.gte(p) || s.gte(n)) {
      console.log("Failed >= condition");
      return true;
    }

    let hash = taggedHash("BIPSchnorr", Buffer.concat([r.toBuffer(), this.pubkey.toBuffer().slice(1,33), this.hashbuf]));
    let e = BN.fromBuffer(hash, 'big').umod(n);

    let sG = G.mul(s);
    let eP = P.mul(new BN(n.sub(e)));
    let R = sG.add(eP);

    if(R.isInfinity() || !R.hasSquare() || !R.getX().eq(r)) {
      return true;
    }
    return false;
  };

  Schnorr.prototype.verify = function() {
    if (!this.sigError()) {
      this.verified = true;
    } else {
      this.verified = false;
    }
    return this;
  };

  /**
  * @param {tag | string}
  * @param {bytesSecretKeyMessage | Buffer} buffer to be hashed
  */
  function taggedHash(tag,bytesSecretKeyMessage) {
    let tagHash = Hash.sha256(Buffer.from(tag, 'utf-8'));
    return Hash.sha256(Buffer.concat([tagHash, tagHash, bytesSecretKeyMessage]));
  }

  Schnorr.sign = function(hashbuf, privkey, endian) {
    return Schnorr().set({
      hashbuf: hashbuf,
      endian: endian,
      privkey: privkey
    }).sign().sig;
  };

  Schnorr.verify = function(hashbuf, sig, pubkey, endian) {
    return Schnorr().set({
      hashbuf: hashbuf,
      endian: endian,
      sig: sig,
      pubkey: pubkey
    }).verify().verified;
  };

  /**
   *
   * @param {*} x | BN, public key curve
   * @return undefined | Point(x,y) point for public key.
   */
  function pubkeyPointfromX(x) {
    let p = new BN('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 'hex');
    if (x.gte(p)) {
      return undefined;
    }
    let ySq = modPow(x,new BN(3),p).add(new BN(7)).mod(p);
    let y = modPow(ySq, p.add(new BN(1)).div(new BN(4)), p);
    if (!modPow(y, new BN(2), p).eq(ySq)) {
      return undefined;
    }
    return new Point(x, y);
  }

  /**
   * use Red reduction for faster calculation modular exponentiation
   * @param {*} base BN
   * @param {*} exponent BN
   * @param {*} moduloDivisor BN
   * @return (base^power) % moduloDivisor
   */
  function modPow(base, power, moduloDivisor) {
    let redMultiplier = base.toRed(BN.red(moduloDivisor));
    return redMultiplier.redPow(power).fromRed();
  }

  module.exports = Schnorr;

<|endoftext|>


<commit_before>'use babel';

import fs from 'fs-extra';
import temp from 'temp';
import specHelpers from 'atom-build-spec-helpers';
import os from 'os';

describe('Target', () => {
  const originalHomedirFn = os.homedir;
  let directory = null;
  let workspaceElement = null;

  temp.track();

  beforeEach(() => {
    atom.config.set('build.buildOnSave', false);
    atom.config.set('build.panelVisibility', 'Toggle');
    atom.config.set('build.saveOnBuild', false);
    atom.config.set('build.notificationOnRefresh', true);

    jasmine.unspy(window, 'setTimeout');
    jasmine.unspy(window, 'clearTimeout');

    workspaceElement = atom.views.getView(atom.workspace);
    workspaceElement.setAttribute('style', 'width:9999px');
    jasmine.attachToDOM(workspaceElement);

    waitsForPromise(() => {
      return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then((dir) => {
        return specHelpers.vouch(fs.realpath, dir);
      }).then((dir) => {
        directory = dir + '/';
        atom.project.setPaths([ directory ]);
        return specHelpers.vouch(temp.mkdir, 'atom-build-spec-home');
      }).then( (dir) => {
        return specHelpers.vouch(fs.realpath, dir);
      }).then( (dir) => {
        os.homedir = () => dir;
        return atom.packages.activatePackage('build');
      });
    });
  });

  afterEach(() => {
    os.homedir = originalHomedirFn;
    fs.removeSync(directory);
  });

  describe('when multiple targets exists', () => {
    it('should list those targets in a SelectListView (from .atom-build.json)', () => {
      waitsForPromise(() => {
        const file = __dirname + '/fixture/.atom-build.targets.json';
        return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json')
          .then(() => specHelpers.refreshAwaitTargets());
      });

      waitsForPromise(() => specHelpers.refreshAwaitTargets());

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:select-active-target');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.select-list li.build-target');
      });

      runs(() => {
        const targets = [ ...workspaceElement.querySelectorAll('.select-list li.build-target') ].map(el => el.textContent);
        expect(targets).toEqual([ 'Custom: The default build', 'Custom: Some customized build' ]);
      });
    });

    it('should mark the first target as active', () => {
      waitsForPromise(() => {
        const file = __dirname + '/fixture/.atom-build.targets.json';
        return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json')
          .then(() => specHelpers.refreshAwaitTargets());
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:select-active-target');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.select-list li.build-target');
      });

      runs(() => {
        const el = workspaceElement.querySelector('.select-list li.build-target'); // querySelector selects the first element
        expect(el).toHaveClass('selected');
        expect(el).toHaveClass('active');
      });
    });

    it('should run the selected build', () => {
      waitsForPromise(() => {
        const file = __dirname + '/fixture/.atom-build.targets.json';
        return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json')
          .then(() => specHelpers.refreshAwaitTargets());
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:select-active-target');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.select-list li.build-target');
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:confirm');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.build .title') &&
          workspaceElement.querySelector('.build .title').classList.contains('success');
      });

      runs(() => {
        expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
      });
    });

    it('should run the default target if no selection has been made', () => {
      waitsForPromise(() => {
        const file = __dirname + '/fixture/.atom-build.targets.json';
        return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json')
          .then(() => specHelpers.refreshAwaitTargets());
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:trigger');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.build .title') &&
          workspaceElement.querySelector('.build .title').classList.contains('success');
      });

      runs(() => {
        expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
      });
    });

    it('run the selected target if selection has changed, and subsequent build should run that target', () => {
      waitsForPromise(() => {
        const file = __dirname + '/fixture/.atom-build.targets.json';
        return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json')
          .then(() => specHelpers.refreshAwaitTargets());
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:select-active-target');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.select-list li.build-target');
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:move-down');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.select-list li.selected').textContent === 'Custom: Some customized build';
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:confirm');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.build .title') &&
          workspaceElement.querySelector('.build .title').classList.contains('success');
      });

      runs(() => {
        expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/customized/);
        atom.commands.dispatch(workspaceElement.querySelector('.build'), 'build:stop');
      });

      waitsFor(() => {
        return !workspaceElement.querySelector('.build');
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:trigger');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.build .title') &&
          workspaceElement.querySelector('.build .title').classList.contains('success');
      });

      runs(() => {
        expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/customized/);
      });
    });

    it('should show a warning if current file is not part of an open Atom project', () => {
      waitsForPromise(() => atom.workspace.open('/randomFile'));
      waitsForPromise(() => specHelpers.refreshAwaitTargets());
      runs(() => atom.commands.dispatch(workspaceElement, 'build:select-active-target'));
      waitsFor(() => atom.notifications.getNotifications().find(n => n.message === 'Unable to build.'));
      runs(() => {
        const not = atom.notifications.getNotifications().find(n => n.message === 'Unable to build.');
        expect(not.type).toBe('warning');
      });
    });
  });
});
<commit_msg>Platform independant specs<commit_after>'use babel';

import fs from 'fs-extra';
import temp from 'temp';
import path from 'path';
import specHelpers from 'atom-build-spec-helpers';
import os from 'os';

describe('Target', () => {
  const originalHomedirFn = os.homedir;
  let directory = null;
  let workspaceElement = null;

  temp.track();

  beforeEach(() => {
    atom.config.set('build.buildOnSave', false);
    atom.config.set('build.panelVisibility', 'Toggle');
    atom.config.set('build.saveOnBuild', false);
    atom.config.set('build.notificationOnRefresh', true);

    jasmine.unspy(window, 'setTimeout');
    jasmine.unspy(window, 'clearTimeout');

    workspaceElement = atom.views.getView(atom.workspace);
    workspaceElement.setAttribute('style', 'width:9999px');
    jasmine.attachToDOM(workspaceElement);

    waitsForPromise(() => {
      return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then((dir) => {
        return specHelpers.vouch(fs.realpath, dir);
      }).then((dir) => {
        directory = dir + '/';
        atom.project.setPaths([ directory ]);
        return specHelpers.vouch(temp.mkdir, 'atom-build-spec-home');
      }).then( (dir) => {
        return specHelpers.vouch(fs.realpath, dir);
      }).then( (dir) => {
        os.homedir = () => dir;
        return atom.packages.activatePackage('build');
      });
    });
  });

  afterEach(() => {
    os.homedir = originalHomedirFn;
    fs.removeSync(directory);
  });

  describe('when multiple targets exists', () => {
    it('should list those targets in a SelectListView (from .atom-build.json)', () => {
      waitsForPromise(() => {
        const file = __dirname + '/fixture/.atom-build.targets.json';
        return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json')
          .then(() => specHelpers.refreshAwaitTargets());
      });

      waitsForPromise(() => specHelpers.refreshAwaitTargets());

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:select-active-target');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.select-list li.build-target');
      });

      runs(() => {
        const targets = [ ...workspaceElement.querySelectorAll('.select-list li.build-target') ].map(el => el.textContent);
        expect(targets).toEqual([ 'Custom: The default build', 'Custom: Some customized build' ]);
      });
    });

    it('should mark the first target as active', () => {
      waitsForPromise(() => {
        const file = __dirname + '/fixture/.atom-build.targets.json';
        return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json')
          .then(() => specHelpers.refreshAwaitTargets());
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:select-active-target');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.select-list li.build-target');
      });

      runs(() => {
        const el = workspaceElement.querySelector('.select-list li.build-target'); // querySelector selects the first element
        expect(el).toHaveClass('selected');
        expect(el).toHaveClass('active');
      });
    });

    it('should run the selected build', () => {
      waitsForPromise(() => {
        const file = __dirname + '/fixture/.atom-build.targets.json';
        return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json')
          .then(() => specHelpers.refreshAwaitTargets());
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:select-active-target');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.select-list li.build-target');
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:confirm');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.build .title') &&
          workspaceElement.querySelector('.build .title').classList.contains('success');
      });

      runs(() => {
        expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
      });
    });

    it('should run the default target if no selection has been made', () => {
      waitsForPromise(() => {
        const file = __dirname + '/fixture/.atom-build.targets.json';
        return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json')
          .then(() => specHelpers.refreshAwaitTargets());
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:trigger');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.build .title') &&
          workspaceElement.querySelector('.build .title').classList.contains('success');
      });

      runs(() => {
        expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
      });
    });

    it('run the selected target if selection has changed, and subsequent build should run that target', () => {
      waitsForPromise(() => {
        const file = __dirname + '/fixture/.atom-build.targets.json';
        return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json')
          .then(() => specHelpers.refreshAwaitTargets());
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:select-active-target');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.select-list li.build-target');
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:move-down');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.select-list li.selected').textContent === 'Custom: Some customized build';
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:confirm');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.build .title') &&
          workspaceElement.querySelector('.build .title').classList.contains('success');
      });

      runs(() => {
        expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/customized/);
        atom.commands.dispatch(workspaceElement.querySelector('.build'), 'build:stop');
      });

      waitsFor(() => {
        return !workspaceElement.querySelector('.build');
      });

      runs(() => {
        atom.commands.dispatch(workspaceElement, 'build:trigger');
      });

      waitsFor(() => {
        return workspaceElement.querySelector('.build .title') &&
          workspaceElement.querySelector('.build .title').classList.contains('success');
      });

      runs(() => {
        expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/customized/);
      });
    });

    it('should show a warning if current file is not part of an open Atom project', () => {
      waitsForPromise(() => atom.workspace.open(path.join('..', 'randomFile')));
      waitsForPromise(() => specHelpers.refreshAwaitTargets());
      runs(() => atom.commands.dispatch(workspaceElement, 'build:select-active-target'));
      waitsFor(() => atom.notifications.getNotifications().find(n => n.message === 'Unable to build.'));
      runs(() => {
        const not = atom.notifications.getNotifications().find(n => n.message === 'Unable to build.');
        expect(not.type).toBe('warning');
      });
    });
  });
});
<|endoftext|>


<commit_before>//keyboard experiment

export let keycodes = {
  48: "0", 49: "1", 50: "2", 51: "3", 52: "4", 53: "5", 54: "6", 55: "7", 56: "8", 57: "9",
  65: "a", 66: "b", 67: "c", 68: "d", 69: "e", 70: "f", 71: "g",
  72: "h", 73: "i", 74: "j", 75: "k", 76: "l", 77: "m", 78: "n",
  79: "o", 80: "p", 81: "q", 82: "r", 83: "s", 84: "t", 85: "u",
  86: "v", 87: "w", 88: "x", 89: "y", 90: "z"
}

/*
function setKeyBidings( element ){
  //based on http://qiita.com/jdeseno/items/72e12a5fa815b52f95e2
  // US keyboard

  let source = Rx.Observable.fromEvent(element, 'keydown')
  let subscription = source
     .map(function(e) {
        return keycodes[e.keyCode]
      })
     .filter(function(key) {
       return !!key
     })
     .subscribe(function(key) {
       console.log('keydown', key)
     });

}

let rxjsTrap = {

  bind(keyCombo){

  }
}*/

export function isValidElementEvent(event)
{
  let element = event.srcElement
  return !(element.tagName == 'INPUT' || element.tagName == 'SELECT' || element.tagName == 'TEXTAREA' || element.isContentEditable)
}<commit_msg>- fixed keyboard event target issues<commit_after>//keyboard experiment

export let keycodes = {
  48: "0", 49: "1", 50: "2", 51: "3", 52: "4", 53: "5", 54: "6", 55: "7", 56: "8", 57: "9",
  65: "a", 66: "b", 67: "c", 68: "d", 69: "e", 70: "f", 71: "g",
  72: "h", 73: "i", 74: "j", 75: "k", 76: "l", 77: "m", 78: "n",
  79: "o", 80: "p", 81: "q", 82: "r", 83: "s", 84: "t", 85: "u",
  86: "v", 87: "w", 88: "x", 89: "y", 90: "z"
}

/*
function setKeyBidings( element ){
  //based on http://qiita.com/jdeseno/items/72e12a5fa815b52f95e2
  // US keyboard

  let source = Rx.Observable.fromEvent(element, 'keydown')
  let subscription = source
     .map(function(e) {
        return keycodes[e.keyCode]
      })
     .filter(function(key) {
       return !!key
     })
     .subscribe(function(key) {
       console.log('keydown', key)
     });

}

let rxjsTrap = {

  bind(keyCombo){

  }
}*/

export function isValidElementEvent(event)
{
  let element = event.target || event.srcElement
  return !(element.tagName == 'INPUT' || element.tagName == 'SELECT' || element.tagName == 'TEXTAREA' || element.isContentEditable)
}<|endoftext|>