<commit_before>/**
 * Cache based on Web Storage (session or local)
 */

function now() {
    return new Date().getTime();
}

/**
 * A fake WebStorage doing nothing.
 *
 * To use as fallback when WebStorage is not available
 */
export class NullStorage {
    constructor() {
        this.length = 0;
    }
    key() {}
    getItem() {}
    setItem() {}
    removeItem() {}
    clear() {}
}

/**
 * A WebStorage based cache with optionnal TTL (expressed in seconds).
 */
export class Cache {
    /**
     * Constructor
     * @param  {String} namespace The namespace key meant to isolate keys
     * @param  {int} ttl                An optionnal default TTL
     */
    constructor(namespace, ttl) {
        this.namespace = namespace;
        this.ttl = ttl;
        this.prefix = `__${this.namespace}__`;
        this.rekey = new RegExp(`^${this.prefix}`);
        try {
            this.storage = sessionStorage;
        } catch(e) {
            // Session storage access is not allowed (browser privacy settings)
            // A warning is issued in the console and cache is disabled
            const msg = `Access to sessionStorage is not allowed.\
            "${namespace}" cache is disabled`;
            console.warn(msg);  // eslint-disable-line no-console
            this.storage = new NullStorage();
        }
    }

    /**
     * Build the namespace key
     * @param  {String} key The public raw key to be namespaced
     * @return {String}     The namespaced key
     */
    _key(key) {
        return this.prefix + key;
    }

    /**
     * Prefix the namespace ttl key
     * @param  {String} key The public raw key to be namespaced
     * @return {String}     The namespace ttl key
     */
    _ttl(key) {
        return `${this.prefix}__ttl__${key}`;
    }

    /**
     * List all cache keys in the storage
     * @return {Array} All existing cache keys
     */
    get keys() {
        return [...Array(this.storage.length).keys()]
            .map(idx => this.storage.key(idx))
            .filter(key => this.rekey.test(key))
            .map(key => key.replace(this.rekey, ''));
    }

    /**
     * Get value from its key
     * @param  {String} key The cache key
     * @return {Object}     The value if exists, undefined otherwise
     */
    get(key) {
        if (this.isExpired(key)) {
            this.remove(key);
        }

        const value = this.storage.getItem(this._key(key));
        if (value) return JSON.parse(value);
    }

    /**
     * Insert or update a cached value
     * @param {String} key   The cache key
     * @param {Object} value The value to cache
     * @param {int} ttl   an optional TTL (override the default TTL)
     * @return {Object} The cache instance (allow chaining)
     */
    set(key, value, ttl) {
        if (Number.isInteger(ttl) || Number.isInteger(this.ttl)) {
            ttl = Number.isInteger(ttl) ? ttl : this.ttl;
            this.storage.setItem(this._ttl(key), now() + ttl);
        } else {
           this.storage.removeItem(this._ttl(key));
        }

        this.storage.setItem(this._key(key), JSON.stringify(value));
        return this;
    }

    /**
     * Remove a value from the cache given its key
     * @param {String} key   The cache key
     * @return {Object} The cache instance (allow chaining)
     */
    remove(key) {
        this.storage.removeItem(this._ttl(key));
        this.storage.removeItem(this._key(key));
        return this;
    }

    /**
     * Empty the cache (remove all keys)
     * @return {Object} The cache instance (allow chaining)
     */
    clear() {
        this.keys.forEach(key => this.remove(key));
        return this;
    }

    /**
     * Check if a cached value is expired
     * @param {String} key   The cache key
     * @return {Boolean}     true if the cached value expired
     */
    isExpired(key) {
        // const value = this.storage.getItem(this._ttl(key));
        // if (!value) return false;
        const ttl = JSON.parse(this.storage.getItem(this._ttl(key)));
        return Number.isInteger(ttl) && now() > ttl;
    }
}

export const cache = new Cache('udata');

export default cache;
<commit_msg>Improve fallback storage<commit_after>/**
 * Cache based on Web Storage (session or local)
 */

function now() {
    return new Date().getTime();
}

/**
 * A WebStorage shim.
 *
 * To use as fallback when WebStorage is not available
 * or when access to webstorage is not allowed.
 *
 * This storage has poor performance and won't survive page change or reload.
 */
export class ShimStorage {
    constructor() {
        this.store = {};
    }

    get length() {
        return Object.keys(this.store).length;
    }

    key(idx) {
        return Object.keys(this.storage)[idx] || null;
    }

    getItem(key) {
        return this.store[key] || null;
    }

    setItem(key, value) {
        this.store[key] = value;
    }

    removeItem(key) {
        delete this.store[key];
    }

    clear() {
        this.store = {};
    }
}

/**
 * A WebStorage based cache with optionnal TTL (expressed in seconds).
 */
export class Cache {
    /**
     * Constructor
     * @param  {String} namespace The namespace key meant to isolate keys
     * @param  {int} ttl                An optionnal default TTL
     */
    constructor(namespace, ttl) {
        this.namespace = namespace;
        this.ttl = ttl;
        this.prefix = `__${this.namespace}__`;
        this.rekey = new RegExp(`^${this.prefix}`);
        try {
            this.storage = sessionStorage;
        } catch(e) {
            // Session storage access is not allowed (browser privacy settings)
            // A warning is issued in the console
            const msg = `Access to sessionStorage is not allowed.\
            "${namespace}" cache performances will be degraded`;
            console.warn(msg);  // eslint-disable-line no-console
            this.storage = new ShimStorage();
        }
    }

    /**
     * Build the namespace key
     * @param  {String} key The public raw key to be namespaced
     * @return {String}     The namespaced key
     */
    _key(key) {
        return this.prefix + key;
    }

    /**
     * Prefix the namespace ttl key
     * @param  {String} key The public raw key to be namespaced
     * @return {String}     The namespace ttl key
     */
    _ttl(key) {
        return `${this.prefix}__ttl__${key}`;
    }

    /**
     * List all cache keys in the storage
     * @return {Array} All existing cache keys
     */
    get keys() {
        return [...Array(this.storage.length).keys()]
            .map(idx => this.storage.key(idx))
            .filter(key => this.rekey.test(key))
            .map(key => key.replace(this.rekey, ''));
    }

    /**
     * Get value from its key
     * @param  {String} key The cache key
     * @return {Object}     The value if exists, undefined otherwise
     */
    get(key) {
        if (this.isExpired(key)) {
            this.remove(key);
        }

        const value = this.storage.getItem(this._key(key));
        if (value) return JSON.parse(value);
    }

    /**
     * Insert or update a cached value
     * @param {String} key   The cache key
     * @param {Object} value The value to cache
     * @param {int} ttl   an optional TTL (override the default TTL)
     * @return {Object} The cache instance (allow chaining)
     */
    set(key, value, ttl) {
        if (Number.isInteger(ttl) || Number.isInteger(this.ttl)) {
            ttl = Number.isInteger(ttl) ? ttl : this.ttl;
            this.storage.setItem(this._ttl(key), now() + ttl);
        } else {
           this.storage.removeItem(this._ttl(key));
        }

        this.storage.setItem(this._key(key), JSON.stringify(value));
        return this;
    }

    /**
     * Remove a value from the cache given its key
     * @param {String} key   The cache key
     * @return {Object} The cache instance (allow chaining)
     */
    remove(key) {
        this.storage.removeItem(this._ttl(key));
        this.storage.removeItem(this._key(key));
        return this;
    }

    /**
     * Empty the cache (remove all keys)
     * @return {Object} The cache instance (allow chaining)
     */
    clear() {
        this.keys.forEach(key => this.remove(key));
        return this;
    }

    /**
     * Check if a cached value is expired
     * @param {String} key   The cache key
     * @return {Boolean}     true if the cached value expired
     */
    isExpired(key) {
        const ttl = JSON.parse(this.storage.getItem(this._ttl(key)));
        return Number.isInteger(ttl) && now() > ttl;
    }
}

export const cache = new Cache('udata');

export default cache;
<|endoftext|>


<commit_before>/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {

} from 'react-native';

import * as Animatable from 'react-native-animatable';
import Entypo from 'react-native-vector-icons/Entypo';

export default class RowGraph extends Component {

    componentWillMount(){
        console.log(this.state);
    }
    componentDidMount(){
    }
    render() {

    }
}

module.exports = RowGraph;
<commit_msg>Implementation of chart screen.<commit_after>/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    Image,
    Dimensions,
    AsyncStorage,
    Platform,
    AppState,
    TouchableHighlight
} from 'react-native';

import * as Animatable from 'react-native-animatable';
import Entypo from 'react-native-vector-icons/Entypo';

export default class RowGraph extends Component {
    state = {
        size : this.props.size,
        title : this.props.title,
        value : this.props.value,
        color : this.props.color,

        padding : (GLOBAL.width - this.props.size)/2,
    }
    componentWillMount(){
        console.log(this.state);
    }
    componentDidMount(){
    }
    render() {
        const styles = StyleSheet.create({
            container: {
                width: this.state.size,
                height: this.state.size/5,
                marginTop: this.state.padding,
                alignItems: 'center',
                justifyContent: 'center',
                backgroundColor:'#fff',
                flexDirection:'row',
            },
            leftLable:{
                width: this.state.size*0.35,
                height: this.state.size/5,
                alignItems: 'center',
                justifyContent: 'center',
                backgroundColor:this.state.color,
            },
            rightLable:{
                width: this.state.size*0.65,
                height: this.state.size/5,
                alignItems: 'center',
                justifyContent: 'center',
            },
            Text:{
                color :'#000',
                fontSize : 20,
            },
            subText:{
                color :'#999',
                fontSize : 13,
                marginTop:5,
            },
        });
        return (
            <View style={styles.container}>

                <View style={styles.leftLable}>
                    <Entypo name="adjust" size={this.state.size*0.1} color="#fff"/>
                </View>
                <Animatable.View animation="bounceInRight"  style={styles.rightLable}>
                    <Text style={styles.Text}>{this.state.value}</Text>
                    <Text style={styles.subText}>{this.state.title}</Text>
                </Animatable.View>
            </View>
        );
    }
}

