<commit_before>import React from 'react';
import ReactTestUtils from 'react/lib/ReactTestUtils';
import Carousel from '../src/Carousel';
import CarouselItem from '../src/CarouselItem';

describe('Carousel', function () {
  it('Should show the correct item', function () {

    let instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={1}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    assert.equal(instance.refs.item1.props.active, false);
    assert.equal(instance.refs.item2.props.active, true);

    instance = ReactTestUtils.renderIntoDocument(
      <Carousel defaultActiveIndex={1}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    assert.equal(instance.refs.item1.props.active, false);
    assert.equal(instance.refs.item2.props.active, true);
    assert.equal(
      ReactTestUtils.scryRenderedDOMComponentsWithTag(
        ReactTestUtils.findRenderedDOMComponentWithClass(instance, 'carousel-indicators'), 'li'
      ).length, 2
    );
  });

  it('Should handle null children', function () {
    let instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={1}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        {null}
        {false}
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    assert.equal(instance.refs.item1.props.active, false);
    assert.equal(instance.refs.item2.props.active, true);
    assert.equal(
      ReactTestUtils.scryRenderedDOMComponentsWithTag(
        ReactTestUtils.findRenderedDOMComponentWithClass(instance, 'carousel-indicators'), 'li'
      ).length, 2
    );
  });

  it('Should call onSelect when indicator selected', function (done) {
    function onSelect(index, direction) {
      assert.equal(index, 0);
      assert.equal(direction, 'prev');
      done();
    }

    let instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={1} onSelect={onSelect}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    ReactTestUtils.Simulate.click(
      ReactTestUtils.scryRenderedDOMComponentsWithTag(
        ReactTestUtils.findRenderedDOMComponentWithClass(instance, 'carousel-indicators'), 'li'
      )[0]
    );
  });

  it('Should show all controls on the first/last image if wrap is true', function () {
    var instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={0} controls={true} wrap={true}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    var backButton = ReactTestUtils.findRenderedDOMComponentWithClass(instance, 'left');

    assert.ok(backButton);
    assert.equal(backButton.props.href, '#prev');

    instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={1} controls={true} wrap={true}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    var nextButton = ReactTestUtils.findRenderedDOMComponentWithClass(instance, 'right');

    assert.ok(nextButton);
    assert.equal(nextButton.props.href, '#next');
  });

  it('Should not show the prev button on the first image if wrap is false', function () {
    var instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={0} controls={true} wrap={false}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    var backButtons = ReactTestUtils.scryRenderedDOMComponentsWithClass(instance, 'left');
    var nextButtons = ReactTestUtils.scryRenderedDOMComponentsWithClass(instance, 'right');

    assert.equal(backButtons.length, 0);
    assert.equal(nextButtons.length, 1);
  });
});
<commit_msg>Fix merge errors<commit_after>import React from 'react';
import ReactTestUtils from 'react/lib/ReactTestUtils';
import Carousel from '../src/Carousel';
import CarouselItem from '../src/CarouselItem';

describe('Carousel', function () {
  it('Should show the correct item', function () {

    let instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={1}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    assert.equal(instance.refs.item1.props.active, false);
    assert.equal(instance.refs.item2.props.active, true);

    instance = ReactTestUtils.renderIntoDocument(
      <Carousel defaultActiveIndex={1}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    assert.equal(instance.refs.item1.props.active, false);
    assert.equal(instance.refs.item2.props.active, true);
    assert.equal(
      ReactTestUtils.scryRenderedDOMComponentsWithTag(
        ReactTestUtils.findRenderedDOMComponentWithClass(instance, 'carousel-indicators'), 'li'
      ).length, 2
    );
  });

  it('Should handle null children', function () {
    let instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={1}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        {null}
        {false}
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    assert.equal(instance.refs.item1.props.active, false);
    assert.equal(instance.refs.item2.props.active, true);
    assert.equal(
      ReactTestUtils.scryRenderedDOMComponentsWithTag(
        ReactTestUtils.findRenderedDOMComponentWithClass(instance, 'carousel-indicators'), 'li'
      ).length, 2
    );
  });

  it('Should call onSelect when indicator selected', function (done) {
    function onSelect(index, direction) {
      assert.equal(index, 0);
      assert.equal(direction, 'prev');
      done();
    }

    let instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={1} onSelect={onSelect}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    ReactTestUtils.Simulate.click(
      ReactTestUtils.scryRenderedDOMComponentsWithTag(
        ReactTestUtils.findRenderedDOMComponentWithClass(instance, 'carousel-indicators'), 'li'
      )[0]
    );
  });

  it('Should show all controls on the first/last image if wrap is true', function () {
    let instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={0} controls={true} wrap={true}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    let backButton = ReactTestUtils.findRenderedDOMComponentWithClass(instance, 'left');

    assert.ok(backButton);
    assert.equal(backButton.props.href, '#prev');

    instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={1} controls={true} wrap={true}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    let nextButton = ReactTestUtils.findRenderedDOMComponentWithClass(instance, 'right');

    assert.ok(nextButton);
    assert.equal(nextButton.props.href, '#next');
  });

  it('Should not show the prev button on the first image if wrap is false', function () {
    let instance = ReactTestUtils.renderIntoDocument(
      <Carousel activeIndex={0} controls={true} wrap={false}>
        <CarouselItem ref="item1">Item 1 content</CarouselItem>
        <CarouselItem ref="item2">Item 2 content</CarouselItem>
      </Carousel>
    );

    let backButtons = ReactTestUtils.scryRenderedDOMComponentsWithClass(instance, 'left');
    let nextButtons = ReactTestUtils.scryRenderedDOMComponentsWithClass(instance, 'right');

    assert.equal(backButtons.length, 0);
    assert.equal(nextButtons.length, 1);
  });
});
<|endoftext|>


<commit_before>import history from './history'
import Cookies from 'js-cookie'

import { store } from './index'

const TOKEN_EXPIRY_PREEMPT = 2 * 60 * 1000 // Refresh token this many milliseconds before expiry time
const DEFAULT_REFRESH_INTERVAL = 60 * 1000 // Only used on first login, when we don't get given an expiry time (ms)
const ERROR_REFRESH_INTERVAL = 15 * 1000 // Used as fixed retry interval when we can't refresh token (ms)

let timeout = null
export let loggedIn = false

export const refreshToken = () => {
  let oldRefreshToken = Cookies.get('refreshToken')

  if (!oldRefreshToken) {
    history.push('/login')
    return false
  }

  if (!loggedIn) {
    return false
  }

  fetch('/graphql', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: `mutation RefreshToken($refreshToken: String!) {
  refreshToken(refreshToken: $refreshToken) {
    token
    refreshToken
    payload
  }
}`,
      variables: {
        refreshToken: oldRefreshToken,
      },
    }),
  })
    .then(response => {
      return response.json()
    })
    .then(response => {
      console.log(response.data)
      if (response.data && response.data.refreshToken) {
        // We got token and refreshToken
        Cookies.set('refreshToken', response.data.refreshToken.refreshToken, { expires: 365, sameSite: 'strict' })
        store.dispatch({type: 'USER_CHANGED', user: {username: response.data.refreshToken.payload.username}})

        // Schedule next token refresh
        let expiry = response.data.refreshToken.payload.exp
        let nextRefresh = expiry * 1000 - Date.now() - TOKEN_EXPIRY_PREEMPT
        scheduleTokenRefresh(nextRefresh)
      } else if (response.errors) {
        // Log all GraphQL errors
        response.errors.forEach(({ message, locations, path }) => {
          console.log(
            `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
          )
          // refreshToken expired or some other problem
          if (
            message.indexOf('Refresh token is expired') > -1 ||
            message.indexOf('Invalid refresh token') > -1
          ) {
            history.push('/login')
            return false
          }
        })
        // All other GraphQL errors, assume server problem and shedule a new refresh
        console.log('Received GraphQL error')
        scheduleTokenRefresh(ERROR_REFRESH_INTERVAL)
      } else {
        // All other conditions, assume server problem and shedule a new refresh
        console.log("Didn't receive fresh token")
        scheduleTokenRefresh(ERROR_REFRESH_INTERVAL)
      }
    })
    .catch(function(error) {
      // All other errors, assume network issue and shedule a new refresh
      console.log('Network error while refreshing token')
      scheduleTokenRefresh(ERROR_REFRESH_INTERVAL)
    })
}

export const scheduleTokenRefresh = timeout => {
  // timeout is ms until next refresh attempt
  // Note that old refresh token will be automatically revoked by Django signal (one time use)
  let nextRefresh = timeout ? timeout : DEFAULT_REFRESH_INTERVAL
  console.log('Next token refresh in ' + nextRefresh + 'ms')
  timeout = setTimeout(refreshToken, nextRefresh)
}

export const revokeRefreshToken = refreshToken => {
  // This only needs to be called on logout as old refresh tokens get automatically revoked by Django signal (one time use)
  console.log('revokeRefreshToken ' + refreshToken)

  fetch('/graphql', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: `mutation RevokeToken($refreshToken: String!) {
  revokeToken(refreshToken: $refreshToken) {
    revoked
  }
}`,
      variables: {
        refreshToken: refreshToken,
      },
    }),
  })
    .then(response => {
      return response.json()
    })
    .then(response => {
      console.log(response.data)
      if (response.data.revokeToken) {
        return true
      }
    })
}

export const logIn = refreshToken => {
  if (refreshToken) {
    Cookies.set('refreshToken', refreshToken, { expires: 365, sameSite: 'strict' })
  }
  loggedIn = true
}

export const logOut = () => {
  loggedIn = false
  let oldToken = Cookies.get('refreshToken')
  if (oldToken) {
    revokeRefreshToken(oldToken)
    Cookies.remove('refreshToken')
  }
  if (timeout) {
    clearTimeout(timeout)
  }
}
<commit_msg>Auth token timing adjustment<commit_after>import history from './history'
import Cookies from 'js-cookie'

import { store } from './index'

const TOKEN_EXPIRY_PREEMPT = 2 * 60 * 1000 // Refresh token this many milliseconds before expiry time
const DEFAULT_REFRESH_INTERVAL = 3 * 1000 // Only used on first login, when we don't get given an expiry time (ms)
const ERROR_REFRESH_INTERVAL = 15 * 1000 // Used as fixed retry interval when we can't refresh token (ms)

let timeout = null
export let loggedIn = false

export const refreshToken = () => {
  let oldRefreshToken = Cookies.get('refreshToken')

  if (!oldRefreshToken) {
    history.push('/login')
    return false
  }

  if (!loggedIn) {
    return false
  }

  fetch('/graphql', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: `mutation RefreshToken($refreshToken: String!) {
  refreshToken(refreshToken: $refreshToken) {
    token
    refreshToken
    payload
  }
}`,
      variables: {
        refreshToken: oldRefreshToken,
      },
    }),
  })
    .then(response => {
      return response.json()
    })
    .then(response => {
      console.log(response.data)
      if (response.data && response.data.refreshToken) {
        // We got token and refreshToken
        Cookies.set('refreshToken', response.data.refreshToken.refreshToken, { expires: 365, sameSite: 'strict' })
        store.dispatch({type: 'USER_CHANGED', user: {username: response.data.refreshToken.payload.username}})

        // Schedule next token refresh
        let expiry = response.data.refreshToken.payload.exp
        let nextRefresh = expiry * 1000 - Date.now() - TOKEN_EXPIRY_PREEMPT
        scheduleTokenRefresh(nextRefresh)
      } else if (response.errors) {
        // Log all GraphQL errors
        response.errors.forEach(({ message, locations, path }) => {
          console.log(
            `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
          )
          // refreshToken expired or some other problem
          if (
            message.indexOf('Refresh token is expired') > -1 ||
            message.indexOf('Invalid refresh token') > -1
          ) {
            history.push('/login')
            return false
          }
        })
        // All other GraphQL errors, assume server problem and shedule a new refresh
        console.log('Received GraphQL error')
        scheduleTokenRefresh(ERROR_REFRESH_INTERVAL)
      } else {
        // All other conditions, assume server problem and shedule a new refresh
        console.log("Didn't receive fresh token")
        scheduleTokenRefresh(ERROR_REFRESH_INTERVAL)
      }
    })
    .catch(function(error) {
      // All other errors, assume network issue and shedule a new refresh
      console.log('Network error while refreshing token')
      scheduleTokenRefresh(ERROR_REFRESH_INTERVAL)
    })
}

export const scheduleTokenRefresh = timeout => {
  // timeout is ms until next refresh attempt
  // Note that old refresh token will be automatically revoked by Django signal (one time use)
  let nextRefresh = timeout ? timeout : DEFAULT_REFRESH_INTERVAL
  console.log('Next token refresh in ' + nextRefresh + 'ms')
  timeout = setTimeout(refreshToken, nextRefresh)
}

export const revokeRefreshToken = refreshToken => {
  // This only needs to be called on logout as old refresh tokens get automatically revoked by Django signal (one time use)
  console.log('revokeRefreshToken ' + refreshToken)

  fetch('/graphql', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: `mutation RevokeToken($refreshToken: String!) {
  revokeToken(refreshToken: $refreshToken) {
    revoked
  }
}`,
      variables: {
        refreshToken: refreshToken,
      },
    }),
  })
    .then(response => {
      return response.json()
    })
    .then(response => {
      console.log(response.data)
      if (response.data.revokeToken) {
        return true
      }
    })
}

export const logIn = refreshToken => {
  if (refreshToken) {
    Cookies.set('refreshToken', refreshToken, { expires: 365, sameSite: 'strict' })
  }
  loggedIn = true
}

export const logOut = () => {
  loggedIn = false
  let oldToken = Cookies.get('refreshToken')
  if (oldToken) {
    revokeRefreshToken(oldToken)
    Cookies.remove('refreshToken')
  }
  if (timeout) {
    clearTimeout(timeout)
  }
}
<|endoftext|>


<commit_before>/*
 * Thicket
 * https://github.com/d-plaindoux/thicket
 *
 * Copyright (c) 2015-2016 Didier Plaindoux
 * Licensed under the LGPL2 license.
 */

module.exports = (function () {

    'use strict';

    var error = require('../exception.js'),
        list = require('../../../Data/list.js'),
        aTry = require('../../../Data/atry.js'),
        symbols = require('../symbols.js'),
        types = require('../checker/types.js'),
        stringify = require('../syntax/stringify.js');

    function Expression() {
        // Nothing for the moment
    }

    Expression.prototype.unify = function(expression, aType1, aType2, environment) {
        return types.unify(aType1, aType2, environment).map(function(result) {
            return aTry.success(result);
        }).lazyRecoverWith(function(anError) {
            return aTry.failure(error(expression,
                                      anError.message,
                                      anError.name === "Abort"));
        });
    };

    Expression.prototype.retrieveBehaviorType = function (environment, entity, name) {
        var that = this;

        return types.unfold(list(), environment, entity).flatmap(function (definition) {
            var entity = types.instantiate(definition);

            switch (entity.$t) {
                case symbols.TypeSpecialize:
                    return types.reduce(entity).flatmap(function(entity) {
                        return that.retrieveBehaviorType(environment, entity, name);
                    });

                case symbols.Typedef:
                    return types.unfold(list(), environment, entity.type).flatmap(function (unfoldType) {
                        return that.retrieveBehaviorType(environment, unfoldType, name);
                    });

                case symbols.EntitySpecialization:
                    return that.retrieveBehaviorType(environment, entity.type, name).map(function (aType) {
                        var variables = entity.type.variables.map(function(variable) { return variable.name; });
                        return types.substitute(list(variables).zipWith(list(entity.parameters)), aType);
                    });

                case symbols.Model:
                    return list(entity.params).findFirst(function (param) {
                        return param.name === name;
                    }).map(function (param) {
                        return types.unfold(list(), environment, param.type);
                    }).orLazyElse(function() {
                        return aTry.failure(error(entity,
                                                  "definition '" + name + "' not found in " +
                                                  stringify(types.reduce(entity,true).recoverWith(entity)),
                                                  true));
                    });

                case symbols.Trait:
                case symbols.Controller:
                    return list(entity.specifications).append(list(entity.behaviors)).findFirst(function (behavior) {
                        return behavior.name === name && behavior.type;
                    }).map(function (behavior) {
                        return types.unfold(list(), environment, behavior.type);
                    }).orLazyElse(function() {
                        var result = aTry.failure(error(entity,
                                                        "definition '" + name + "' not found in " +
                                                        stringify(types.reduce(entity,true).recoverWith(entity)),
                                                        true));

                        return list(entity.derivations).foldL(result, function(result, derivation) {
                            if (result.isSuccess()) {
                                return result;
                            }

                            var newResult = that.retrieveBehaviorType(environment, derivation, name);
                            if (newResult.isSuccess()) {
                                return newResult;
                            } else {
                                return result;
                            }
                        });
                    });

                case symbols.TypeVariable:
                    return aTry.failure(error(entity,
                                              "definition " + name + " not found in " +
                                              stringify(types.reduce(entity,true).recoverWith(entity))));

                default:
                    return aTry.failure(error(entity,
                                              "definition " + name + " not found in " +
                                              stringify(types.reduce(entity,true).recoverWith(entity)),
                                              true));
            }
        });
    };

    Expression.prototype.retrieveModelType = function (environment, entity, name) {
        var that = this;

        return types.unfold(list(), environment, entity).flatmap(function (definition) {
            var entity = types.instantiate(definition);

            switch (entity.$t) {
                case symbols.TypeSpecialize:
                    return types.reduce(entity).flatmap(function(entity) {
                        return that.retrieveModelType(environment, entity, name);
                    });

                case symbols.EntitySpecialization:
                    return that.retrieveModelType(environment, entity.type, name).map(function (type) {
                        var variables = entity.type.variables.map(function(variable) { return variable.name; });
                        return types.substitute(list(variables).zipWith(list(entity.parameters)), type);
                    });

                case symbols.Model:
                    return list(entity.params).findFirst(function (param) {
                        return param.name === name;
                    }).map(function (param) {
                        return types.unfold(list(), environment, param.type).map(function (unfoldType) {
                            return types.instantiate(unfoldType);
                        });
                    }).orLazyElse(function() {
                        return aTry.failure(error(entity,
                                                  "attribute '" + name + "' not found in " +
                                                  stringify(types.reduce(entity,true).recoverWith(entity)),
                                                  true));
                    });

                case symbols.Trait:
                case symbols.Controller:
                    return aTry.failure(error(entity,
                                              stringify(types.reduce(entity,true).recoverWith(entity)) +
                                              " is not a model. Attribute " + name + " not found",
                                              true));

                case symbols.Typedef:
                    return types.unfold(list(), environment, entity.type).flatmap(function (unfoldType) {
                        return that.retrieveModelType(environment, unfoldType, name);
                    });

                case symbols.TypeVariable:
                    return aTry.failure(error(entity,
                                              "attribute " + name + " not found in " +
                                              stringify(types.reduce(entity,true).recoverWith(entity))));

                default:
                    return aTry.failure(error(entity,
                                              "attribute " + name + " not found for " +
                                              stringify(types.reduce(entity,true).recoverWith(entity)),
                                              true));
            }
        });
    };

    return new Expression();
}());
    <commit_msg>Remove unused method<commit_after>/*
 * Thicket
 * https://github.com/d-plaindoux/thicket
 *
 * Copyright (c) 2015-2016 Didier Plaindoux
 * Licensed under the LGPL2 license.
 */