module.exports = RowGraph;
<|endoftext|>


<commit_before>import {element} from 'deku';

import BookmarkItem from './bookmark_item';

function closeHandler(event, {props, state}) {

}

function render({props, state}) {
  const treeInfo = props.treeInfo;
  const treeItems = [];

  const isRootBox = globals.isRootFolder(treeInfo);

  const pushTreeItem = (thisTreeInfo) => {
    thisTreeInfo.children.forEach((itemInfo) => {
      treeItems.push(
        <BookmarkItem itemInfo={itemInfo} />
      );
    });
  };

  if (isRootBox) {
    pushTreeItem(globals.rootTree);
  }

  pushTreeItem(treeInfo);

  return (

{treeInfo.title}

        {treeItems}

  );
}

function scrollHandler(event, {props, state}) {
}

function wheelHandler(event, {props, state}) {
  event.preventDefault();
}

export default {render};
<commit_msg>Implement setHeight logic in box_template<commit_after>import {element} from 'deku';

import BookmarkItem from './bookmark_item';

function afterRender(component, el) {
  setHeight(el);
}

function closeHandler(event, {props, state}) {

}

function render({props, state}) {
  const treeInfo = props.treeInfo;
  const treeItems = [];

  const isRootBox = globals.isRootFolder(treeInfo);

  const pushTreeItem = (thisTreeInfo) => {
    thisTreeInfo.children.forEach((itemInfo) => {
      treeItems.push(
        <BookmarkItem itemInfo={itemInfo} />
      );
    });
  };

  if (isRootBox) {
    pushTreeItem(globals.rootTree);
  }

  pushTreeItem(treeInfo);

  return (

{treeInfo.title}

        {treeItems}

  );
}

function scrollHandler(event, {props, state}) {
}

function setHeight(el) {
  const bookmarkList = el.getElementsByClassName('bookmark-list')[0];

  // head-box and search-box height
  const bookmarkListOffsetTop = bookmarkList.getBoundingClientRect().top;

  const maxListHeight = globals.maxHeight - bookmarkListOffsetTop;

  const listHeight = Math.min(bookmarkList.scrollHeight, maxListHeight);

  const bodyHeight = listHeight + bookmarkListOffsetTop;

  bookmarkList.style.maxHeight = listHeight + 'px';

  document.body.style.height = Math.min(bodyHeight, globals.maxHeight) + 'px';
}

function wheelHandler(event, {props, state}) {
  event.preventDefault();
}

export default {afterRender, render};
<|endoftext|>


<commit_before>// Various assorted call/response combinations

module.exports = {listeners: [
{
    type: "equals",
    query: ".dice",
    callback: function(reply){
        reply(Math.floor(Math.random() * 6) + 1);
    }
}, {
    type: "equals",
    query: ".coin",
    callback: function(reply){
        reply(Math.random()<.5 ? "Heads" : "Tails");
    }
}
]};
<commit_msg>Dynamic types are best types<commit_after>// Various assorted call/response combinations

module.exports = {listeners: [
{
    type: "equals",
    query: ".dice",
    callback: function(reply){
        reply(Math.floor(Math.random() * 6) + 1 + "");
    }
}, {
    type: "equals",
    query: ".coin",
    callback: function(reply){
        reply(Math.random()<.5 ? "Heads" : "Tails");
    }
}
]};
<|endoftext|>


<commit_before>const path = require('path');
const resolve = pkg => path.join(__dirname, '../../packages', pkg, 'dist', 'index.dev.esm.js');

const customLaunchers = {
  slChrome: {
    base: 'SauceLabs',
    browserName: 'chrome'
  },
  slIphone5: {
    base: 'SauceLabs',
    browserName: 'iphone',
    version: '9.3'
  },
  slIphone6: {
    base: 'SauceLabs',
    browserName: 'iphone',
    version: '10.3'
  },
  slIphone7: {
    base: 'SauceLabs',
    browserName: 'iphone',
    version: 'latest'
  },
  slSafari8: {
    base: 'SauceLabs',
    browserName: 'safari',
    platform: 'OS X 10.10'
  },
  slSafari9: {
    base: 'SauceLabs',
    browserName: 'safari',
    platform: 'OS X 10.11'
  },
  sl_mac_firfox: {
    base: 'SauceLabs',
    browserName: 'firefox',
    platform: 'OS X 10.12'
  },
  sl_safari: {
    base: 'SauceLabs',
    browserName: 'safari',
    version: 'latest'
  },
  slIE10: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 7',
    version: '10'
  },
  slIE11: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 7',
    version: '11'
  },
  slEdge13: {
    base: 'SauceLabs',
    browserName: 'MicrosoftEdge',
    version: '13',
    platform: 'Windows 10'
  },
  slEdge14: {
    base: 'SauceLabs',
    browserName: 'MicrosoftEdge',
    version: '14',
    platform: 'Windows 10'
  },
  slEdge16: {
    base: 'SauceLabs',
    browserName: 'MicrosoftEdge',
    version: '16',
    platform: 'Windows 10'
  },
  sl_mac_chrome: {
    base: 'SauceLabs',
    browserName: 'chrome',
    platform: 'macOS 10.12'
  },
  slFirefox: {
    base: 'SauceLabs',
    browserName: 'firefox'
  },
  slAndroid5: {
    base: 'SauceLabs',
    browserName: 'android',
    version: '5.1'
  },
  slAndroid7: {
    base: 'SauceLabs',
    browserName: 'android',
    version: '6.0'
  }
};

module.exports = function(config) {
  config.set({
    basePath: '../../',

    frameworks: ['gzip', 'jasmine'],

    files: [path.join(__dirname, '../../fixtures/browser/test.index.js')],

    preprocessors: {
      './fixtures/browser/test.index.js': ['webpack', 'gzip']
    },

    client: {
      jasmine: {
        random: false // Adding jasmine.random false disables test random order
      }
    },

    reporters: ['dots', 'saucelabs'],
    sauceLabs: {
      build: 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')',
      tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
      startConnect: true,
      testName: `InfernoJS`,
      recordVideo: false,
      recordScreenshots: false,
      videoUploadOnPass: false,
      recordLogs: false,
      captureHtml: false,
      commandTimeout: 400
    },

    plugins: ['karma-jasmine', 'karma-gzip', 'karma-webpack', 'havunen-karma-sauce-launcher'],

    customLaunchers: customLaunchers,
    browsers: Object.keys(customLaunchers),

    captureTimeout: 600000,
    browserNoActivityTimeout: 600000,
    browserDisconnectTolerance: 2,
    processKillTimeout: 20000,
    browserDisconnectTimeout: 10000,

    browserConsoleLogOptions: {
      level: 'warn',
      terminal: false
    },
    colors: true,
    singleRun: true,
    autoWatch: false,
    concurrency: 1,

    webpackMiddleware: {
      stats: 'errors-only',
      noInfo: true
    },

    webpack: {
      devtool: 'none',
      mode: 'production',
      optimization: {
        splitChunks: false,
        runtimeChunk: false,
        minimize: true
      },
      module: {
        rules: [
          {
            test: /\.(js|jsx|tsx|ts)$/,
            loader: path.join(__dirname, 'node_modules/babel-loader'),
            exclude: /node_modules/,
            options: {
              babelrc: false,
              presets: [
                [
                  '@babel/preset-env',
                  {
                    loose: true,
                    targets: {
                      browsers: ['ie >= 10', 'safari > 7']
                    }
                  }
                ],
                '@babel/typescript'
              ],
              plugins: [['babel-plugin-inferno', { imports: true }], ['@babel/plugin-proposal-class-properties', { loose: true }]]
            }
          }
        ]
      },
      resolve: {
        alias: {
          inferno: resolve('inferno'),
          'inferno-component': resolve('inferno-component'),
          'inferno-compat': resolve('inferno-compat'),
          'inferno-create-class': resolve('inferno-create-class'),
          'inferno-create-element': resolve('inferno-create-element'),
          'inferno-devtools': resolve('inferno-devtools'),
          'inferno-hydrate': resolve('inferno-hydrate'),
          'inferno-extras': resolve('inferno-extras'),
          'inferno-hyperscript': resolve('inferno-hyperscript'),
          'inferno-mobx': resolve('inferno-mobx'),
          'inferno-redux': resolve('inferno-redux'),
          'inferno-router': resolve('inferno-router'),
          'inferno-server': resolve('inferno-server'),
          'inferno-shared': resolve('inferno-shared'),
          'inferno-test-utils': resolve('inferno-test-utils'),
          'inferno-utils': path.join(__dirname, '../../packages', 'inferno-utils', 'src', 'index.ts'),
          'inferno-vnode-flags': resolve('inferno-vnode-flags'),
          'inferno-clone-vnode': resolve('inferno-clone-vnode'),
          mobx: path.join(__dirname, '../../node_modules/mobx/lib/mobx.module.js')
        },
        extensions: ['.js', '.jsx', '.tsx', '.ts'],
        mainFields: ['browser', 'main']
      },
      devServer: {
        noInfo: true
      },
      stats: 'errors-only',
      performance: {
        hints: false
      }
    }
  });
};
<commit_msg>removed iphone browser because it does not start ... something wrong with saucelabs<commit_after>const path = require('path');
const resolve = pkg => path.join(__dirname, '../../packages', pkg, 'dist', 'index.dev.esm.js');

const customLaunchers = {
  slChrome: {
    base: 'SauceLabs',
    browserName: 'chrome'
  },
  slIphone5: {
    base: 'SauceLabs',
    browserName: 'iphone',
    version: '9.3'
  },
  slSafari8: {
    base: 'SauceLabs',
    browserName: 'safari',
    platform: 'OS X 10.10'
  },
  slSafari9: {
    base: 'SauceLabs',
    browserName: 'safari',
    platform: 'OS X 10.11'
  },
  sl_mac_firfox: {
    base: 'SauceLabs',
    browserName: 'firefox',
    platform: 'OS X 10.12'
  },
  sl_safari: {
    base: 'SauceLabs',
    browserName: 'safari',
    version: 'latest'
  },
  slIE10: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 7',
    version: '10'
  },
  slIE11: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 7',
    version: '11'
  },
  slEdge13: {
    base: 'SauceLabs',
    browserName: 'MicrosoftEdge',
    version: '13',
    platform: 'Windows 10'
  },
  slEdge14: {
    base: 'SauceLabs',
    browserName: 'MicrosoftEdge',
    version: '14',
    platform: 'Windows 10'
  },
  slEdge16: {
    base: 'SauceLabs',
    browserName: 'MicrosoftEdge',
    version: '16',
    platform: 'Windows 10'
  },
  sl_mac_chrome: {
    base: 'SauceLabs',
    browserName: 'chrome',
    platform: 'macOS 10.12'
  },
  slFirefox: {
    base: 'SauceLabs',
    browserName: 'firefox'
  },
  slAndroid5: {
    base: 'SauceLabs',
    browserName: 'android',
    version: '5.1'
  },
  slAndroid7: {
    base: 'SauceLabs',
    browserName: 'android',
    version: '6.0'
  }
};

module.exports = function(config) {
  config.set({
    basePath: '../../',

    frameworks: ['gzip', 'jasmine'],

    files: [path.join(__dirname, '../../fixtures/browser/test.index.js')],

    preprocessors: {
      './fixtures/browser/test.index.js': ['webpack', 'gzip']
    },

    client: {
      jasmine: {
        random: false // Adding jasmine.random false disables test random order
      }
    },

    reporters: ['dots', 'saucelabs'],
    sauceLabs: {
      build: 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')',
      tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
      startConnect: true,
      testName: `InfernoJS`,
      recordVideo: false,
      recordScreenshots: false,
      videoUploadOnPass: false,
      recordLogs: false,
      captureHtml: false,
      commandTimeout: 400
    },

    plugins: ['karma-jasmine', 'karma-gzip', 'karma-webpack', 'havunen-karma-sauce-launcher'],

    customLaunchers: customLaunchers,
    browsers: Object.keys(customLaunchers),

    captureTimeout: 600000,
    browserNoActivityTimeout: 600000,
    browserDisconnectTolerance: 2,
    processKillTimeout: 20000,
    browserDisconnectTimeout: 10000,

    browserConsoleLogOptions: {
      level: 'warn',
      terminal: false
    },
    colors: true,
    singleRun: true,
    autoWatch: false,
    concurrency: 1,

    webpackMiddleware: {
      stats: 'errors-only',
      noInfo: true
    },

    webpack: {
      devtool: 'none',
      mode: 'production',
      optimization: {
        splitChunks: false,
        runtimeChunk: false,
        minimize: true
      },
      module: {
        rules: [
          {
            test: /\.(js|jsx|tsx|ts)$/,
            loader: path.join(__dirname, 'node_modules/babel-loader'),
            exclude: /node_modules/,
            options: {
              babelrc: false,
              presets: [
                [
                  '@babel/preset-env',
                  {
                    loose: true,
                    targets: {
                      browsers: ['ie >= 10', 'safari > 7']
                    }
                  }
                ],
                '@babel/typescript'
              ],
              plugins: [['babel-plugin-inferno', { imports: true }], ['@babel/plugin-proposal-class-properties', { loose: true }]]
            }
          }
        ]
      },
      resolve: {
        alias: {
          inferno: resolve('inferno'),
          'inferno-component': resolve('inferno-component'),
          'inferno-compat': resolve('inferno-compat'),
          'inferno-create-class': resolve('inferno-create-class'),
          'inferno-create-element': resolve('inferno-create-element'),
          'inferno-devtools': resolve('inferno-devtools'),
          'inferno-hydrate': resolve('inferno-hydrate'),
          'inferno-extras': resolve('inferno-extras'),
          'inferno-hyperscript': resolve('inferno-hyperscript'),
          'inferno-mobx': resolve('inferno-mobx'),
          'inferno-redux': resolve('inferno-redux'),
          'inferno-router': resolve('inferno-router'),
          'inferno-server': resolve('inferno-server'),
          'inferno-shared': resolve('inferno-shared'),
          'inferno-test-utils': resolve('inferno-test-utils'),
          'inferno-utils': path.join(__dirname, '../../packages', 'inferno-utils', 'src', 'index.ts'),
          'inferno-vnode-flags': resolve('inferno-vnode-flags'),
          'inferno-clone-vnode': resolve('inferno-clone-vnode'),
          mobx: path.join(__dirname, '../../node_modules/mobx/lib/mobx.module.js')
        },
        extensions: ['.js', '.jsx', '.tsx', '.ts'],
        mainFields: ['browser', 'main']
      },
      devServer: {
        noInfo: true
      },
      stats: 'errors-only',
      performance: {
        hints: false
      }
    }
  });
};
<|endoftext|>


<commit_before>/*eslint-env node */
'use strict';
var net = require('net');
var Long = require('long');
var float = require('./float');
var consts = require('./consts');
var HOST = consts.HOST;
var PORT = consts.PORT;
var sqrt = Math.sqrt;

var NUM_TESTS_PER_CHUNK = consts.NUM_TESTS_PER_CHUNK;
var INTERVAL = 1000;
var MAX_NUM = Long.fromString(float.INF_HEX, false, 16);

// Create a server instance, and chain the listen function to it
// The function passed to net.createServer() becomes the event handler for the 'connection' event
// The sock object the callback function receives UNIQUE for each connection
net.createServer((sock) => {
    var timeout;

    // We have a connection - a socket object is assigned to the connection automatically
    console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);

    // Add a 'data' event handler to this instance of socket
    sock.on('data', (data) => {

        console.log('DATA ' + sock.remoteAddress + ': ' + data);
        // Write the data back to the socket, the client will receive it as data from the server
        sock.write('You said "' + data + '"');

    });

    // Add a 'close' event handler to this instance of socket
    sock.on('close', () => {
        console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
        clearTimeout(timeout);
    });

    // n is long
    // sends an array of hex strings eg [x, sqrt(x), x+1, sqrt(x+1)...] to client
    function generateTests(n) {
      let tests = [];
      for (let i = 0; i < NUM_TESTS_PER_CHUNK; i++) {
        if (n.add(i).greaterThan(MAX_NUM)) {
            return;
        }

        let h = n.add(i).toString(16);
        let f = float.fromHex(h);

        tests.push(h, float.toHex(sqrt(f)));
      }

      sock.write(JSON.stringify(tests));

      // console.log(tests);
      if (n.lessThanOrEqual(MAX_NUM)) {
        timeout = setTimeout(generateTests.bind(null, n.add(NUM_TESTS_PER_CHUNK)), INTERVAL);
      }
    }

    generateTests(Long.UZERO);

}).listen(PORT, HOST);

console.log('Server listening on ' + HOST + ':' + PORT);

<commit_msg>change testing to random sampling<commit_after>/*eslint-env node */
'use strict';
var net = require('net');
var Long = require('long');
var float = require('./float');
var consts = require('./consts');
var HOST = consts.HOST;
var PORT = consts.PORT;
var sqrt = Math.sqrt;

var NUM_TESTS_PER_CHUNK = consts.NUM_TESTS_PER_CHUNK;
var MAX_NUM = Long.fromString(float.INF_HEX, false, 16);