module.exports = (function () {

    'use strict';

    var error = require('../exception.js'),
        list = require('../../../Data/list.js'),
        aTry = require('../../../Data/atry.js'),
        symbols = require('../symbols.js'),
        types = require('../checker/types.js'),
        stringify = require('../syntax/stringify.js');

    function Expression() {
        // Nothing for the moment
    }

    Expression.prototype.unify = function(expression, aType1, aType2, environment) {
        return types.unify(aType1, aType2, environment).map(function(result) {
            return aTry.success(result);
        }).lazyRecoverWith(function(anError) {
            return aTry.failure(error(expression,
                                      anError.message,
                                      anError.name === "Abort"));
        });
    };

    Expression.prototype.retrieveBehaviorType = function (environment, entity, name) {
        var that = this;

        return types.unfold(list(), environment, entity).flatmap(function (definition) {
            var entity = types.instantiate(definition);

            switch (entity.$t) {
                case symbols.TypeSpecialize:
                    return types.reduce(entity).flatmap(function(entity) {
                        return that.retrieveBehaviorType(environment, entity, name);
                    });

                case symbols.Typedef:
                    return types.unfold(list(), environment, entity.type).flatmap(function (unfoldType) {
                        return that.retrieveBehaviorType(environment, unfoldType, name);
                    });

                case symbols.EntitySpecialization:
                    return that.retrieveBehaviorType(environment, entity.type, name).map(function (aType) {
                        var variables = entity.type.variables.map(function(variable) { return variable.name; });
                        return types.substitute(list(variables).zipWith(list(entity.parameters)), aType);
                    });

                case symbols.Model:
                    return list(entity.params).findFirst(function (param) {
                        return param.name === name;
                    }).map(function (param) {
                        return types.unfold(list(), environment, param.type);
                    }).orLazyElse(function() {
                        return aTry.failure(error(entity,
                                                  "definition '" + name + "' not found in " +
                                                  stringify(types.reduce(entity,true).recoverWith(entity)),
                                                  true));
                    });

                case symbols.Trait:
                case symbols.Controller:
                    return list(entity.specifications).append(list(entity.behaviors)).findFirst(function (behavior) {
                        return behavior.name === name && behavior.type;
                    }).map(function (behavior) {
                        return types.unfold(list(), environment, behavior.type);
                    }).orLazyElse(function() {
                        var result = aTry.failure(error(entity,
                                                        "definition '" + name + "' not found in " +
                                                        stringify(types.reduce(entity,true).recoverWith(entity)),
                                                        true));

                        return list(entity.derivations).foldL(result, function(result, derivation) {
                            if (result.isSuccess()) {
                                return result;
                            }

                            var newResult = that.retrieveBehaviorType(environment, derivation, name);
                            if (newResult.isSuccess()) {
                                return newResult;
                            } else {
                                return result;
                            }
                        });
                    });

                case symbols.TypeVariable:
                    return aTry.failure(error(entity,
                                              "definition " + name + " not found in " +
                                              stringify(types.reduce(entity,true).recoverWith(entity)),
                                              true));

                default:
                    return aTry.failure(error(entity,
                                              "definition " + name + " not found in " +
                                              stringify(types.reduce(entity,true).recoverWith(entity)),
                                              true));
            }
        });
    };

    return new Expression();
}());
    <|endoftext|>


<commit_before>exports.startserver = function() {
    var restify = require('restify');
    var server = restify.createServer();
    var test = require('./routes.js');
    test.getRoutes(server);
    server.use(restify.bodyParser());
    server.use(restify.queryParser());
    server.use(restify.authorizationParser());
    console.log('server ' + server)
    server.listen('8080', 'localhost', function() {
        console.log('%s server listen at %s', server.name, server.url);
    });
}<commit_msg>changed settings of test server to match actual server<commit_after>exports.startserver = function() {
    var restify = require('restify');
    var server = restify.createServer();
    server.use(restify.CORS({
    origins: ['*'], // defaults to ['*']
    credentials: true, // defaults to false
    headers: ['authorization', 'content-type', 'accept', 'origin'],
    methods: ['GET', 'PUT', 'POST', 'HEAD', 'DELETE'] // sets expose-headers
}));
     server.use(restify.bodyParser());
    server.use(restify.queryParser());
    server.use(restify.authorizationParser());
    var test = require('./routes.js');
    test.getRoutes(server);
    console.log('server ' + server)
    server.listen('8080', 'localhost', function() {
        console.log('%s server listen at %s', server.name, server.url);
    });
}<|endoftext|>


<commit_before><commit_msg>Re-added braintree support<commit_after><|endoftext|>


<commit_before>/**
 * @Author: Geoffrey Bauduin <bauduin.geo@gmail.com>
 */

angular.module("ion.rangeslider", []);