// Create a server instance, and chain the listen function to it
// The function passed to net.createServer() becomes the event handler for the 'connection' event
// The sock object the callback function receives UNIQUE for each connection
net.createServer((sock) => {
    var timeout;
    var m = Long.fromString(float.ZERO_HEX, 16);
    var tests = [];

    // We have a connection - a socket object is assigned to the connection automatically
    console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);

    // Add a 'data' event handler to this instance of socket
    sock.on('data', (data) => {

        // console.log('DATA ' + sock.remoteAddress + ': ' + data);

          if (data.toString() === 'received' && m.lessThanOrEqual(MAX_NUM)) {
            if (m.modulo(0x10000).toNumber() === 0) {
                console.log(m.toString());
            }
            m = m.add(NUM_TESTS_PER_CHUNK);
            sendTests();
            generateTests(m);
          } else {
              console.log('failed tests', tests.map((c, i) => c + ' ' + tests[i+1])
                .filter((c, i) => (i % 2) === 0)
                .join('\n'));
          }
    });

    // Add a 'close' event handler to this instance of socket
    sock.on('close', () => {
        console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
        clearTimeout(timeout);
    });

    // n is long
    // sends an array of hex strings eg [x, sqrt(x), x+1, sqrt(x+1)...] to client
    function generateTests(n) {
        tests = [];
      for (let i = 0; i < NUM_TESTS_PER_CHUNK; i++) {
        if (n.add(i).greaterThan(MAX_NUM)) {
            return;
        }

        /* random sampling instead of exhaustive testing */
        // let h = n.add(i).toString(16);
        let h = float.random();
        let f = float.fromHex(h);

        tests.push(h, float.toHex(sqrt(f)));
      }
    }

    function sendTests() {
      sock.write(tests.join(' '));
    }

    generateTests(m);
    sendTests();

}).listen(PORT, HOST);

console.log('Server listening on ' + HOST + ':' + PORT);

<|endoftext|>


<commit_before>/* global $:false, localStorage: false, Handlebars: false, document: false, window: false, console.log: false, setTimeout: false;*/

'use strict';
var s, // access to settings
e, // access events
Quiz = {

    /**
     * Setting contain variables for easy access
     * @type {Object}
     */
    settings: {
        points: 0,                                      // How many right answeres user has
        answeredQuestions: [],                          // All the questions user has answerd and what he answered
        quizContainer: $('.quiz--container'),            // Selector for the quiz container
        alertContainer: $('.quiz--alerts'),              // Selector for alert container
        questionView: $('#question-template').html(),   // QuestionView Template
        finishedView: $('#quiz-finished').html(),       // FinishedView Template
        errorView: $('#quiz-error-template').html()     // ErrorView Template
    },

    /**
     * Initializes the quiz
     * @return {void} Returns nothing
     */
    init: function(username) {
        s = this.settings;
        e = this.events;
        s.username = username;
        this.bindKeys();

        this.update();
    },

    /**
     * Updates for new question or game finished
     * @return {void} Returns nothng
     */
    update: function() {
        localStorage.setItem(s.username, JSON.stringify(s.answeredQuestions));

        document.addEventListener('keydown', this.events.bindKeys);

        if (Quiz.questions.length !== s.answeredQuestions.length) {

            // Gets random question and displays it to the user
            var context;
            do {
                // returns random question
                context = this.questions[Math.floor(Math.random() * this.questions.length)];
            } while (Quiz.isAnswered(context.id, s.answeredQuestions)); // Checks if question has been answered

            // Loads the template
            this.template(s.questionView, context, s.quizContainer);

            // Adds the function for user to answer the question
            //this.bindUIActions();

            this.currentQuestion = context;
            document.getElementById('next-question').addEventListener('click', e.nxt, false);

        }
        else {
            // Returns finish view with information
           Quiz.finished();
        }

    },

    /**
     * Function for template engine
     * @param  {id}     inputSource  Where the template is located
     * @param  {object} inputContext What should be set into template variables
     * @param  {string} outputHtml   Where should the template be exported
     * @return {[void]}              Returns nothing
     */
    template: function (inputSource, inputContext, outputHtml) {
        var source = inputSource; // Gets the quiz view
        var template = Handlebars.compile(source); // Compiles the view
        var context = inputContext; // Gets random question and displays it to the user
        outputHtml.html(template(context)); // Appends the view to the index
    },

    /**
     * Checks if the question has already been answered
     * @param  {int}        needle   Question id
     * @param  {array}      heystack Where should the function look
     * @return {Boolean}
     */
    isAnswered: function(needle, heystack) {
        var length = heystack.length;
        for (var i = 0; i < length; i++) {
            if (heystack[i][0] == needle) return true;
        }
        return false;
    },

    events: {
        nxt: function(evt) {
            evt.preventDefault();
            Quiz.nextQuestion();
        },

        prv: function(evt) {
            evt.preventDefault();
        },

        restart: function(evt) {
            evt.preventDefault();
            s.answeredQuestions = [];
            s.points = 0;

            // Updates the quiz view
            Quiz.update();
        },

        closeError: function(evt) {
            evt.preventDefault();
            Quiz.displayMessage('clear');
        },

        bindKeys: function(evt) {
            switch(evt.which) {
                case 13:
                    e.nxt(evt);
                    break;
                case 49:
                    document.getElementById('0').checked = true;
                    break;
                case 50:
                    document.getElementById('1').checked = true;
                    break;
                case 51:
                    document.getElementById('2').checked = true;
                    break;
                case 52:
                    document.getElementById('3').checked = true;
                    break;
                case 53:
                    document.getElementById('4').checked = true;
                    break;
                case 54:
                    document.getElementById('5').checked = true;
                    break;
            }
        },
    },

    checkAnswere: function() {
        var context = this.currentQuestion;

        // Gets the answere user choose
        var answerButton = $('input[name=' + context.id + ']:checked');

        //  Gets the checked radiobutton
        var answer = Number(answerButton.val());

        //  Checks if it is a number, if not user has not answered
        if (isNaN(answer) === false) {

            //  Checks how smart user is
            if (answer === context.correctAnswer) {
                s.points++;

                answerButton.next('label').addClass('rightAnswere'); // Shows the user that his answere is right
            }
            else {
                $('#'+context.correctAnswer).next().addClass('rightAnswere'); // Shows the right answere
                answerButton.next('label').addClass('wrongAnswere'); // Shows user that his answere is wrong
            }

            s.answeredQuestions.push([context.id, answer]); // Adds question and answered to array

            Quiz.displayMessage('clear'); // Clears error message if there is any
        }
        else {
            Quiz.displayMessage('Please chooce a answer!'); //  User has not answere, error displayd
        }
    },

    nextQuestion: function() {
        Quiz.checkAnswere();

        setTimeout(function() {
            Quiz.update();
        }, 1500);
    },

    bindKeys: function() {

    },

    /**
     * Displays the finished view
     * @return {void} nothing returns
     */
    finished: function() {
        s._localStorage = this.getLocalStorage();
        this.getScore();

        // Loads the right template
        this.template(s.finishedView, this, s.quizContainer);

        //  Event listener for retake quiz button
        $('#retake-quiz').click(function() {

            // Initializes answeredQuestions and points to 0
            s.answeredQuestions = [];
            s.points = 0;

            // Updates the quiz view
            Quiz.update();
        });

    },

    // Calculates total score for a user based on localstorage json string
    getScore: function() {
        var _localStorage = this.getLocalStorage(),
            _questions = this.questions,
            temp_quest,
            temp_username,
            temp_userAnsweres,
            temp_userScore;

        this.leaderboard = {};

        // Loops through each user
        for (var user in _localStorage) {
            temp_userScore = 0;
            temp_username = user;
            temp_userAnsweres = JSON.parse(_localStorage[user]);
            console.log(temp_userAnsweres);

            temp_userAnsweres.forEach(validateAnswere);
            Quiz.leaderboard[temp_username] = temp_userScore;
        }

        function validateAnswere(answere) {
            for (var question in _questions) {
                temp_quest = _questions[question];

                if (temp_quest.id === answere[0]) {
                    if (temp_quest.correctAnswer === answere[1])
                        temp_userScore++;
                }
            }
        }
    },

    getLocalStorage: function() {
        var _localStorage = {};
        for (var i = 0; i < localStorage.length; i++) {
            _localStorage[localStorage.key(i)] = localStorage.getItem(localStorage.key(i));
        }
        return _localStorage;
    },

    /**
     * Displays error message and clears them at the top of the page
     * @param  {string} errorMessage
     * @return {void}              Returns nothing
     */
    displayMessage: function(errorMessage) {
        // Gets random question and displays it to the user
        switch(errorMessage) {
            // Clears alert View
            case 'clear':
                $('.quiz-alerts').html('');
                break;

            default:
                // Loads error with errorMessage as a message
                this.template(s.errorView, { error: errorMessage}, s.alertContainer);
                document.getElementById('close').addEventListener('click', this.events.closeError);
                break;
        }
    },

    /**
     * Array of objects containing questions
     * @type {Array}
     */
    questions: [
        {
            id: 0,
            question: "What is 7 * 10",
            choices: [70, 80, 72, 32],
            correctAnswer: 0
        },
        {
            id: 1,
            question: "What is 90 / 4",
            choices: [25, 60, 22.5],
            correctAnswer: 2
        },
        {
            id: 2,
            question: "What is 54 + 65",
            choices: [112, 119, 540, 32, 115, 152],
            correctAnswer: 1
        },
        {
            id: 3,
            question: "What does this question have many possible answers?",
            choices: [1, 2, 3, 4],
            correctAnswer: 3
        },
        {
            id: 4,
            question: "What is the answer to the Ultimate Question of Life, the Universe, and Everything",
            choices: ["No one know", "The Bible", 42],
            correctAnswer: 2
        }
    ]

};

/**
 * Handlebars helper, returns how many questions are answered right / how many questions
 * @param  {string}
 * @return {string}   Concatinated points/questions
 */
Handlebars.registerHelper('finalPoints', function() {
    return s.points + '/' + Quiz.questions.length;
});
<commit_msg>Fixed close alerts and answere validation so user can't go to next question without answering the question<commit_after>/* global $:false, localStorage: false, Handlebars: false, document: false, window: false, console.log: false, setTimeout: false;*/

'use strict';
var s, // access to settings
e, // access events
Quiz = {

    /**
     * Setting contain variables for easy access
     * @type {Object}
     */
    settings: {
        points: 0,                                      // How many right answeres user has
        answeredQuestions: [],                          // All the questions user has answerd and what he answered
        quizContainer: $('.quiz--container'),            // Selector for the quiz container
        alertContainer: $('.quiz--alerts'),              // Selector for alert container
        questionView: $('#question-template').html(),   // QuestionView Template
        finishedView: $('#quiz-finished').html(),       // FinishedView Template
        errorView: $('#quiz-error-template').html()     // ErrorView Template
    },

    /**
     * Initializes the quiz
     * @return {void} Returns nothing
     */
    init: function(username) {
        s = this.settings;
        e = this.events;
        s.username = username;
        this.bindKeys();

        this.update();
    },

    /**
     * Updates for new question or game finished
     * @return {void} Returns nothng
     */
    update: function() {
        localStorage.setItem(s.username, JSON.stringify(s.answeredQuestions));

        document.addEventListener('keydown', this.events.bindKeys);

        if (Quiz.questions.length !== s.answeredQuestions.length) {

            // Gets random question and displays it to the user
            var context;
            do {
                // returns random question
                context = this.questions[Math.floor(Math.random() * this.questions.length)];
            } while (Quiz.isAnswered(context.id, s.answeredQuestions)); // Checks if question has been answered

            // Loads the template
            this.template(s.questionView, context, s.quizContainer);

            // Adds the function for user to answer the question
            //this.bindUIActions();

            this.currentQuestion = context;
            document.getElementById('next-question').addEventListener('click', e.nxt, false);

        }
        else {
            // Returns finish view with information
           Quiz.finished();
        }

    },

    /**
     * Function for template engine
     * @param  {id}     inputSource  Where the template is located
     * @param  {object} inputContext What should be set into template variables
     * @param  {string} outputHtml   Where should the template be exported
     * @return {[void]}              Returns nothing
     */
    template: function (inputSource, inputContext, outputHtml) {
        var source = inputSource; // Gets the quiz view
        var template = Handlebars.compile(source); // Compiles the view
        var context = inputContext; // Gets random question and displays it to the user
        outputHtml.html(template(context)); // Appends the view to the index
    },

    /**
     * Checks if the question has already been answered
     * @param  {int}        needle   Question id
     * @param  {array}      heystack Where should the function look
     * @return {Boolean}
     */
    isAnswered: function(needle, heystack) {
        var length = heystack.length;
        for (var i = 0; i < length; i++) {
            if (heystack[i][0] == needle) return true;
        }
        return false;
    },

    events: {
        nxt: function(evt) {
            evt.preventDefault();
            Quiz.nextQuestion();
        },

        prv: function(evt) {
            evt.preventDefault();
        },

        restart: function(evt) {
            evt.preventDefault();
            s.answeredQuestions = [];
            s.points = 0;

            // Updates the quiz view
            Quiz.update();
        },

        closeError: function(evt) {
            evt.preventDefault();
            Quiz.displayMessage('clear');
        },

        bindKeys: function(evt) {
            switch(evt.which) {
                case 13:
                    e.nxt(evt);
                    break;
                case 49:
                    document.getElementById('0').checked = true;
                    break;
                case 50:
                    document.getElementById('1').checked = true;
                    break;
                case 51:
                    document.getElementById('2').checked = true;
                    break;
                case 52:
                    document.getElementById('3').checked = true;
                    break;
                case 53:
                    document.getElementById('4').checked = true;
                    break;
                case 54:
                    document.getElementById('5').checked = true;
                    break;
            }
        },
    },

    checkAnswere: function() {
        var context = this.currentQuestion;

        // Gets the answere user choose
        var answerButton = $('input[name=' + context.id + ']:checked');

        //  Gets the checked radiobutton
        var answer = Number(answerButton.val());

        //  Checks if it is a number, if not user has not answered
        if (isNaN(answer) === false) {

            //  Checks how smart user is
            if (answer === context.correctAnswer) {
                s.points++;

                answerButton.next('label').addClass('rightAnswere'); // Shows the user that his answere is right
            }
            else {
                $('#'+context.correctAnswer).next().addClass('rightAnswere'); // Shows the right answere
                answerButton.next('label').addClass('wrongAnswere'); // Shows user that his answere is wrong
            }

            s.answeredQuestions.push([context.id, answer]); // Adds question and answered to array

            Quiz.displayMessage('clear'); // Clears error message if there is any

            setTimeout(function() {
                Quiz.update();
            }, 1500);
        }
        else {
            Quiz.displayMessage('Please chooce a answer!'); //  User has not answere, error displayd
        }
    },

    nextQuestion: function() {
        Quiz.checkAnswere();
    },

    bindKeys: function() {

    },

    /**
     * Displays the finished view
     * @return {void} nothing returns
     */
    finished: function() {
        s._localStorage = this.getLocalStorage();
        this.getScore();

        // Loads the right template
        this.template(s.finishedView, this, s.quizContainer);

        //  Event listener for retake quiz button
        $('#retake-quiz').click(function() {

            // Initializes answeredQuestions and points to 0
            s.answeredQuestions = [];
            s.points = 0;

            // Updates the quiz view
            Quiz.update();
        });

    },

    // Calculates total score for a user based on localstorage json string
    getScore: function() {
        var _localStorage = this.getLocalStorage(),
            _questions = this.questions,
            temp_quest,
            temp_username,
            temp_userAnsweres,
            temp_userScore;

        this.leaderboard = {};

        // Loops through each user
        for (var user in _localStorage) {
            temp_userScore = 0;
            temp_username = user;
            temp_userAnsweres = JSON.parse(_localStorage[user]);
            temp_userAnsweres.forEach(validateAnswere);
            Quiz.leaderboard[temp_username] = temp_userScore;
        }

        function validateAnswere(answere) {
            for (var question in _questions) {
                temp_quest = _questions[question];

                if (temp_quest.id === answere[0]) {
                    if (temp_quest.correctAnswer === answere[1])
                        temp_userScore++;
                }
            }
        }
    },

    getLocalStorage: function() {
        var _localStorage = {};
        for (var i = 0; i < localStorage.length; i++) {
            _localStorage[localStorage.key(i)] = localStorage.getItem(localStorage.key(i));
        }
        return _localStorage;
    },

    /**
     * Displays error message and clears them at the top of the page
     * @param  {string} errorMessage
     * @return {void}              Returns nothing
     */
    displayMessage: function(errorMessage) {
        // Gets random question and displays it to the user
        switch(errorMessage) {
            // Clears alert View
            case 'clear':
                $('.quiz--alerts').html('');
                break;

            default:
                // Loads error with errorMessage as a message
                this.template(s.errorView, { error: errorMessage}, s.alertContainer);
                document.getElementById('close').addEventListener('click', this.events.closeError);
                break;
        }
    },

    /**
     * Array of objects containing questions
     * @type {Array}
     */
    questions: [
        {
            id: 0,
            question: "What is 7 * 10",
            choices: [70, 80, 72, 32],
            correctAnswer: 0
        },
        {
            id: 1,
            question: "What is 90 / 4",
            choices: [25, 60, 22.5],
            correctAnswer: 2
        },
        {
            id: 2,
            question: "What is 54 + 65",
            choices: [112, 119, 540, 32, 115, 152],
            correctAnswer: 1
        },
        {
            id: 3,
            question: "What does this question have many possible answers?",
            choices: [1, 2, 3, 4],
            correctAnswer: 3
        },
        {
            id: 4,
            question: "What is the answer to the Ultimate Question of Life, the Universe, and Everything",
            choices: ["No one know", "The Bible", 42],
            correctAnswer: 2
        }
    ]

};

/**
 * Handlebars helper, returns how many questions are answered right / how many questions
 * @param  {string}
 * @return {string}   Concatinated points/questions
 */
Handlebars.registerHelper('finalPoints', function() {
    return s.points + '/' + Quiz.questions.length;
});
<|endoftext|>


<commit_before>'use strict';

// Required args: id, column, loopend, loopstart
function chess_check_column(args){
    if(args['loopstart'] > args['loopend']){
        const temp = args['loopstart'];
        args['loopstart'] = args['loopend'];
        args['loopend'] = temp;
    }

    for(let i = args['loopstart'] + 1; i < args['loopend']; i++){
        if(chess_games[args['id']]['board'][i][args['column']].length === 1){
            return true;
        }
    }
    return false;
}

// Required args: id, column, dx, dy, loopstart, loopend, row
function chess_check_diagonal(args){
    if(args['loopstart'] > args['loopend']){
        const temp = args['loopstart'];
        args['loopstart'] = args['loopend'];
        args['loopend'] = temp;
    }

    let x = args['column'];
    let y = args['row'];

    for(let i = args['loopstart'] + 1; i < args['loopend']; i++){
        x += args['dx'];
        y += args['dy'];

        if(chess_games[args['id']]['board'][y][x].length === 1){
            return true;
        }
    }

    return false;
}