angular.module("ion.rangeslider").directive("ionRangeSlider", [
    function () {

        return {
            restrict: "E",
            scope: {
                min: "=",
                max: "=",
                type: "@",
                prefix: "@",
                maxPostfix: "@",
                prettify: "@",
                grid: "@",
                gridMargin: "@",
                postfix: "@",
                step: "@",
                hideMinMax: "@",
                hideFromTo: "@",
                from: "=",
                to: "=",
                disable: "=",
                onChange: "&",
                onFinish: "&"
            },
            replace: true,
            link: function ($scope, $element) {
                $element.ionRangeSlider({
                    min: $scope.min,
                    max: $scope.max,
                    type: $scope.type,
                    prefix: $scope.prefix,
                    maxPostfix: $scope.maxPostfix,
                    prettify: $scope.prettify,
                    grid: $scope.grid,
                    gridMargin: $scope.gridMargin,
                    postfix: $scope.postfix,
                    step: $scope.step,
                    hideMinMax: $scope.hideMinMax,
                    hideFromTo: $scope.hideFromTo,
                    from: $scope.from,
                    to: $scope.to,
                    disable: $scope.disable,
                    onChange: function (a) {
                        $scope.$apply(function () {
                            $scope.from = a.from;
                            $scope.to = a.to;
                            $scope.onChange && $scope.onChange({
                                a: a
                            });
                        });
                    },
                    onFinish: function () {
                        $scope.$apply($scope.onFinish);
                    }
                });
                var watchers = [];
                watchers.push($scope.$watch("min", function (value) {
                    $element.data("ionRangeSlider").update({
                        min: value
                    });
                }));
                watchers.push($scope.$watch('max', function (value) {
                    $element.data("ionRangeSlider").update({
                        max: value
                    });
                }));
                watchers.push($scope.$watch('from', function (value) {
                    var slider = $element.data("ionRangeSlider");
                    if (slider.old_from !== value) {
                        slider.update({
                            from: value
                        });
                    }
                }));
                watchers.push($scope.$watch('to', function (value) {
                    var slider = $element.data("ionRangeSlider");
                    if (slider.old_to !== value) {
                        slider.update({
                            to: value
                        });
                    }
                }));
                watchers.push($scope.$watch('disable', function (value) {
                    $element.data("ionRangeSlider").update({
                        disable: value
                    });
                }));
            }
        }

    }
])
<commit_msg>Fix missing and non-working parameters (#8)<commit_after>/**
 * @Author: Geoffrey Bauduin <bauduin.geo@gmail.com>
 */

angular.module("ion.rangeslider", []);

angular.module("ion.rangeslider").directive("ionRangeSlider", [
    function () {

        return {
            restrict: "E",
            scope: {
                min: "=",
                max: "=",
                from: "=",
                to: "=",
                disable: "=",

                type: "@",
                step: "@",
                minInterval: "@",
                maxInterval: "@",
                dragInterval: "@",
                values: "@",
                fromFixed: "@",
                fromMin: "@",
                fromMax: "@",
                fromShadow: "@",
                toFixed: "@",
                toMax: "@",
                toShadow: "@",
                prettifyEnabled: "@",
                prettifySeparator: "@",
                forceEdges: "@",
                keyboard: "@",
                keyboardStep: "@",
                grid: "@",
                gridMargin: "@",
                gridNum: "@",
                gridSnap: "@",
                hideMinMax: "@",
                hideFromTo: "@",
                prefix: "@",
                postfix: "@",
                maxPostfix: "@",
                decorateBoth: "@",
                valuesSeparator: "@",
                inputValuesSeparator: "@",

                prettify: "&",
                onChange: "&",
                onFinish: "&",
            },
            replace: true,
            link: function ($scope, $element, attrs) {
                $element.ionRangeSlider({
                    min: $scope.min,
                    max: $scope.max,
                    from: $scope.from,
                    to: $scope.to,
                    disable: $scope.disable,
                    type: $scope.type,
                    step: $scope.step,
                    minInterval: $scope.min_interval,
                    maxInterval: $scope.max_interval,
                    dragInterval: $scope.drag_interval,
                    values: $scope.values,
                    fromFixed: $scope.from_fixed,
                    fromMin: $scope.from_min,
                    fromMax: $scope.from_max,
                    fromShadow: $scope.from_shadow,
                    toFixed: $scope.to_fixed,
                    toMax: $scope.to_max,
                    toShadow: $scope.to_shadow,
                    prettifyEnabled: $scope.prettify_enabled,
                    prettifySeparator: $scope.prettify_separator,
                    forceEdges: $scope.force_edges,
                    keyboard: $scope.keyboard,
                    keyboardStep: $scope.keyboard_step,
                    grid: $scope.grid,
                    gridMargin: $scope.grid_margin,
                    gridNum: $scope.grid_num,
                    gridSnap: $scope.grid_snap,
                    hideMinMax: $scope.hide_min_max,
                    hideFromTo: $scope.hide_from_to,
                    prefix: $scope.prefix,
                    postfix: $scope.postfix,
                    maxPostfix: $scope.max_postfix,
                    decorateBoth: $scope.decorate_both,
                    valuesSeparator: $scope.values_separator,
                    inputValuesSeparator: $scope.input_values_separator,

                    prettify: function (value) {
                      if(!attrs.prettify) {
                        return value;
                      }
                      return $scope.prettify({value: value});
                    },
                    onChange: function (a) {
                        $scope.$apply(function () {
                            $scope.from = a.from;
                            $scope.to = a.to;
                            $scope.onChange && $scope.onChange({
                                a: a
                            });
                        });
                    },
                    onFinish: function () {
                        $scope.$apply($scope.onFinish);
                    },
                });
                var watchers = [];
                watchers.push($scope.$watch("min", function (value) {
                    $element.data("ionRangeSlider").update({
                        min: value
                    });
                }));
                watchers.push($scope.$watch('max', function (value) {
                    $element.data("ionRangeSlider").update({
                        max: value
                    });
                }));
                watchers.push($scope.$watch('from', function (value) {
                    var slider = $element.data("ionRangeSlider");
                    if (slider.old_from !== value) {
                        slider.update({
                            from: value
                        });
                    }
                }));
                watchers.push($scope.$watch('to', function (value) {
                    var slider = $element.data("ionRangeSlider");
                    if (slider.old_to !== value) {
                        slider.update({
                            to: value
                        });
                    }
                }));
                watchers.push($scope.$watch('disable', function (value) {
                    $element.data("ionRangeSlider").update({
                        disable: value
                    });
                }));
            }
        }

    }
])
<|endoftext|>


<commit_before>
var primitives = require('./primitives');
var Symbol = primitives.Symbol, HashSymbol = primitives.HashSymbol;

var Reader = require('./reader').Reader;
var Stream = require('./stream').Stream;

//// utils

Object.prototype.toArray = function () {
    return Array.prototype.slice.call(this);
};

function S (name) {
    return new Symbol(name);
}

//// expansion

function argumentNames (args) {
    return args.map(function (arg) {
	return (arg instanceof Array ? arg[0] : arg);
    });
}

function requiredArguments (args) {
    function position (hashSymbol) {
	var result = args.indexOf(hashSymbol);
	if (result == -1) {
	    result = args.length;
	}
	return result;
    }
    var hashSymbolPositions =
	[HashSymbol.key, HashSymbol.rest, HashSymbol.values].map(position);
    var end = Math.min.apply(null, [args.length].concat(hashSymbolPositions));
    return args.slice(0, end);

}

function addReturn (forms) {
    var last = forms.length - 1;
    if (forms[last] instanceof Array
	&& !(forms[last][0] instanceof Symbol
	     && forms[last][0].name == 'js:return'))
    {
	forms[last] = [S('js:return'), forms[last]];
    }
    return forms;
}

function functionDeclaration (name, args, body) {
    var documentation = [];
    if (typeof body[0] == 'string' && body.length > 1) {
	documentation.push([S('js:documentation'), body.shift()]);
    }
    var rest = [[S('js:get-property'),
		 "Array", "prototype", "slice", "call"],
		[S('js:identifier'), "arguments"],
		requiredArguments(args).length];
    var restAndKey = [];
    var restPosition = args.indexOf(HashSymbol.rest);
    if (restPosition >= 0) {
	restAndKey.push([S('js:var'), args[restPosition + 1], rest]);
    }
    var keyPosition = args.indexOf(HashSymbol.key);
    if (keyPosition >= 0) {
	// check order of #rest and #key
	if (restPosition >= 0 && keyPosition < restPosition)
	    throw new Error("function '" + name + "': #key before #rest in args: " +
			    JSON.stringify(args));

	var keyVar = Symbol.generate();
	var valueVar = Symbol.generate();
	var restVar = Symbol.generate();
	var indexVar = Symbol.generate();

	// declarations with defaults, setters
	var setter = [S('select'), keyVar, S('==')];
	args.slice(keyPosition + 1).forEach(function (key) {
	    var name, _default = S('#f');
	    if (key instanceof Array) {
		name = key[0];
		_default = key[1];
	    } else if (key instanceof Symbol) {
		name = key;
	    }
	    if (name) {
		restAndKey.push([S('js:var'), name, _default]);
		setter.push([[name.toString()], // TODO: check for keyword
			     [S('js:set'), name, valueVar]]);
	    }
	});
	if (restPosition == -1)
	    restAndKey.push([S('js:var'), restVar, rest]);
	else
	    restVar = args[restPosition + 1];

	restAndKey.push([S('js:for'), [[indexVar, 0],
				       [S('js:<'), indexVar, [S('js:get-property'), restVar, 'length']],
				       [S('js:set'), indexVar, [S('js:+'), indexVar, 2]]],
			 [S('js:var'), keyVar, [S('js:get-property'), restVar, indexVar]],
			 [S('js:var'), valueVar, [S('js:get-property'), restVar, [S('js:+'), indexVar, 1]]],
			 [S('when'), [S('instance?'), keyVar, S('<keyword>')], setter]]);
    }
    // TODO: documentation, keyword arguments, use reduce
    return [S('js:function'), name,
	    argumentNames(requiredArguments(args)),
	    [S('begin')].concat(restAndKey).concat(body)];
}

var macros = {
    // TODO: should be property of current module,
    //       and accessible as function
    'define-function': function (name, args) {
	var body = arguments.toArray().slice(2);
	if (!(name instanceof Symbol))
	    throw new Error('function\'s name should be a symbol: '
			    + JSON.stringify(name));
	return functionDeclaration(name, args, body);
    },
    'method': function (args) {
	var body = arguments.toArray().slice(1);
	return functionDeclaration(null, args, body);
    },
    // TODO: bind multiple values
    // e.g. (bind ((foo bar baz (values 1 2 3)))
    // arguments.callee.acceptsMultipleValues = true;
    // (...) ? arguments.callee.MultipleValues :
    //         new Array([foo, bar, baz].length)
    // TODO: test multiple value bind with nested functions
    'bind': function (bindings) {
	var body = arguments.toArray().slice(1);
	var declarations = bindings.map(function (binding) {
	    return ([S('js:var')].concat(binding));
	});
	return [[S('method'), []]
		.concat(declarations)
		.concat(body)];
    },
    'when': function (test) {
	var body = arguments.toArray().slice(1);
	body.unshift(S('begin'));
	return [S('if'), test, body, S('#f')];
    },
    'cond': function () {
	var cases = arguments.toArray();
	if (cases.length == 0)
	    return S('#f');
	else {
	    var _case = cases[0];
	    var then = _case.slice(1);
	    then.unshift(S('begin'));
	    if (_case[0] instanceof Symbol && _case[0].name == 'else:')
		return then;
	    else
		return [S('if'), _case[0], then,
			[S('cond')].concat(cases.slice(1))];
	}
    },
    'select': function (value, test) {
	function testExpression (testValue) {
	    return [test, testValue, value];
	}
	var cases = arguments.toArray().slice(2).map(function (_case) {
	    if (_case[0] instanceof Symbol && _case[0].name == 'else:')
		return _case;
	    else
		return ([[S('or')].concat(_case[0].map(testExpression))]
			.concat(_case.slice(1)));
	});
	return [S('cond')].concat(cases);
    },
    'bind-methods': function (bindings) {
	var body = arguments.toArray().slice(1);
	var methodBindings = bindings.map(function (binding) {
	    return [binding[0], [S('method')].concat(binding.slice(1))];
	});
	return [S('bind'), methodBindings].concat(body);
    },
    'handler-case': function (body) {
	var conditions = arguments.toArray().slice(1);
	var conditionVariable = Symbol.generate();
	var cases = conditions.map(function (condition) {
	    // TODO: bind condition: argument
	    var _if = condition[0];
	    return [[S('instance?'),
		     conditionVariable, _if[0]]]
		.concat(condition.slice(1));
	});
	return [[S('method'), [],
		 [S('js:try'), body, conditionVariable,
		  [S('cond')].concat(cases)]]];
    },
    // TODO: define-method
    'define-method': function () {
	return [S('js:statements'),
		[S('define-function')].concat(arguments.toArray())];
    }
}

var symbolMacros = {}

function macroexpand (form) {
    if (form instanceof Array) {
	while (form[0] instanceof Symbol && macros.hasOwnProperty(form[0].name))
	    form = macros[form[0].name].apply(this, form.slice(1));
	if (form instanceof Array)
	    return form.map(macroexpand);
	else
	    return macroexpand(form);
    } else if (form instanceof Symbol
	       && symbolMacros.hasOwnProperty(form.name)) {
	return macroexpand(symbolMacros[form.name]());
    } else
	return form;
}

//// writing

var infix = {
    'and': '&&', 'or': '||', 'js:+': '+', 'js:-': '-',
    'js:>': '>', 'js:<': '<', 'js:>=': '>=', 'js:<=': '<=',
    'js:==': '==', 'js:===': '==='
}

var symbolValues = {
    'js:null': 'null',
    '#f': 'false',
    '#t': 'true'
}

var specialForms = {
    'js:negative': function (allowStatements, object) {
	return '(- ' + write(object) + ')';
    },
    'js:not': function (allowStatements, expression) {
	return '!' + write(expression);
    },
    'begin': function (allowStatements) {
	var forms = arguments.toArray().slice(1);
	if (allowStatements) {
	    var separator = ';\n';
	    var result = forms.map(writeExpressions).join(separator);
	    if (forms.length > 1)
		result += '\n';
	    return result;
	} else if (forms.length > 1)
	    return '(' + forms.map(writeExpressions).join(', ') + ')';
	else
	    return writeExpressions(forms[0]);
    },
    'if': function (allowStatements, test, then, _else) {
	if (allowStatements) {
	    var result = 'if (' + write(test) + ') {\n'
		+ writeStatements(then) + '}';
	    if (_else instanceof Array)
		result += (' else {\n' + writeStatements(_else) + '\n}');
	    return result;
	} else {
	    return '(' + write(test) + ' ? '
		+ write(then) + ' : '
		+ write(_else) + ')';
	}
    },
    'list': function (allowStatements) {
	var elements = arguments.toArray().slice(1);
	return '[' + elements.map(writeExpressions).join(', ') + ']';
    },
    'js:defined': function (allowStatements, expression) {
	return '(typeof (' + write(expression) + ') != "undefined")';
    },
    'js:try': function (allowStatements, body, conditionVariable, _catch) {
	// TODO: if !allowStatements: wrap with function
	return 'try {\n'
	    + writeStatements(body) // TODO: return?
	    + '} catch (' + write(conditionVariable) + ') {\n'
	    + writeStatements(_catch)
	    + '\n}';
    },
    'js:for-in': function (allowStatements, variableAndExpression) {
	// TODO: if !allowStatements: wrap with function
	var body = arguments.toArray().slice(2);
	var variable = variableAndExpression[0];
	var expression = variableAndExpression[1];
	return 'for (var ' + variable + ' in ' + write(expression) + ') {\n'
	    + writeStatements([S('begin')].concat(body)) + '\n}';
    },
    'js:for': function (allowStatements, initTestNext) {
	// TODO: if !allowStatements: wrap with function
	var body = arguments.toArray().slice(2);
	var init = initTestNext[0];
	var test = initTestNext[1];
	var next = initTestNext[2];
	return 'for (var ' + init[0] + ' = ' + init[1] + '; '
	    + write(test) + '; ' + write(next) + ') {\n'
	    + writeStatements([S('begin')].concat(body)) + '\n}';
    },
    'js:identifier': function (allowStatements, name) {
	return ('' + name);
    },
    'js:get-property': function (allowStatements) {
	var elements = arguments.toArray().slice(1);
	var object = elements[0];
	if (typeof object != 'string')
	    object = write(object);
	return object
	    + (elements.slice(1)
	       .map(function (element) {
		   if (typeof element == 'string' &&
		       /^[a-zA-Z_]+$/.exec(element))
		   {
		       return '.' + element;
		   } else
		       return '[' + write(element) + ']';
	       }).join(''));
    },
    'js:call': function (allowStatements, name) {
	var args = arguments.toArray().slice(2);
	return name + '(' + args.map(writeExpressions).join(', ') + ')';
    },
    'js:new': function (allowStatements, name) {
	var args = arguments.toArray().slice(2);
	return 'new ' + name + '(' + args.map(writeExpressions).join(', ') + ')';
    },
    'js:var': function (allowStatements, name, value) {
	return "var " + name + " = " + write(value);
    },
    'js:set': function (allowStatements, name, value) {
	return write(name) + " = " + write(value);
    },
    'js:return': function (allowStatements, body) {
	return 'return ' + write(body);
    },
    'js:function': function (allowStatements, name, args, body) {
	return 'function ' + (name ? name + ' ' : '')
	    + '(' + args.join(', ') + ') '
	    + '{\n' + writeStatements(addReturn(body)) + '}';
    },
    'js:documentation': function (allowStatements, documentation) {
	return '/** \n'
	    + documentation.split('\n').map(function (line) {
		return ' * ' + line;
	    }).join('\n')
	    + '\n */\n';
    },
    'js:statements': function (allowStatements) {
	var body = arguments.toArray().slice(1);
	return body.map(writeStatements).join('');
    }
}

// helper
function writeStatements (form) {
    return write(form, true);
}

function writeExpressions (form) {
    return write(form, false);
}

function write (form, allowStatements) {
    if (form instanceof Array) {
	var head = form[0];
	var rest = form.slice(1);
	if (head instanceof Symbol && infix.hasOwnProperty(head.name)) {
	    return '(' + rest.map(writeExpressions).join(' ' + infix[head.name] + ' ') + ')';
	} else if (head instanceof Symbol && specialForms.hasOwnProperty(head.name)) {
	    return specialForms[head.name].apply(this, [allowStatements].concat(rest));
	} else if (head instanceof Array && head[0] && head[0].name == 'js:function') {
	    return '(' + write(head) + ')(' + rest.map(writeExpressions).join(', ') + ')';
	} else {
	    return write(head) + '(' + rest.map(writeExpressions).join(', ') + ')';
	}
    } else if (typeof form == "string") {
	return '"' + form + '"';
    } else if (form instanceof Symbol && symbolValues.hasOwnProperty(form.name)) {
	return symbolValues[form.name];
    } else
	return form;
}

function compile (form, allowStatements) {
    return write(macroexpand(form), allowStatements);
}

//// interface

exports.compile = function (code) {
    var stream = new Stream("(begin\n" + code + "\n)");
    var reader = new Reader(stream);
    var form = reader.read();
    return compile(form, true);
}<commit_msg>implement 'values'<commit_after>
var primitives = require('./primitives');
var Symbol = primitives.Symbol, HashSymbol = primitives.HashSymbol;

var Reader = require('./reader').Reader;
var Stream = require('./stream').Stream;

//// utils

Object.prototype.toArray = function () {
    return Array.prototype.slice.call(this);
};

function S (name) {
    return new Symbol(name);
}

//// expansion

function argumentNames (args) {
    return args.map(function (arg) {
	return (arg instanceof Array ? arg[0] : arg);
    });
}

function requiredArguments (args) {
    function position (hashSymbol) {
	var result = args.indexOf(hashSymbol);
	if (result == -1) {
	    result = args.length;
	}
	return result;
    }
    var hashSymbolPositions =
	[HashSymbol.key, HashSymbol.rest, HashSymbol.values].map(position);
    var end = Math.min.apply(null, [args.length].concat(hashSymbolPositions));
    return args.slice(0, end);

}

function addReturn (forms) {
    var last = forms.length - 1;
    if (forms[last] instanceof Array
	&& !(forms[last][0] instanceof Symbol
	     && forms[last][0].name == 'js:return'))
    {
	forms[last] = [S('js:return'), forms[last]];
    }
    return forms;
}

function functionDeclaration (name, args, body) {
    var documentation = [];
    if (typeof body[0] == 'string' && body.length > 1) {
	documentation.push([S('js:documentation'), body.shift()]);
    }
    var rest = [[S('js:get-property'),
		 "Array", "prototype", "slice", "call"],
		[S('js:identifier'), "arguments"],
		requiredArguments(args).length];
    var restAndKey = [];
    var restPosition = args.indexOf(HashSymbol.rest);
    if (restPosition >= 0) {
	restAndKey.push([S('js:var'), args[restPosition + 1], rest]);
    }
    var keyPosition = args.indexOf(HashSymbol.key);
    if (keyPosition >= 0) {
	// check order of #rest and #key
	if (restPosition >= 0 && keyPosition < restPosition)
	    throw new Error("function '" + name + "': #key before #rest in args: " +
			    JSON.stringify(args));

	var keyVar = Symbol.generate();
	var valueVar = Symbol.generate();
	var restVar = Symbol.generate();
	var indexVar = Symbol.generate();

	// declarations with defaults, setters
	var setter = [S('select'), keyVar, S('==')];
	args.slice(keyPosition + 1).forEach(function (key) {
	    var name, _default = S('#f');
	    if (key instanceof Array) {
		name = key[0];
		_default = key[1];
	    } else if (key instanceof Symbol) {
		name = key;
	    }
	    if (name) {
		restAndKey.push([S('js:var'), name, _default]);
		setter.push([[name.toString()], // TODO: check for keyword
			     [S('js:set'), name, valueVar]]);
	    }
	});
	if (restPosition == -1)
	    restAndKey.push([S('js:var'), restVar, rest]);
	else
	    restVar = args[restPosition + 1];

	restAndKey.push([S('js:for'), [[indexVar, 0],
				       [S('js:<'), indexVar, [S('js:get-property'), restVar, 'length']],
				       [S('js:set'), indexVar, [S('js:+'), indexVar, 2]]],
			 [S('js:var'), keyVar, [S('js:get-property'), restVar, indexVar]],
			 [S('js:var'), valueVar, [S('js:get-property'), restVar, [S('js:+'), indexVar, 1]]],
			 [S('when'), [S('instance?'), keyVar, S('<keyword>')], setter]]);
    }
    // TODO: documentation, keyword arguments, use reduce
    return [S('js:function'), name,
	    argumentNames(requiredArguments(args)),
	    [S('begin')].concat(restAndKey).concat(body)];
}

var macros = {
    // TODO: should be property of current module,
    //       and accessible as function
    'define-function': function (name, args) {
	var body = arguments.toArray().slice(2);
	if (!(name instanceof Symbol))
	    throw new Error('function\'s name should be a symbol: '
			    + JSON.stringify(name));
	return functionDeclaration(name, args, body);
    },
    'method': function (args) {
	var body = arguments.toArray().slice(1);
	return functionDeclaration(null, args, body);
    },
    // TODO: bind multiple values
    // e.g. (bind ((foo bar baz (values 1 2 3)))
    // arguments.callee.acceptsMultipleValues = true;
    // (...) ? arguments.callee.MultipleValues :
    //         new Array([foo, bar, baz].length)
    // TODO: test multiple value bind with nested functions
    'bind': function (bindings) {
	var body = arguments.toArray().slice(1);
	var declarations = bindings.map(function (binding) {
	    return ([S('js:var')].concat(binding));
	});
	return [[S('method'), []]
		.concat(declarations)
		.concat(body)];
    },
    'when': function (test) {
	var body = arguments.toArray().slice(1);
	body.unshift(S('begin'));
	return [S('if'), test, body, S('#f')];
    },
    'cond': function () {
	var cases = arguments.toArray();
	if (cases.length == 0)
	    return S('#f');
	else {
	    var _case = cases[0];
	    var then = _case.slice(1);
	    then.unshift(S('begin'));
	    if (_case[0] instanceof Symbol && _case[0].name == 'else:')
		return then;
	    else
		return [S('if'), _case[0], then,
			[S('cond')].concat(cases.slice(1))];
	}
    },
    'select': function (value, test) {
	function testExpression (testValue) {
	    return [test, testValue, value];
	}
	var cases = arguments.toArray().slice(2).map(function (_case) {
	    if (_case[0] instanceof Symbol && _case[0].name == 'else:')
		return _case;
	    else
		return ([[S('or')].concat(_case[0].map(testExpression))]
			.concat(_case.slice(1)));
	});
	return [S('cond')].concat(cases);
    },
    'bind-methods': function (bindings) {
	var body = arguments.toArray().slice(1);
	var methodBindings = bindings.map(function (binding) {
	    return [binding[0], [S('method')].concat(binding.slice(1))];
	});
	return [S('bind'), methodBindings].concat(body);
    },
    'handler-case': function (body) {
	var conditions = arguments.toArray().slice(1);
	var conditionVariable = Symbol.generate();
	var cases = conditions.map(function (condition) {
	    // TODO: bind condition: argument
	    var _if = condition[0];
	    return [[S('instance?'),
		     conditionVariable, _if[0]]]
		.concat(condition.slice(1));
	});
	return [[S('method'), [],
		 [S('js:try'), body, conditionVariable,
		  [S('cond')].concat(cases)]]];
    },
    // TODO: define-method
    'define-method': function () {
	return [S('js:statements'),
		[S('define-function')].concat(arguments.toArray())];
    },
    'values': function () {
	var values = arguments.toArray();
	var caller = ['arguments', 'callee', 'caller'];
	return [S('begin'),
		[S('when'), ([S('js:get-property')]
			     .concat(caller).concat(['acceptsMultipleValues'])),
		 [S('js:set'), ([S('js:get-property')]
				.concat(caller).concat(['otherValues'])),
		  [S('list')].concat(values.slice(1))]],
		values[0]];
    }
}

var symbolMacros = {}

function macroexpand (form) {
    if (form instanceof Array) {
	while (form[0] instanceof Symbol && macros.hasOwnProperty(form[0].name))
	    form = macros[form[0].name].apply(this, form.slice(1));
	if (form instanceof Array)
	    return form.map(macroexpand);
	else
	    return macroexpand(form);
    } else if (form instanceof Symbol
	       && symbolMacros.hasOwnProperty(form.name)) {
	return macroexpand(symbolMacros[form.name]());
    } else
	return form;
}

//// writing

var infix = {
    'and': '&&', 'or': '||', 'js:+': '+', 'js:-': '-',
    'js:>': '>', 'js:<': '<', 'js:>=': '>=', 'js:<=': '<=',
    'js:==': '==', 'js:===': '==='
}

var symbolValues = {
    'js:null': 'null',
    '#f': 'false',
    '#t': 'true'
}

var specialForms = {
    'js:negative': function (allowStatements, object) {
	return '(- ' + write(object) + ')';
    },
    'js:not': function (allowStatements, expression) {
	return '!' + write(expression);
    },
    'begin': function (allowStatements) {
	var forms = arguments.toArray().slice(1);
	if (allowStatements) {
	    var separator = ';\n';
	    var result = forms.map(writeExpressions).join(separator);
	    if (forms.length > 1)
		result += '\n';
	    return result;
	} else if (forms.length > 1)
	    return '(' + forms.map(writeExpressions).join(', ') + ')';
	else
	    return writeExpressions(forms[0]);
    },
    'if': function (allowStatements, test, then, _else) {
	if (allowStatements) {
	    var result = 'if (' + write(test) + ') {\n'
		+ writeStatements(then) + '}';
	    if (_else instanceof Array)
		result += (' else {\n' + writeStatements(_else) + '\n}');
	    return result;
	} else {
	    return '(' + write(test) + ' ? '
		+ write(then) + ' : '
		+ write(_else) + ')';
	}
    },
    'list': function (allowStatements) {
	var elements = arguments.toArray().slice(1);
	return '[' + elements.map(writeExpressions).join(', ') + ']';
    },
    'js:defined': function (allowStatements, expression) {
	return '(typeof (' + write(expression) + ') != "undefined")';
    },
    'js:try': function (allowStatements, body, conditionVariable, _catch) {
	// TODO: if !allowStatements: wrap with function
	return 'try {\n'
	    + writeStatements(body) // TODO: return?
	    + '} catch (' + write(conditionVariable) + ') {\n'
	    + writeStatements(_catch)
	    + '\n}';
    },
    'js:for-in': function (allowStatements, variableAndExpression) {
	// TODO: if !allowStatements: wrap with function
	var body = arguments.toArray().slice(2);
	var variable = variableAndExpression[0];
	var expression = variableAndExpression[1];
	return 'for (var ' + variable + ' in ' + write(expression) + ') {\n'
	    + writeStatements([S('begin')].concat(body)) + '\n}';
    },
    'js:for': function (allowStatements, initTestNext) {
	// TODO: if !allowStatements: wrap with function
	var body = arguments.toArray().slice(2);
	var init = initTestNext[0];
	var test = initTestNext[1];
	var next = initTestNext[2];
	return 'for (var ' + init[0] + ' = ' + init[1] + '; '
	    + write(test) + '; ' + write(next) + ') {\n'
	    + writeStatements([S('begin')].concat(body)) + '\n}';
    },
    'js:identifier': function (allowStatements, name) {
	return ('' + name);
    },
    'js:get-property': function (allowStatements) {
	var elements = arguments.toArray().slice(1);
	var object = elements[0];
	if (typeof object != 'string')
	    object = write(object);
	return object
	    + (elements.slice(1)
	       .map(function (element) {
		   if (typeof element == 'string' &&
		       /^[a-zA-Z_]+$/.exec(element))
		   {
		       return '.' + element;
		   } else
		       return '[' + write(element) + ']';
	       }).join(''));
    },
    'js:call': function (allowStatements, name) {
	var args = arguments.toArray().slice(2);
	return name + '(' + args.map(writeExpressions).join(', ') + ')';
    },
    'js:new': function (allowStatements, name) {
	var args = arguments.toArray().slice(2);
	return 'new ' + name + '(' + args.map(writeExpressions).join(', ') + ')';
    },
    'js:var': function (allowStatements, name, value) {
	return "var " + name + " = " + write(value);
    },
    'js:set': function (allowStatements, name, value) {
	return write(name) + " = " + write(value);
    },
    'js:return': function (allowStatements, body) {
	return 'return ' + write(body);
    },
    'js:function': function (allowStatements, name, args, body) {
	return 'function ' + (name ? name + ' ' : '')
	    + '(' + args.join(', ') + ') '
	    + '{\n' + writeStatements(addReturn(body)) + '}';
    },
    'js:documentation': function (allowStatements, documentation) {
	return '/** \n'
	    + documentation.split('\n').map(function (line) {
		return ' * ' + line;
	    }).join('\n')
	    + '\n */\n';
    },
    'js:statements': function (allowStatements) {
	var body = arguments.toArray().slice(1);
	return body.map(writeStatements).join('');
    }
}

// helper
function writeStatements (form) {
    return write(form, true);
}

function writeExpressions (form) {
    return write(form, false);
}

function write (form, allowStatements) {
    if (form instanceof Array) {
	var head = form[0];
	var rest = form.slice(1);
	if (head instanceof Symbol && infix.hasOwnProperty(head.name)) {
	    return '(' + rest.map(writeExpressions).join(' ' + infix[head.name] + ' ') + ')';
	} else if (head instanceof Symbol && specialForms.hasOwnProperty(head.name)) {
	    return specialForms[head.name].apply(this, [allowStatements].concat(rest));
	} else if (head instanceof Array && head[0] && head[0].name == 'js:function') {
	    return '(' + write(head) + ')(' + rest.map(writeExpressions).join(', ') + ')';
	} else {
	    return write(head) + '(' + rest.map(writeExpressions).join(', ') + ')';
	}
    } else if (typeof form == "string") {
	return '"' + form + '"';
    } else if (form instanceof Symbol && symbolValues.hasOwnProperty(form.name)) {
	return symbolValues[form.name];
    } else
	return form;
}

function compile (form, allowStatements) {
    return write(macroexpand(form), allowStatements);
}

//// interface

exports.compile = function (code) {
    var stream = new Stream("(begin\n" + code + "\n)");
    var reader = new Reader(stream);
    var form = reader.read();
    return compile(form, true);
}<|endoftext|>


<commit_before>
// The textbook is stored in brackets.currentTextbook

function newTextbook() {
	var newTextbook 		= {};
	newTextbook.title 		= "Title";
	newTextbook.author 		= "Author";
	newTextbook.elements 	= [];
	return newTextbook;
}

function addPDFRectangleClip(source,startX,startY,endX,endY) {
	var newElement 		= {};
	newElement.type 	= "pdf";
	newElement.source 	= source;
	newElement.startX 	= startX;
	newElement.startY 	= startY;
	newElement.endX 	= endX;
	newElement.endY 	= endY;
	brackets.currentTextbook.elements[] = newElement;
	// return textbook;
}

function addYouTubeVid(textbook,source,offset) {}

function addText(textbook,text) {}

function addWiki(textbook,source) {}

function deleteElement(textbook, clipNumber) {}

// Move element at index oldPosition in between element at index NewPosition and the element at index (newPosition+1)
function moveElement(textbook,oldPosition,newPosition) {}<commit_msg>functions to add/delete elements and modify order<commit_after>
// The textbook is stored in brackets.currentTextbook

function newTextbook() {
	var newTextbook 		= {};
	newTextbook.title 		= "Title";
	newTextbook.author 		= "Author";
	newTextbook.elements 	= [];
	return newTextbook;
}

function addPDFRectangleClip(source,startX,startY,endX,endY) {
	var newElement 		= {};
	newElement.type 	= "pdf";
	newElement.source 	= source;
	newElement.startX 	= startX;
	newElement.startY 	= startY;
	newElement.endX 	= endX;
	newElement.endY 	= endY;
	brackets.currentTextbook.elements[] = newElement;
}

function addYouTubeVid(source,startTime) {
	var newElement 		= {};
	newElement.type 	= "youtube";
	newElement.source 	= source;
	newElement.startTime 	= startTime;
	brackets.currentTextbook.elements[] = newElement;
}

function addText(text) {
	var newElement 		= {};
	newElement.type 	= "text";
	newElement.text 	= text;
	brackets.currentTextbook.elements[] = newElement;
}

function addWiki(source) {
	var newElement 		= {};
	newElement.type 	= "wiki";
	newElement.source 	= source;
	brackets.currentTextbook.elements[] = newElement;
}

// If within range, delete. Else skip
function deleteElement(clipNumber) {
	var numberOfElements = brackets.currentTextbook.elements.length;
	if (clipNumber >= 0 && clipNumber<numberOfElements) {
		var newElements = [];
		for (var el = 0; el < n; el++) {
			newElements[] = brackets.currentTextbook.elements[el]
		}
		for (var el = n+1; el < numberOfElements; el++) {
			newElements[] = brackets.currentTextbook.elements[el]
		}
		brackets.currentTextbook.elements = newElements;
	}
}

// Move element at index oldPosition in between element at index newPosition and the element at index (newPosition+1)
function moveElement(oldPosition,newPosition) {
	var numberOfElements = brackets.currentTextbook.elements.length;
	if (oldPosition >= 0 && oldPosition<numberOfElements
		newPosition >= 0 && newPosition<numberOfElements) {
		// If no change then return
		if (oldPosition == newPosition) {return;}
		// Copy everything that's not going to be changed
		var newElements = [];
		var firstChange = Math.min(oldPosition,newPosition);
		for (var el = 0; el < firstChange; el++) {
			newElements[] = brackets.currentTextbook.elements[el];
		}
		// If move up the page
		if (oldPosition > newPosition) {
			newElements[] = brackets.currentTextbook.elements[oldPosition];
			for (var el = newPosition; el < oldPosition; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			for (var el = oldPosition+1; el < numberOfElements; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			brackets.currentTextbook.elements = newElements;
		}
		// If move down the page
		else {
			for (var el = oldPosition+1; el <= newPosition; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			newElements[] = brackets.currentTextbook.elements[oldPosition];
			for (var el = newPosition+1; el < numberOfElements; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			brackets.currentTextbook.elements = newElements;
		}
	};
}
<|endoftext|>


<commit_before>
// The textbook is stored in brackets.currentTextbook

function newTextbook() {
	var newTextbook 		= {};
	newTextbook.title 		= "Title";
	newTextbook.author 		= "Author";
	newTextbook.elements 	= [];
	return newTextbook;
}

function addPDFRectangleClip(source,startX,startY,endX,endY) {
	var newElement 		= {};
	newElement.type 	= "pdf";
	newElement.source 	= source;
	newElement.startX 	= startX;
	newElement.startY 	= startY;
	newElement.endX 	= endX;
	newElement.endY 	= endY;
	brackets.currentTextbook.elements[] = newElement;
}

function addYouTubeVid(source,startTime) {
	var newElement 		= {};
	newElement.type 	= "youtube";
	newElement.source 	= source;
	newElement.startTime 	= startTime;
	brackets.currentTextbook.elements[] = newElement;
}

function addText(text) {
	var newElement 		= {};
	newElement.type 	= "text";
	newElement.text 	= text;
	brackets.currentTextbook.elements[] = newElement;
}

function addWiki(source) {
	var newElement 		= {};
	newElement.type 	= "wiki";
	newElement.source 	= source;
	brackets.currentTextbook.elements[] = newElement;
}

// If within range, delete. Else skip
function deleteElement(clipNumber) {
	var numberOfElements = brackets.currentTextbook.elements.length;
	if (clipNumber >= 0 && clipNumber<numberOfElements) {
		var newElements = [];
		for (var el = 0; el < n; el++) {
			newElements[] = brackets.currentTextbook.elements[el]
		}
		for (var el = n+1; el < numberOfElements; el++) {
			newElements[] = brackets.currentTextbook.elements[el]
		}
		brackets.currentTextbook.elements = newElements;
	}
}

// Move element at index oldPosition in between element at index newPosition and the element at index (newPosition+1)
function moveElement(oldPosition,newPosition) {
	var numberOfElements = brackets.currentTextbook.elements.length;
	if (oldPosition >= 0 && oldPosition<numberOfElements
		newPosition >= 0 && newPosition<numberOfElements) {
		// If no change then return
		if (oldPosition == newPosition) {return;}
		// Copy everything that's not going to be changed
		var newElements = [];
		var firstChange = Math.min(oldPosition,newPosition);
		for (var el = 0; el < firstChange; el++) {
			newElements[] = brackets.currentTextbook.elements[el];
		}
		// If move up the page
		if (oldPosition > newPosition) {
			newElements[] = brackets.currentTextbook.elements[oldPosition];
			for (var el = newPosition; el < oldPosition; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			for (var el = oldPosition+1; el < numberOfElements; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			brackets.currentTextbook.elements = newElements;
		}
		// If move down the page
		else {
			for (var el = oldPosition+1; el <= newPosition; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			newElements[] = brackets.currentTextbook.elements[oldPosition];
			for (var el = newPosition+1; el < numberOfElements; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			brackets.currentTextbook.elements = newElements;
		}
	};
}
<commit_msg>added comments<commit_after>
// The textbook is stored in brackets.currentTextbook

function newTextbook() {
	var newTextbook 		= {};
	newTextbook.title 		= "Title";
	newTextbook.author 		= "Author";
	newTextbook.elements 	= [];
	return newTextbook;
}

function addPDFRectangleClip(source,startX,startY,endX,endY) {
	var newElement 		= {};
	newElement.type 	= "pdf";
	newElement.source 	= source;
	newElement.startX 	= startX;
	newElement.startY 	= startY;
	newElement.endX 	= endX;
	newElement.endY 	= endY;
	newElement.comments = [];
	brackets.currentTextbook.elements[] = newElement;
}

function addYouTubeVid(source,startTime) {
	var newElement 		= {};
	newElement.type 	= "youtube";
	newElement.source 	= source;
	newElement.startTime 	= startTime;
	newElement.comments = [];
	brackets.currentTextbook.elements[] = newElement;
}

function addText(text) {
	var newElement 		= {};
	newElement.type 	= "text";
	newElement.text 	= text;
	newElement.comments = [];
	brackets.currentTextbook.elements[] = newElement;
}

function addWiki(source) {
	var newElement 		= {};
	newElement.type 	= "wiki";
	newElement.source 	= source;
	newElement.comments = [];
	brackets.currentTextbook.elements[] = newElement;
}

// If within range, delete. Else skip
function deleteElement(clipNumber) {
	var numberOfElements = brackets.currentTextbook.elements.length;
	if (clipNumber >= 0 && clipNumber<numberOfElements) {
		var newElements = [];
		for (var el = 0; el < clipNumber; el++) {
			newElements[] = brackets.currentTextbook.elements[el]
		}
		for (var el = clipNumber+1; el < numberOfElements; el++) {
			newElements[] = brackets.currentTextbook.elements[el]
		}
		brackets.currentTextbook.elements = newElements;
	}
}

// Move element at index oldPosition in between element at index newPosition and the element at index (newPosition+1)
function moveElement(oldPosition,newPosition) {
	var numberOfElements = brackets.currentTextbook.elements.length;
	if (oldPosition >= 0 && oldPosition<numberOfElements
		newPosition >= 0 && newPosition<numberOfElements) {
		// If no change then return
		if (oldPosition == newPosition) {return;}
		// Copy everything that's not going to be changed
		var newElements = [];
		var firstChange = Math.min(oldPosition,newPosition);
		for (var el = 0; el < firstChange; el++) {
			newElements[] = brackets.currentTextbook.elements[el];
		}
		// If move up the page
		if (oldPosition > newPosition) {
			newElements[] = brackets.currentTextbook.elements[oldPosition];
			for (var el = newPosition; el < oldPosition; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			for (var el = oldPosition+1; el < numberOfElements; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			brackets.currentTextbook.elements = newElements;
		}
		// If move down the page
		else {
			for (var el = oldPosition+1; el <= newPosition; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			newElements[] = brackets.currentTextbook.elements[oldPosition];
			for (var el = newPosition+1; el < numberOfElements; el++) {
				newElements[] = brackets.currentTextbook.elements[el]
			}
			brackets.currentTextbook.elements = newElements;
		}
	};
}

function addComment(elementNumber,comment,author) {
	brackets.currentTextbook.elements.comments[] = {
		"author"  = author,
		"comment" = comment
	};
}

function deleteComment(elementNumber,commentNumber) {
	var numberOfElements = brackets.currentTextbook.elements.length;
	if (elementNumber >= 0 && elementNumber<numberOfElements) {
		var numberOfComments = brackets.currentTextbook.elements[elementNumber].comments.length;
		if (brackets.currentTextbook.elements[elementNumber]comments.length > commentNumber) {       // Fix this also fix array.append() vs array[]
			var newComments = [];
			for (var comm = 0; comm < commentNumber; el++) {
				newElements[] = brackets.currentTextbook.elements[elementNumber].comments[comm];
			}
			for (var comm = commentNumber+1; comm < numberOfElements; el++) {
				newElements[] = brackets.currentTextbook.elements[elementNumber].comments[comm];
			}
			brackets.currentTextbook.elements[elementNumber].comments[commentNumber];
		}
	}

}<|endoftext|>