// Required args: id, loopend, loopstart, row
function chess_check_row(args){
    if(args['loopstart'] > args['loopend']){
        const temp = args['loopstart'];
        args['loopstart'] = args['loopend'];
        args['loopend'] = temp;
    }

    for(let i = args['loopstart'] + 1; i < args['loopend']; i++){
        if(chess_games[args['id']]['board'][args['row']][i].length === 1){
            return true;
        }
    }
    return false;
}

// Required args: id, piece-x, piece-y, target-x, target-y
function chess_move(args){
    if(!chess_games[args['id']]){
        return false;
    }

    const validation = chess_validate(args);
    if(validation['valid']){
        const piece_x = args['piece-x'] - 1;
        const piece_y = args['piece-y'] - 1;
        const piece = chess_games[args['id']]['board'][piece_y][piece_x];

        chess_games[args['id']]['board'][piece_y][piece_x] = '';
        chess_games[args['id']]['en-passant'] = validation['en-passant'];
        if(validation['en-passant-taken']){
            chess_games[args['id']]['board'][piece_y][args['target-x'] - 1] = '';
        }
        chess_games[args['id']]['board'][args['target-y'] - 1][args['target-x'] - 1] = piece;
        chess_games[args['id']]['player'] = 1 - chess_games[args['id']]['player'];
    }
    return validation['valid'];
}

// Required args: id
function chess_new(args){
    chess_games[args['id']] = {
      'board': [
        [chess_pieces[1][3], chess_pieces[1][1], chess_pieces[1][2], chess_pieces[1][4], chess_pieces[1][5], chess_pieces[1][2], chess_pieces[1][1], chess_pieces[1][3],],
        [chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0],],
        ['', '', '', '', '', '', '', '',],
        ['', '', '', '', '', '', '', '',],
        ['', '', '', '', '', '', '', '',],
        ['', '', '', '', '', '', '', '',],
        [chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0],],
        [chess_pieces[0][3], chess_pieces[0][1], chess_pieces[0][2], chess_pieces[0][4], chess_pieces[0][5], chess_pieces[0][2], chess_pieces[0][1], chess_pieces[0][3],],
      ],
      'en-passant': -1,
      'en-passant-taken': false,
      'player': 0,
    };
}

// Required args: id, piece-x, piece-y, target-x, target-y
function chess_validate(args){
    let en_passant = -1;
    let en_passant_taken = false;
    let valid_move = true;
    const piece_x = args['piece-x'] - 1;
    const piece_y = args['piece-y'] - 1;
    const target_x = args['target-x'] - 1;
    const target_y = args['target-y'] - 1;

    if(!chess_games[args['id']]
      || piece_x < 0 || piece_x > 7
      || piece_y < 0 || piece_y > 7
      || target_x < 0 || target_x > 7
      || target_y < 0 || target_y > 7){
        valid_move = false;

    }else{
        const player = chess_games[args['id']]['player'];
        const piece = chess_games[args['id']]['board'][piece_y][piece_x];
        if(piece.length === 0 || !chess_pieces[player].includes(piece)){
            valid_move = false;

        }else{
            const target_piece = chess_games[args['id']]['board'][target_y][target_x];
            if(chess_pieces[player].includes(target_piece)){
                valid_move = false;

            }else{
                const movement_x = Math.abs(piece_x - target_x);
                const movement_y = Math.abs(piece_y - target_y);
                switch(piece){
                    // Pawn
                    case chess_pieces[player][0]: {
                        const direction = player === 0 ? -1 : 1;

                        if(target_x !== piece_x){
                            if(movement_x !== 1
                              || target_y - piece_y !== direction){
                                valid_move = false;

                            }else if(chess_games[args['id']]['en-passant'] > -1
                              && piece_y === 3 + player){
                                if(target_x !== chess_games[args['id']]['en-passant'] - 1
                                  || target_y !== 2 + (player * 3)){
                                    valid_move = false;

                                }else{
                                    en_passant_taken = true;
                                }

                            }else if(!chess_pieces[1 - player].includes(target_piece)){
                                valid_move = false;
                            }

                        }else if(target_piece.length === 0){
                            if(piece_y === 6 - (player * 5)){
                                if(target_y !== piece_y + direction
                                  && target_y !== piece_y + direction * 2){
                                    valid_move = false;

                                }else if(target_y === piece_y + direction * 2){
                                    en_passant = piece_x + 1;
                                }

                            }else if(target_y !== piece_y + direction){
                                valid_move = false;
                            }

                        }else{
                            valid_move = false;
                        }

                        break;
                    }

                    // Knight
                    case chess_pieces[player][1]: {
                        if(movement_x < 1 || movement_x > 2 || movement_y < 1 || movement_y > 2){
                            valid_move = false;

                        }else if((movement_x === 1 && movement_y !== 2)
                          || (movement_x === 2 && movement_y !== 1)){
                            valid_move = false;
                        }

                        break;
                    }

                    // Bishop
                    case chess_pieces[player][2]: {
                        if(movement_x === movement_y){
                            if(movement_y > 1 && chess_check_diagonal({
                                'column': piece_x,
                                'dx': piece_x < target_x
                                  ? 1
                                  : -1,
                                'dy': piece_y < target_y
                                  ? 1
                                  : -1,
                                'id': args['id'],
                                'loopend': target_x,
                                'loopstart': piece_x,
                                'row': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else{
                            valid_move = false;
                        }

                        break;
                    }

                    // Rook
                    case chess_pieces[player][3]: {
                        if(target_x === piece_x){
                            if(movement_y > 1 && chess_check_column({
                                'column': piece_x,
                                'id': args['id'],
                                'loopend': target_y,
                                'loopstart': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else if(target_y === piece_y){
                            if(movement_x > 1 && chess_check_row({
                                'id': args['id'],
                                'loopend': target_x,
                                'loopstart': piece_x,
                                'row': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else{
                            valid_move = false;
                        }

                        break;
                    }

                    // Queen
                    case chess_pieces[player][4]: {
                        if(movement_x === movement_y){
                            if(movement_y > 1 && chess_check_diagonal({
                                'column': piece_x,
                                'dx': piece_x < target_x
                                  ? 1
                                  : -1,
                                'dy': piece_y < target_y
                                  ? 1
                                  : -1,
                                'id': args['id'],
                                'loopend': target_x,
                                'loopstart': piece_x,
                                'row': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else if(target_x === piece_x){
                            if(movement_y > 1 && chess_check_column({
                                'column': piece_x,
                                'id': args['id'],
                                'loopend': target_y,
                                'loopstart': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else if(target_y === piece_y){
                            if(movement_x > 1 && chess_check_row({
                                'id': args['id'],
                                'loopend': target_x,
                                'loopstart': piece_x,
                                'row': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else{
                            valid_move = false;
                        }

                        break;
                    }

                    // King
                    case chess_pieces[player][5]: {
                        if(movement_x > 1 || movement_y > 1){
                            valid_move = false;
                        }

                        break;
                    }

                    default:
                        valid_move = false;
                }
            }
        }
    }

    return {
      'en-passant': en_passant,
      'en-passant-taken': en_passant_taken,
      'valid': valid_move,
    };
}

globalThis.chess_games = {};
globalThis.chess_pieces = [
  ['♙', '♘', '♗', '♖', '♕', '♔'],
  ['♟', '♞', '♝', '♜', '♛', '♚'],
];
<commit_msg>improved en passant check<commit_after>'use strict';

// Required args: id, column, loopend, loopstart
function chess_check_column(args){
    if(args['loopstart'] > args['loopend']){
        const temp = args['loopstart'];
        args['loopstart'] = args['loopend'];
        args['loopend'] = temp;
    }

    for(let i = args['loopstart'] + 1; i < args['loopend']; i++){
        if(chess_games[args['id']]['board'][i][args['column']].length === 1){
            return true;
        }
    }
    return false;
}

// Required args: id, column, dx, dy, loopstart, loopend, row
function chess_check_diagonal(args){
    if(args['loopstart'] > args['loopend']){
        const temp = args['loopstart'];
        args['loopstart'] = args['loopend'];
        args['loopend'] = temp;
    }

    let x = args['column'];
    let y = args['row'];

    for(let i = args['loopstart'] + 1; i < args['loopend']; i++){
        x += args['dx'];
        y += args['dy'];

        if(chess_games[args['id']]['board'][y][x].length === 1){
            return true;
        }
    }

    return false;
}

// Required args: id, loopend, loopstart, row
function chess_check_row(args){
    if(args['loopstart'] > args['loopend']){
        const temp = args['loopstart'];
        args['loopstart'] = args['loopend'];
        args['loopend'] = temp;
    }

    for(let i = args['loopstart'] + 1; i < args['loopend']; i++){
        if(chess_games[args['id']]['board'][args['row']][i].length === 1){
            return true;
        }
    }
    return false;
}

// Required args: id, piece-x, piece-y, target-x, target-y
function chess_move(args){
    if(!chess_games[args['id']]){
        return false;
    }

    const validation = chess_validate(args);
    if(validation['valid']){
        const piece_x = args['piece-x'] - 1;
        const piece_y = args['piece-y'] - 1;
        const piece = chess_games[args['id']]['board'][piece_y][piece_x];

        chess_games[args['id']]['board'][piece_y][piece_x] = '';
        chess_games[args['id']]['en-passant'] = validation['en-passant'];
        if(validation['en-passant-taken']){
            chess_games[args['id']]['board'][piece_y][args['target-x'] - 1] = '';
        }
        chess_games[args['id']]['board'][args['target-y'] - 1][args['target-x'] - 1] = piece;
        chess_games[args['id']]['player'] = 1 - chess_games[args['id']]['player'];
    }
    return validation['valid'];
}

// Required args: id
function chess_new(args){
    chess_games[args['id']] = {
      'board': [
        [chess_pieces[1][3], chess_pieces[1][1], chess_pieces[1][2], chess_pieces[1][4], chess_pieces[1][5], chess_pieces[1][2], chess_pieces[1][1], chess_pieces[1][3],],
        [chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0], chess_pieces[1][0],],
        ['', '', '', '', '', '', '', '',],
        ['', '', '', '', '', '', '', '',],
        ['', '', '', '', '', '', '', '',],
        ['', '', '', '', '', '', '', '',],
        [chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0], chess_pieces[0][0],],
        [chess_pieces[0][3], chess_pieces[0][1], chess_pieces[0][2], chess_pieces[0][4], chess_pieces[0][5], chess_pieces[0][2], chess_pieces[0][1], chess_pieces[0][3],],
      ],
      'en-passant': -1,
      'en-passant-taken': false,
      'player': 0,
    };
}

// Required args: id, piece-x, piece-y, target-x, target-y
function chess_validate(args){
    let en_passant = -1;
    let en_passant_taken = false;
    let valid_move = true;
    const piece_x = args['piece-x'] - 1;
    const piece_y = args['piece-y'] - 1;
    const target_x = args['target-x'] - 1;
    const target_y = args['target-y'] - 1;

    if(!chess_games[args['id']]
      || piece_x < 0 || piece_x > 7
      || piece_y < 0 || piece_y > 7
      || target_x < 0 || target_x > 7
      || target_y < 0 || target_y > 7){
        valid_move = false;

    }else{
        const player = chess_games[args['id']]['player'];
        const piece = chess_games[args['id']]['board'][piece_y][piece_x];
        if(piece.length === 0 || !chess_pieces[player].includes(piece)){
            valid_move = false;

        }else{
            const target_piece = chess_games[args['id']]['board'][target_y][target_x];
            if(chess_pieces[player].includes(target_piece)){
                valid_move = false;

            }else{
                const movement_x = Math.abs(piece_x - target_x);
                const movement_y = Math.abs(piece_y - target_y);
                switch(piece){
                    // Pawn
                    case chess_pieces[player][0]: {
                        const direction = player === 0 ? -1 : 1;

                        if(target_x !== piece_x){
                            if(movement_x !== 1
                              || target_y - piece_y !== direction){
                                valid_move = false;

                            }else if(chess_games[args['id']]['en-passant'] > -1
                              && target_x === chess_games[args['id']]['en-passant'] - 1
                              && target_y === 2 + (player * 3)){
                                en_passant_taken = true;

                            }else if(!chess_pieces[1 - player].includes(target_piece)){
                                valid_move = false;
                            }

                        }else if(target_piece.length === 0){
                            if(piece_y === 6 - (player * 5)){
                                if(target_y !== piece_y + direction
                                  && target_y !== piece_y + direction * 2){
                                    valid_move = false;

                                }else if(target_y === piece_y + direction * 2){
                                    en_passant = piece_x + 1;
                                }

                            }else if(target_y !== piece_y + direction){
                                valid_move = false;
                            }

                        }else{
                            valid_move = false;
                        }

                        break;
                    }

                    // Knight
                    case chess_pieces[player][1]: {
                        if(movement_x < 1 || movement_x > 2 || movement_y < 1 || movement_y > 2){
                            valid_move = false;

                        }else if((movement_x === 1 && movement_y !== 2)
                          || (movement_x === 2 && movement_y !== 1)){
                            valid_move = false;
                        }

                        break;
                    }

                    // Bishop
                    case chess_pieces[player][2]: {
                        if(movement_x === movement_y){
                            if(movement_y > 1 && chess_check_diagonal({
                                'column': piece_x,
                                'dx': piece_x < target_x
                                  ? 1
                                  : -1,
                                'dy': piece_y < target_y
                                  ? 1
                                  : -1,
                                'id': args['id'],
                                'loopend': target_x,
                                'loopstart': piece_x,
                                'row': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else{
                            valid_move = false;
                        }

                        break;
                    }

                    // Rook
                    case chess_pieces[player][3]: {
                        if(target_x === piece_x){
                            if(movement_y > 1 && chess_check_column({
                                'column': piece_x,
                                'id': args['id'],
                                'loopend': target_y,
                                'loopstart': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else if(target_y === piece_y){
                            if(movement_x > 1 && chess_check_row({
                                'id': args['id'],
                                'loopend': target_x,
                                'loopstart': piece_x,
                                'row': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else{
                            valid_move = false;
                        }

                        break;
                    }

                    // Queen
                    case chess_pieces[player][4]: {
                        if(movement_x === movement_y){
                            if(movement_y > 1 && chess_check_diagonal({
                                'column': piece_x,
                                'dx': piece_x < target_x
                                  ? 1
                                  : -1,
                                'dy': piece_y < target_y
                                  ? 1
                                  : -1,
                                'id': args['id'],
                                'loopend': target_x,
                                'loopstart': piece_x,
                                'row': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else if(target_x === piece_x){
                            if(movement_y > 1 && chess_check_column({
                                'column': piece_x,
                                'id': args['id'],
                                'loopend': target_y,
                                'loopstart': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else if(target_y === piece_y){
                            if(movement_x > 1 && chess_check_row({
                                'id': args['id'],
                                'loopend': target_x,
                                'loopstart': piece_x,
                                'row': piece_y,
                              })){
                                valid_move = false;
                            }

                        }else{
                            valid_move = false;
                        }

                        break;
                    }

                    // King
                    case chess_pieces[player][5]: {
                        if(movement_x > 1 || movement_y > 1){
                            valid_move = false;
                        }

                        break;
                    }

                    default:
                        valid_move = false;
                }
            }
        }
    }

    return {
      'en-passant': en_passant,
      'en-passant-taken': en_passant_taken,
      'valid': valid_move,
    };
}

globalThis.chess_games = {};
globalThis.chess_pieces = [
  ['♙', '♘', '♗', '♖', '♕', '♔'],
  ['♟', '♞', '♝', '♜', '♛', '♚'],
];
<|endoftext|>


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

  angular.module('foundation.modal', ['foundation.core'])
    .directive('zfModal', modalDirective)
    .factory('ModalFactory', ModalFactory)
  ;

  FoundationModal.$inject = ['FoundationApi', 'ModalFactory'];

  function FoundationModal(foundationApi, ModalFactory) {
    var service    = {};

    service.activate = activate;
    service.deactivate = deactivate;
    service.newModal = newModal;

    return service;

    //target should be element ID
    function activate(target) {
      foundationApi.publish(target, 'show');
    }

    //target should be element ID
    function deactivate(target) {
      foundationApi.publish(target, 'hide');
    }

    //new modal has to be controlled via the new instance
    function newModal(config) {
      return new ModalFactory(config);
    }
  }

  modalDirective.$inject = ['FoundationApi'];

  function modalDirective(foundationApi) {

    var directive = {
      restrict: 'EA',
      templateUrl: 'components/modal/modal.html',
      transclude: true,
      scope: true,
      replace: true,
      compile: compile
    };

    return directive;

    function compile(tElement, tAttrs, transclude) {
      var type = 'modal';

      return {
        pre: preLink,
        post: postLink
      };

      function preLink(scope, iElement, iAttrs, controller) {
          iAttrs.$set('zf-closable', type);
      }

      function postLink(scope, element, attrs) {
        var dialog = angular.element(element.children()[0]);

        scope.active = scope.active || false;
        scope.overlay = attrs.overlay === 'false' ? false : true;
        scope.overlayClose = attrs.overlayClose === 'false' ? false : true;

        var animationIn = attrs.animationIn || 'fadeIn';
        var animationOut = attrs.animationOut || 'fadeOut';

        var overlayIn = 'fadeIn';
        var overlayOut = 'fadeOut';

        scope.hideOverlay = function() {
          if(scope.overlayClose) {
            scope.hide();
          }
        };

        scope.hide = function() {
          scope.active = false;
          animate();
          return;
        };

        scope.show = function() {
          scope.active = true;
          animate();
          dialog.tabIndex = -1;
          dialog[0].focus();
          return;
        };

        scope.toggle = function() {
          scope.active = !scope.active;
          animate();
          return;
        };

        init();

        //setup
        foundationApi.subscribe(attrs.id, function(msg) {
          if(msg === 'show' || msg === 'open') {
            scope.show();
          } else if (msg === 'close' || msg === 'hide') {
            scope.hide();
          } else if (msg === 'toggle') {
            scope.toggle();
          }

          if (scope.$root && !scope.$root.$$phase) {
            scope.$apply();
          }

          return;
        });

        function animate() {
          //animate both overlay and dialog
          if(!scope.overlay) {
            element.css('background', 'transparent');
          }

          foundationApi.animate(element, scope.active, overlayIn, overlayOut);
          foundationApi.animate(dialog, scope.active, animationIn, animationOut);
        }

        function init() {
          if(scope.active) {
            scope.show();
          }
        }
      }
    }
  }

  ModalFactory.$inject = ['$http', '$templateCache', '$rootScope', '$compile', '$timeout', '$q', 'FoundationApi'];

  function ModalFactory($http, $templateCache, $rootScope, $compile, $timeout, $q, foundationApi) {
    return modalFactory;

    function modalFactory(config) {
      var self = this, //for prototype functions
          container = angular.element(config.container || document.body),
          id = config.id || foundationApi.generateUuid(),
          attached = false,
          destroyed = false,
          html,
          element,
          fetched,
          scope,
          contentScope
      ;

      var props = [
        'animationIn',
        'animationOut',
        'overlay',
        'overlayClose'
      ];

      if(config.templateUrl) {
        //get template
        fetched = $http.get(config.templateUrl, {
          cache: $templateCache
        }).then(function (response) {
          html = response.data;
          assembleDirective();
        });

      } else if(config.template) {
        //use provided template
        fetched = true;
        html = config.template;
        assembleDirective();
      }

      self.activate = activate;
      self.deactivate = deactivate;
      self.toggle = toggle;
      self.destroy = destroy;

      return {
        activate: activate,
        deactivate: deactivate,
        toggle: toggle,
        destroy: destroy
      };

      function checkStatus() {
        if(destroyed) {
          throw "Error: Modal was destroyed. Delete the object and create a new ModalFactory instance."
        }
      }

      function activate() {
        checkStatus();
        $timeout(function() {
          init(true);
          foundationApi.publish(id, 'show');
        }, 0, false);
      }

      function deactivate() {
        checkStatus();
        $timeout(function() {
          init(false);
          foundationApi.publish(id, 'hide');
        }, 0, false);
      }

      function toggle() {
        checkStatus();
        $timeout(function() {
          init(true);
          foundationApi.publish(id, 'toggle');
        }, 0, false);
      }

      function init(state) {
        $q.when(fetched).then(function() {
          if(!attached && html.length > 0) {
            var modalEl = container.append(element);

            scope.active = state;
            $compile(element)(scope);

            attached = true;
          }
        });
      }

      function assembleDirective() {
        // check for duplicate elements to prevent factory from cloning modals
        if (document.getElementById(id)) {
          return;
        }

        html = '<zf-modal id="' + id + '">' + html + '</zf-modal>';

        element = angular.element(html);

        scope = $rootScope.$new();

        // account for directive attributes
        for(var i = 0; i < props.length; i++) {
          var prop = props[i];

          if(config[prop]) {
            switch (prop) {
              case 'animationIn':
                element.attr('animation-in', config[prop]);
                break;
              case 'animationOut':
                element.attr('animation-out', config[prop]);
                break;
              default:
                element.attr(prop, config[prop]);
            }
          }
        }
        // access view scope variables
        if (config.contentScope) {
          contentScope = config.contentScope;
          for (var prop in config.contentScope) {
            if (config.contentScope.hasOwnProperty(prop)) {
              scope[prop] = config.contentScope[prop];
            }
          }
        }
      }

      function destroy() {
        self.deactivate();
        setTimeout(function() {
          scope.$destroy();
          element.remove();
          destroyed = true;
        }, 3000);
        foundationApi.unsubscribe(id);
      }

    }

  }

})();
<commit_msg>Added FoundationModal service to foundation.modal module<commit_after>(function() {
  'use strict';

  angular.module('foundation.modal', ['foundation.core'])
    .directive('zfModal', modalDirective)
    .factory('ModalFactory', ModalFactory)
    .service('FoundationModal', FoundationModal)
  ;

  FoundationModal.$inject = ['FoundationApi', 'ModalFactory'];

  function FoundationModal(foundationApi, ModalFactory) {
    var service    = {};

    service.activate = activate;
    service.deactivate = deactivate;
    service.newModal = newModal;

    return service;

    //target should be element ID
    function activate(target) {
      foundationApi.publish(target, 'show');
    }

    //target should be element ID
    function deactivate(target) {
      foundationApi.publish(target, 'hide');
    }

    //new modal has to be controlled via the new instance
    function newModal(config) {
      return new ModalFactory(config);
    }
  }

  modalDirective.$inject = ['FoundationApi'];

  function modalDirective(foundationApi) {

    var directive = {
      restrict: 'EA',
      templateUrl: 'components/modal/modal.html',
      transclude: true,
      scope: true,
      replace: true,
      compile: compile
    };

    return directive;

    function compile(tElement, tAttrs, transclude) {
      var type = 'modal';

      return {
        pre: preLink,
        post: postLink
      };

      function preLink(scope, iElement, iAttrs, controller) {
          iAttrs.$set('zf-closable', type);
      }

      function postLink(scope, element, attrs) {
        var dialog = angular.element(element.children()[0]);

        scope.active = scope.active || false;
        scope.overlay = attrs.overlay === 'false' ? false : true;
        scope.overlayClose = attrs.overlayClose === 'false' ? false : true;

        var animationIn = attrs.animationIn || 'fadeIn';
        var animationOut = attrs.animationOut || 'fadeOut';

        var overlayIn = 'fadeIn';
        var overlayOut = 'fadeOut';

        scope.hideOverlay = function() {
          if(scope.overlayClose) {
            scope.hide();
          }
        };

        scope.hide = function() {
          scope.active = false;
          animate();
          return;
        };

        scope.show = function() {
          scope.active = true;
          animate();
          dialog.tabIndex = -1;
          dialog[0].focus();
          return;
        };

        scope.toggle = function() {
          scope.active = !scope.active;
          animate();
          return;
        };

        init();

        //setup
        foundationApi.subscribe(attrs.id, function(msg) {
          if(msg === 'show' || msg === 'open') {
            scope.show();
          } else if (msg === 'close' || msg === 'hide') {
            scope.hide();
          } else if (msg === 'toggle') {
            scope.toggle();
          }

          if (scope.$root && !scope.$root.$$phase) {
            scope.$apply();
          }

          return;
        });

        function animate() {
          //animate both overlay and dialog
          if(!scope.overlay) {
            element.css('background', 'transparent');
          }

          foundationApi.animate(element, scope.active, overlayIn, overlayOut);
          foundationApi.animate(dialog, scope.active, animationIn, animationOut);
        }

        function init() {
          if(scope.active) {
            scope.show();
          }
        }
      }
    }
  }

  ModalFactory.$inject = ['$http', '$templateCache', '$rootScope', '$compile', '$timeout', '$q', 'FoundationApi'];

  function ModalFactory($http, $templateCache, $rootScope, $compile, $timeout, $q, foundationApi) {
    return modalFactory;

    function modalFactory(config) {
      var self = this, //for prototype functions
          container = angular.element(config.container || document.body),
          id = config.id || foundationApi.generateUuid(),
          attached = false,
          destroyed = false,
          html,
          element,
          fetched,
          scope,
          contentScope
      ;

      var props = [
        'animationIn',
        'animationOut',
        'overlay',
        'overlayClose'
      ];

      if(config.templateUrl) {
        //get template
        fetched = $http.get(config.templateUrl, {
          cache: $templateCache
        }).then(function (response) {
          html = response.data;
          assembleDirective();
        });

      } else if(config.template) {
        //use provided template
        fetched = true;
        html = config.template;
        assembleDirective();
      }

      self.activate = activate;
      self.deactivate = deactivate;
      self.toggle = toggle;
      self.destroy = destroy;

      return {
        activate: activate,
        deactivate: deactivate,
        toggle: toggle,
        destroy: destroy
      };

      function checkStatus() {
        if(destroyed) {
          throw "Error: Modal was destroyed. Delete the object and create a new ModalFactory instance."
        }
      }

      function activate() {
        checkStatus();
        $timeout(function() {
          init(true);
          foundationApi.publish(id, 'show');
        }, 0, false);
      }

      function deactivate() {
        checkStatus();
        $timeout(function() {
          init(false);
          foundationApi.publish(id, 'hide');
        }, 0, false);
      }

      function toggle() {
        checkStatus();
        $timeout(function() {
          init(true);
          foundationApi.publish(id, 'toggle');
        }, 0, false);
      }

      function init(state) {
        $q.when(fetched).then(function() {
          if(!attached && html.length > 0) {
            var modalEl = container.append(element);

            scope.active = state;
            $compile(element)(scope);

            attached = true;
          }
        });
      }

      function assembleDirective() {
        // check for duplicate elements to prevent factory from cloning modals
        if (document.getElementById(id)) {
          return;
        }

        html = '<zf-modal id="' + id + '">' + html + '</zf-modal>';

        element = angular.element(html);

        scope = $rootScope.$new();

        // account for directive attributes
        for(var i = 0; i < props.length; i++) {
          var prop = props[i];

          if(config[prop]) {
            switch (prop) {
              case 'animationIn':
                element.attr('animation-in', config[prop]);
                break;
              case 'animationOut':
                element.attr('animation-out', config[prop]);
                break;
              default:
                element.attr(prop, config[prop]);
            }
          }
        }
        // access view scope variables
        if (config.contentScope) {
          contentScope = config.contentScope;
          for (var prop in config.contentScope) {
            if (config.contentScope.hasOwnProperty(prop)) {
              scope[prop] = config.contentScope[prop];
            }
          }
        }
      }

      function destroy() {
        self.deactivate();
        setTimeout(function() {
          scope.$destroy();
          element.remove();
          destroyed = true;
        }, 3000);
        foundationApi.unsubscribe(id);
      }

    }

  }

})();
<|endoftext|>