<commit_before>'use strict';
const _ = require('lodash');
const utils = require('../../utils.js');

module.exports = function(AngularATGenerator) {

    AngularATGenerator.prototype.copyCopmFiles = function copyFiles() {
        // setting defaults, component name and path settings
        let fullPath = this.props.componentName;
        let pathAsArray = fullPath.split('/');
        let componentName = pathAsArray[pathAsArray.length - 1];
        let parentName = null;
        let parentPath = null;
        let isDuplicate = false;
        // data to be passed to templates and used to get info
        const data = {
            'componentName': componentName,
            'componentNameCamel': _.camelCase(componentName),
            'controllerName': _.upperFirst(_.camelCase(componentName)),
            'componentModule': _.camelCase(componentName)
        };
        //if the component has no parent
        if (pathAsArray.length === 1) {
          try {
            const indexModulesWriteLine = "require('./components/" + data.componentName + "/" + data.componentName + ".module').name,";
            utils.addToFile('index.components.js', indexModulesWriteLine, utils.COMPONENT_MARKER, this.destinationRoot() + '/src/app');
          } catch (err) {
              this.log('Could not generate this item due to missing file structure.');
              return;
          }
        } else {
            //if the component is nested in a parent component
            parentName = pathAsArray[pathAsArray.length - 2];
            // if single parent, join by '/' else join by '/components/' to nest within the parent components
            const joinString = (pathAsArray.length>2)?'/components/':'/';
            parentPath = _.join(pathAsArray.slice(0, pathAsArray.length - 1), joinString);
            fullPath = parentPath + '/components/' + data.componentName;
            // importing files to parent component
            try {
                //module
                const moduleImport = "import * as " + data.componentModule + " from './components/" + componentName + '/' + componentName + ".module';";
                utils.addToFile(parentName + '.module.js', moduleImport, utils.IMPORT_MODULE_MARKER, this.destinationRoot() + '/src/app/components/' + parentPath);
                //dependency
                const dependencyImport = "'" + data.componentModule + "',";
                utils.addToFile(parentName + '.module.js', dependencyImport, utils.IMPORT_DEPENDENCY_MARKER, this.destinationRoot() + '/src/app/components/' + parentPath);
            } catch (err) {
                this.log('Parent component files not found.');
                return;
            }
        }

        // checking if the module exists, if so it is a duplicate
        isDuplicate = utils.existsSync(this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.module.js'));

        // copy template files, no need for try and catch since file structure already exists from above
        this.fs.copyTpl(this.templatePath('_component.html'), this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.component.html'), data);
        this.fs.copyTpl(this.templatePath('_component.scss'), this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.component.scss'), data);
        this.fs.copyTpl(this.templatePath('_component.module.js'), this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.module.js'), data);
        this.fs.copyTpl(this.templatePath('_component.component.js'), this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.component' + '.js'), data);
        this.fs.copyTpl(this.templatePath('_component.component-spec.js'), this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.component-spec' + '.js'), data);

        // Documenting the creation of the component
        if(!isDuplicate){
          try{
            const nestedLineMarkExtensionForDocs = " for "+fullPath;
            const descriptionForDocs = (this.props.description && this.props.description.length>0)?this.props.description:data.componentName + " component";
            const componentDocJSONString = '{\n\t\t"name": "' + data.componentName + '", "path": "' + this.props.componentName + '",\n\t\t"components": [\n\t\t\t'+utils.COMPONENT_NESTED_MARKER+nestedLineMarkExtensionForDocs+'\n\t\t],\n\t\t"directives": [\n\t\t\t'+utils.DIRECTIVE_NESTED_MARKER+nestedLineMarkExtensionForDocs+'\n\t\t],\n\t\t"services": [\n\t\t\t'+utils.SERVICE_NESTED_MARKER+nestedLineMarkExtensionForDocs+'\n\t\t],\n\t\t"description": "'+ descriptionForDocs + ' component"\n\t\t},'
            // extending the nested Line marker with information about the component in order to insert there later
            utils.addToFile(utils.DOCS_STORAGE_FILENAME, componentDocJSONString, utils.COMPONENT_MARKER, this.destinationRoot() + utils.DOCS_ASSETS_PATH);
            // if the component has a parent, Link it to its parent
            if (pathAsArray.length !== 1) {
              const nestedLineMarkExtensionOfParent = " for "+parentPath;
              // Foreign Key String for component is injected into the parent component
              const componentDocForeignKeyJSONString = '{"path": "' + this.props.componentName + '", "name": "' + data.componentName + '"},';
              utils.addToFile(utils.DOCS_STORAGE_FILENAME, componentDocForeignKeyJSONString, utils.COMPONENT_NESTED_MARKER+nestedLineMarkExtensionOfParent, this.destinationRoot() + utils.DOCS_ASSETS_PATH);
            }
          } catch (err) {
            this.log('Could not document this item due to missing documentation file.');
          }
        }
    };
};
<commit_msg>component new docs<commit_after>'use strict';
const _ = require('lodash');
const utils = require('../../utils.js');
const jsonfile = require('jsonfile');
const jsonQuery = require('json-query');

module.exports = function(AngularATGenerator) {

    AngularATGenerator.prototype.copyCopmFiles = function copyFiles() {
        // setting defaults, component name and path settings
        let fullPath = this.props.componentName;
        let pathAsArray = fullPath.split('/');
        let componentName = pathAsArray[pathAsArray.length - 1];
        let parentName = null;
        let parentPath = null;
        let isDuplicate = false;
        // data to be passed to templates and used to get info
        const data = {
            'componentName': componentName,
            'componentNameCamel': _.camelCase(componentName),
            'controllerName': _.upperFirst(_.camelCase(componentName)),
            'componentModule': _.camelCase(componentName)
        };
        //if the component has no parent
        if (pathAsArray.length === 1) {
          try {
            const indexModulesWriteLine = "require('./components/" + data.componentName + "/" + data.componentName + ".module').name,";
            utils.addToFile('index.components.js', indexModulesWriteLine, utils.COMPONENT_MARKER, this.destinationRoot() + '/src/app');
          } catch (err) {
              this.log('Could not generate this item due to missing file structure.');
              return;
          }
        } else {
            //if the component is nested in a parent component
            parentName = pathAsArray[pathAsArray.length - 2];
            // if single parent, join by '/' else join by '/components/' to nest within the parent components
            const joinString = (pathAsArray.length>2)?'/components/':'/';
            parentPath = _.join(pathAsArray.slice(0, pathAsArray.length - 1), joinString);
            fullPath = parentPath + '/components/' + data.componentName;
            // importing files to parent component
            try {
                //module
                const moduleImport = "import * as " + data.componentModule + " from './components/" + componentName + '/' + componentName + ".module';";
                utils.addToFile(parentName + '.module.js', moduleImport, utils.IMPORT_MODULE_MARKER, this.destinationRoot() + '/src/app/components/' + parentPath);
                //dependency
                const dependencyImport = "'" + data.componentModule + "',";
                utils.addToFile(parentName + '.module.js', dependencyImport, utils.IMPORT_DEPENDENCY_MARKER, this.destinationRoot() + '/src/app/components/' + parentPath);
            } catch (err) {
                this.log('Parent component files not found.');
                return;
            }
        }

        // checking if the module exists, if so it is a duplicate
        isDuplicate = utils.existsSync(this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.module.js'));

        // copy template files, no need for try and catch since file structure already exists from above
        this.fs.copyTpl(this.templatePath('_component.html'), this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.component.html'), data);
        this.fs.copyTpl(this.templatePath('_component.scss'), this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.component.scss'), data);
        this.fs.copyTpl(this.templatePath('_component.module.js'), this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.module.js'), data);
        this.fs.copyTpl(this.templatePath('_component.component.js'), this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.component' + '.js'), data);
        this.fs.copyTpl(this.templatePath('_component.component-spec.js'), this.destinationPath(this.destinationRoot() + '/src/app/components/' + fullPath + '/' + data.componentName + '.component-spec' + '.js'), data);

        // Documenting the creation of the component
        if (!isDuplicate) {
          const file = this.destinationPath(this.destinationRoot() + '/docs/docs-assets/docs.json');
          jsonfile.readFile(file, function(err, docsJSON) {
            if (err) {
              this.log('Could not document this item due to missing or corrupted documentation file.');
              return;
            }
            const descriptionForDocs = (this.props.description && this.props.description.length>0)?this.props.description:data.componentName + " component";

            const componentDocJSON = {
              "name": data.componentName,
              "path": this.props.componentName,
              "components": [],
              "directives": [],
              "services": [],
              "description": descriptionForDocs
            };
            docsJSON.components.push(componentDocJSON);
            if (pathAsArray.length !== 1) {
              // Foreign Key String for component is injected into the parent component
              const componentDocForeignKeyJSON = {
                "path": this.props.componentName,
                "name": data.componentName
              };
              docsJSON.components[jsonQuery('components[path=' + pathAsArray.slice(0, -1).join('/') + ']', {data: docsJSON}).key].components.push(componentDocForeignKeyJSON);
            }
            jsonfile.writeFile(file, docsJSON, function(err) {}.bind(this));
          }.bind(this));
        }
    };
};
<|endoftext|>


<commit_before>const net = require('net')
const createRequest = require('./protocol/request')
const Encoder = require('./protocol/encoder')
const Decoder = require('./protocol/decoder')
const createRetry = require('./retry')

const processData = pendingQueue => data => {
  const decoder = new Decoder(data)
  const size = decoder.readInt32()
  const correlationId = decoder.readInt32()
  const payload = decoder.readAll()

  const entry = pendingQueue[correlationId]
  delete pendingQueue[correlationId]

  if (!entry) {
    this.logger.debug(`Response without match`, { correlationId })
    return
  }

  entry.resolve({
    correlationId,
    size,
    entry,
    payload,
  })
}

module.exports = class Connection {
  constructor({ host, port, logger, retry = {} }) {
    this.host = host
    this.port = port
    this.logger = logger
    this.retrier = createRetry(retry)

    this.connected = false
    this.correlationId = 0
    this.pendingQueue = {}
  }

  nextCorrelationId() {
    if (this.correlationId === Number.MAX_VALUE) {
      this.correlationId = 0
    }

    return this.correlationId++
  }

  connect() {
    return new Promise((resolve, reject) => {
      this.socket = net.connect({ host: this.host, port: this.port }, () => {
        this.connected = true
        resolve()
      })

      this.socket.on('data', processData(this.pendingQueue))
      this.socket.on('end', () => {
        this.logger.error('Kafka server has closed connection')
        this.disconnect()
      })

      this.socket.on('error', e => {
        this.logger.error(`Connection error`, { error: e.message })
        reject(e)
        this.disconnect()
      })
    })
  }

  disconnect() {
    this.logger.debug('disconnecting...')
    this.connected && this.socket.end()
    this.connected = false
    this.logger.debug('disconnected')
  }

  send({ request, response }) {
    const sendRequest = async () => {
      const correlationId = this.nextCorrelationId()

      this.logger.debug(
        `Request ${request.apiName}(key: ${request.apiKey}, version: ${request.apiVersion})`,
        { correlationId }
      )

      const encoder = new Encoder()
      const requestPayload = createRequest({
        request,
        correlationId,
        clientId: 'abc',
      })

      return new Promise(resolve => {
        this.pendingQueue[correlationId] = {
          apiKey: request.apiKey,
          apiName: request.apiName,
          apiVersion: request.apiVersion,
          resolve,
        }
        this.socket.write(requestPayload.buffer, 'binary')
      })
    }

    return this.retrier(async (bail, retryCount, retryTime) => {
      const { correlationId, size, entry, payload } = await sendRequest()
      try {
        const data = response.parse(response.decode(payload))

        this.logger.debug(
          `Response ${entry.apiName}(key: ${entry.apiKey}, version: ${entry.apiVersion})`,
          { correlationId, size }
        )

        return data
      } catch (e) {
        this.logger.error(
          `Response ${entry.apiName}(key: ${entry.apiKey}, version: ${entry.apiVersion}) error`,
          Object.assign({ correlationId, retryCount, retryTime, size, error: e.message }, e)
        )

        if (e.retriable) throw e
        bail(e)
      }
    })
  }
}
<commit_msg>Add the broker information in the connection log<commit_after>const net = require('net')
const createRequest = require('./protocol/request')
const Encoder = require('./protocol/encoder')
const Decoder = require('./protocol/decoder')
const createRetry = require('./retry')

const processData = pendingQueue => data => {
  const decoder = new Decoder(data)
  const size = decoder.readInt32()
  const correlationId = decoder.readInt32()
  const payload = decoder.readAll()

  const entry = pendingQueue[correlationId]
  delete pendingQueue[correlationId]

  if (!entry) {
    this.logger.debug(`Response without match`, { correlationId })
    return
  }

  entry.resolve({
    correlationId,
    size,
    entry,
    payload,
  })
}

module.exports = class Connection {
  constructor({ host, port, logger, retry = {} }) {
    this.host = host
    this.port = port
    this.logger = logger
    this.retrier = createRetry(retry)
    this.broker = `${host}:${port}`

    this.connected = false
    this.correlationId = 0
    this.pendingQueue = {}
  }

  nextCorrelationId() {
    if (this.correlationId === Number.MAX_VALUE) {
      this.correlationId = 0
    }

    return this.correlationId++
  }

  connect() {
    return new Promise((resolve, reject) => {
      this.logger.debug(`Connecting`, { broker: this.broker })
      this.socket = net.connect({ host: this.host, port: this.port }, () => {
        this.connected = true
        resolve()
      })

      this.socket.on('data', processData(this.pendingQueue))
      this.socket.on('end', () => {
        this.logger.error('Kafka server has closed connection', { broker: this.broker })
        this.connected = false
      })

      this.socket.on('error', e => {
        this.logger.error(`Connection error`, { broker: this.broker, error: e.message })
        reject(e)
        this.disconnect()
      })
    })
  }

  disconnect() {
    if (this.connected) {
      this.logger.debug('disconnecting...', { broker: this.broker })
      this.socket.end()
      this.connected = false
    }

    this.logger.debug('disconnected', { broker: this.broker })
  }

  send({ request, response }) {
    const sendRequest = async () => {
      const correlationId = this.nextCorrelationId()

      this.logger.debug(
        `Request ${request.apiName}(key: ${request.apiKey}, version: ${request.apiVersion})`,
        { broker: this.broker, correlationId }
      )

      const encoder = new Encoder()
      const requestPayload = createRequest({
        request,
        correlationId,
        clientId: 'abc',
      })

      return new Promise(resolve => {
        this.pendingQueue[correlationId] = {
          apiKey: request.apiKey,
          apiName: request.apiName,
          apiVersion: request.apiVersion,
          resolve,
        }
        this.socket.write(requestPayload.buffer, 'binary')
      })
    }

    return this.retrier(async (bail, retryCount, retryTime) => {
      const { correlationId, size, entry, payload } = await sendRequest()
      try {
        const data = response.parse(response.decode(payload))

        this.logger.debug(
          `Response ${entry.apiName}(key: ${entry.apiKey}, version: ${entry.apiVersion})`,
          { broker: this.broker, correlationId, size, data }
        )

        return data
      } catch (e) {
        this.logger.error(
          `Response ${entry.apiName}(key: ${entry.apiKey}, version: ${entry.apiVersion}) error`,
          Object.assign(
            {
              broker: this.broker,
              correlationId,
              retryCount,
              retryTime,
              size,
              error: e.message,
            },
            e
          )
        )

        if (e.retriable) throw e
        bail(e)
      }
    })
  }
}
<|endoftext|>


<commit_before>var EventEmitter    = require('eventemitter3');
var _               = require('lodash');
var ircLineParser   = require('./irclineparser');

function Connection(options) {
    EventEmitter.call(this);

    this.options = options || {};

    this.connected = false;
    this.requested_disconnect = false;

    this.auto_reconnect = options.auto_reconnect || false;
    this.auto_reconnect_wait = options.auto_reconnect_wait || 4000;
    this.auto_reconnect_max_retries = options.auto_reconnect_max_retries || 3;
    this.reconnect_attempts = 0;

    // When an IRC connection was successfully registered.
    this.registered = false;

    this.read_buffer = [];
    this.reading_buffer = false;

    this.read_command_buffer = [];

    this.transport = null;

    this._timers = [];
}

_.extend(Connection.prototype, EventEmitter.prototype);

module.exports = Connection;

Connection.prototype.debugOut = function(out) {
    this.emit('debug', out);
};

Connection.prototype.registeredSuccessfully = function() {
    this.registered = Date.now();
};

Connection.prototype.connect = function(options) {
    var that = this;
    var transport;

    if (options) {
        this.options = options;
    }

    options = this.options;
    transport = this.transport = new options.transport(options);

    if (!options.encoding || !this.setEncoding(options.encoding)) {
        this.setEncoding('utf8');
    }

    // Some transports may emit extra events
    transport.on('extra', function(/*event_name, argN*/) {
        that.emit.apply(that, arguments);
    });

    transport.on('open', socketOpen);
    transport.on('line', socketLine);
    transport.on('close', socketClose);
    transport.on('debug', function (out) {
        that.debugOut(out);
    });

    transport.connect();

    // Called when the socket is connected and ready to start sending/receiving data.
    function socketOpen() {
        that.debugOut('Socket fully connected');
        that.reconnect_attempts = 0;
        that.connected = true;
        that.emit('socket connected');
    }

    function socketLine(line) {
        that.debugOut('[incoming line] ' + line);
        that.read_buffer.push(line);
        that.processReadBuffer();
    }

    function socketClose(err) {
        var was_connected = that.connected;
        var should_reconnect = false;
        var safely_registered = false;
        var registered_ms_ago = Date.now() - that.registered;

        // Some networks use aKills which kill a user after succesfully
        // registering instead of a ban, so we must wait some time after
        // being registered to be sure that we are connected properly.
        safely_registered = that.registered !== false && registered_ms_ago > 5000;

        that.debugOut('Socket closed. was_connected=' + was_connected + ' safely_registered=' + safely_registered + ' requested_disconnect='+that.requested_disconnect);

        that.connected = false;
        that.clearTimers();

        that.emit('socket close', err);

        if (that.requested_disconnect || !that.auto_reconnect) {
            should_reconnect = false;

        // If trying to reconnect, continue with it
        } else if (that.reconnect_attempts && that.reconnect_attempts < that.auto_reconnect_max_retries) {
            should_reconnect = true;

        // If we were originally connected OK, reconnect
        } else if (was_connected && safely_registered) {
            should_reconnect = true;

        } else {
            should_reconnect = false;
        }

        if (should_reconnect) {
            that.reconnect_attempts++;
            that.emit('reconnecting', {
                attempt: that.reconnect_attempts,
                max_retries: that.auto_reconnect_max_retries,
                wait: that.auto_reconnect_wait
            });
        } else {
            that.emit('close', err ? true : false);
            that.reconnect_attempts = 0;
        }

        if (should_reconnect) {
            that.debugOut('Scheduling reconnect');
            that.setTimeout(function() {
                that.connect();
            }, that.auto_reconnect_wait);
        }
    }
};

Connection.prototype.write = function(data, callback) {
    if (!this.connected || this.requested_disconnect) {
        return 0;
    }

    return this.transport.writeLine(data, callback);
};

/**
 * Create and keep track of all timers so they can be easily removed
 */
Connection.prototype.setTimeout = function(/*fn, length, argN */) {
    var that = this;
    var tmr = null;
    var callback = arguments[0];

    arguments[0] = function() {
       _.pull(that._timers, tmr);
       callback.apply(null, arguments);
    };

    tmr = setTimeout.apply(null, arguments);
    this._timers.push(tmr);
    return tmr;
};

Connection.prototype.clearTimeout = function(tmr) {
	clearTimeout(tmr);
	_.pull(this._timers, tmr);
};

Connection.prototype.clearTimers = function() {
    this._timers.forEach(function(tmr) {
        clearTimeout(tmr);
    });

    this._timers = [];
};

/**
 * Close the connection to the IRCd after forcing one last line
 */
Connection.prototype.end = function(data, callback) {
    var that = this;

    this.debugOut('Connection.end() connected=' + this.connected + ' with data=' + !!data);

    if (this.connected && data) {
        // Once the last bit of data has been sent, then re-run this function to close the socket
        this.write(data, function() {
            that.end();
        });

        return;
    }

    this.requested_disconnect = true;

    if (this.transport) {
        this.transport.close();
    }
};

Connection.prototype.setEncoding = function(encoding) {
    this.debugOut('Connection.setEncoding() encoding=' + encoding);

    if (this.transport) {
        return this.transport.setEncoding(encoding);
    }
};

/**
 * Process the buffered messages recieved from the IRCd
 * Will only process 4 lines per JS tick so that node can handle any other events while
 * handling a large buffer
 */
Connection.prototype.processReadBuffer = function(continue_processing) {
    // If we already have the read buffer being iterated through, don't start
    // another one.
    if (this.reading_buffer && !continue_processing) {
        return;
    }

    var that = this;
    var lines_per_js_tick = 4;
    var processed_lines = 0;
    var line;
    var message;

    this.reading_buffer = true;

    while (processed_lines < lines_per_js_tick && this.read_buffer.length > 0) {
        line = this.read_buffer.shift();
        if (!line) {
            continue;
        }

        message = ircLineParser(line);

        if (!message) {
            // A malformed IRC line
            continue;
        }
        this.emit('raw', line);
        this.emit('message', message);

        processed_lines++;
    }

    // If we still have items left in our buffer then continue reading them in a few ticks
    if (this.read_buffer.length > 0) {
        this.setTimeout(function() {
            that.processReadBuffer(true);
        }, 1);
    } else {
        this.reading_buffer = false;
    }
};
<commit_msg>Sent IRC lines included in the ‘raw’ event<commit_after>var EventEmitter    = require('eventemitter3');
var _               = require('lodash');
var ircLineParser   = require('./irclineparser');

function Connection(options) {
    EventEmitter.call(this);

    this.options = options || {};

    this.connected = false;
    this.requested_disconnect = false;

    this.auto_reconnect = options.auto_reconnect || false;
    this.auto_reconnect_wait = options.auto_reconnect_wait || 4000;
    this.auto_reconnect_max_retries = options.auto_reconnect_max_retries || 3;
    this.reconnect_attempts = 0;

    // When an IRC connection was successfully registered.
    this.registered = false;

    this.read_buffer = [];
    this.reading_buffer = false;

    this.read_command_buffer = [];

    this.transport = null;

    this._timers = [];
}

_.extend(Connection.prototype, EventEmitter.prototype);

module.exports = Connection;

Connection.prototype.debugOut = function(out) {
    this.emit('debug', out);
};

Connection.prototype.registeredSuccessfully = function() {
    this.registered = Date.now();
};

Connection.prototype.connect = function(options) {
    var that = this;
    var transport;

    if (options) {
        this.options = options;
    }

    options = this.options;
    transport = this.transport = new options.transport(options);

    if (!options.encoding || !this.setEncoding(options.encoding)) {
        this.setEncoding('utf8');
    }

    // Some transports may emit extra events
    transport.on('extra', function(/*event_name, argN*/) {
        that.emit.apply(that, arguments);
    });

    transport.on('open', socketOpen);
    transport.on('line', socketLine);
    transport.on('close', socketClose);
    transport.on('debug', function (out) {
        that.debugOut(out);
    });

    transport.connect();

    // Called when the socket is connected and ready to start sending/receiving data.
    function socketOpen() {
        that.debugOut('Socket fully connected');
        that.reconnect_attempts = 0;
        that.connected = true;
        that.emit('socket connected');
    }

    function socketLine(line) {
        that.debugOut('[incoming line] ' + line);
        that.read_buffer.push(line);
        that.processReadBuffer();
    }

    function socketClose(err) {
        var was_connected = that.connected;
        var should_reconnect = false;
        var safely_registered = false;
        var registered_ms_ago = Date.now() - that.registered;

        // Some networks use aKills which kill a user after succesfully
        // registering instead of a ban, so we must wait some time after
        // being registered to be sure that we are connected properly.
        safely_registered = that.registered !== false && registered_ms_ago > 5000;

        that.debugOut('Socket closed. was_connected=' + was_connected + ' safely_registered=' + safely_registered + ' requested_disconnect='+that.requested_disconnect);

        that.connected = false;
        that.clearTimers();

        that.emit('socket close', err);

        if (that.requested_disconnect || !that.auto_reconnect) {
            should_reconnect = false;

        // If trying to reconnect, continue with it
        } else if (that.reconnect_attempts && that.reconnect_attempts < that.auto_reconnect_max_retries) {
            should_reconnect = true;

        // If we were originally connected OK, reconnect
        } else if (was_connected && safely_registered) {
            should_reconnect = true;

        } else {
            should_reconnect = false;
        }

        if (should_reconnect) {
            that.reconnect_attempts++;
            that.emit('reconnecting', {
                attempt: that.reconnect_attempts,
                max_retries: that.auto_reconnect_max_retries,
                wait: that.auto_reconnect_wait
            });
        } else {
            that.emit('close', err ? true : false);
            that.reconnect_attempts = 0;
        }

        if (should_reconnect) {
            that.debugOut('Scheduling reconnect');
            that.setTimeout(function() {
                that.connect();
            }, that.auto_reconnect_wait);
        }
    }
};

Connection.prototype.write = function(data, callback) {
    if (!this.connected || this.requested_disconnect) {
        return 0;
    }

    this.debugOut('[outgoing line] ' + data);
    this.emit('raw', data, false);
    return this.transport.writeLine(data, callback);
};

/**
 * Create and keep track of all timers so they can be easily removed
 */
Connection.prototype.setTimeout = function(/*fn, length, argN */) {
    var that = this;
    var tmr = null;
    var callback = arguments[0];

    arguments[0] = function() {
       _.pull(that._timers, tmr);
       callback.apply(null, arguments);
    };

    tmr = setTimeout.apply(null, arguments);
    this._timers.push(tmr);
    return tmr;
};

Connection.prototype.clearTimeout = function(tmr) {
	clearTimeout(tmr);
	_.pull(this._timers, tmr);
};

Connection.prototype.clearTimers = function() {
    this._timers.forEach(function(tmr) {
        clearTimeout(tmr);
    });

    this._timers = [];
};

/**
 * Close the connection to the IRCd after forcing one last line
 */
Connection.prototype.end = function(data, callback) {
    var that = this;

    this.debugOut('Connection.end() connected=' + this.connected + ' with data=' + !!data);

    if (this.connected && data) {
        // Once the last bit of data has been sent, then re-run this function to close the socket
        this.write(data, function() {
            that.end();
        });

        return;
    }

    this.requested_disconnect = true;

    if (this.transport) {
        this.transport.close();
    }
};

Connection.prototype.setEncoding = function(encoding) {
    this.debugOut('Connection.setEncoding() encoding=' + encoding);

    if (this.transport) {
        return this.transport.setEncoding(encoding);
    }
};

/**
 * Process the buffered messages recieved from the IRCd
 * Will only process 4 lines per JS tick so that node can handle any other events while
 * handling a large buffer
 */
Connection.prototype.processReadBuffer = function(continue_processing) {
    // If we already have the read buffer being iterated through, don't start
    // another one.
    if (this.reading_buffer && !continue_processing) {
        return;
    }

    var that = this;
    var lines_per_js_tick = 4;
    var processed_lines = 0;
    var line;
    var message;

    this.reading_buffer = true;

    while (processed_lines < lines_per_js_tick && this.read_buffer.length > 0) {
        line = this.read_buffer.shift();
        if (!line) {
            continue;
        }

        message = ircLineParser(line);

        if (!message) {
            // A malformed IRC line
            continue;
        }
        this.emit('raw', line, true);
        this.emit('message', message);

        processed_lines++;
    }

    // If we still have items left in our buffer then continue reading them in a few ticks
    if (this.read_buffer.length > 0) {
        this.setTimeout(function() {
            that.processReadBuffer(true);
        }, 1);
    } else {
        this.reading_buffer = false;
    }
};
<|endoftext|>


<commit_before>const { IntrospectionFragmentMatcher } = require("apollo-cache-inmemory");

const introspectionQueryResultData = {
  __schema: {
    types: [
      {
        kind: "UNION",
        name: "Media",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "Image", ofType: null },
          { kind: "OBJECT", name: "Video", ofType: null }
        ]
      },
      {
        kind: "INTERFACE",
        name: "Layout",
        description:
          "A selection of template types that have opinions over how they should be presented. Usually used within the context of an associated list of articles",
        fields: [
          {
            name: "template",
            description: "",
            args: [],
            type: { kind: "ENUM", name: "Template", ofType: null },
            isDeprecated: false,
            deprecationReason: null
          }
        ],
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "LeadAndTwo", ofType: null },
          { kind: "OBJECT", name: "OpinionAndTwo", ofType: null },
          { kind: "OBJECT", name: "Default", ofType: null }
        ]
      },
      {
        kind: "INTERFACE",
        name: "ArticleSlice",
        description: "",
        fields: [
          {
            name: "items",
            description: "",
            args: [],
            type: {
              kind: "NON_NULL",
              name: null,
              ofType: {
                kind: "LIST",
                name: null,
                ofType: {
                  kind: "NON_NULL",
                  name: null,
                  ofType: { kind: "OBJECT", name: "Tile", ofType: null }
                }
              }
            },
            isDeprecated: false,
            deprecationReason: null
          }
        ],
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSlice", ofType: null },
          { kind: "OBJECT", name: "FocusSlice", ofType: null },
          { kind: "OBJECT", name: "LeadersSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndOneSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneFullWidthSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "LeadOneNoPicAndOneAndPortraitSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "LeadTwoNoPicAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryTwoAndTwoSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryTwoNoPicAndTwoSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "TwoPicAndSixNoPicSlice", ofType: null },
          { kind: "OBJECT", name: "CommentLeadAndCartoonSlice", ofType: null },
          { kind: "OBJECT", name: "LetterThundererPodcastSlice", ofType: null },
          { kind: "OBJECT", name: "CommentTwoAndNotebookSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryOneAndColumnistSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "ObituariesLeadAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "OpinionOneAndTwoSlice", ofType: null }
        ]
      },
      {
        kind: "INTERFACE",
        name: "Section",
        description: "",
        fields: [
          {
            name: "id",
            description: "",
            args: [],
            type: {
              kind: "NON_NULL",
              name: null,
              ofType: { kind: "SCALAR", name: "UUID", ofType: null }
            },
            isDeprecated: false,
            deprecationReason: null
          },
          {
            name: "title",
            description: "",
            args: [],
            type: {
              kind: "NON_NULL",
              name: null,
              ofType: { kind: "SCALAR", name: "String", ofType: null }
            },
            isDeprecated: false,
            deprecationReason: null
          },
          {
            name: "slug",
            description: "",
            args: [],
            type: {
              kind: "NON_NULL",
              name: null,
              ofType: { kind: "SCALAR", name: "Slug", ofType: null }
            },
            isDeprecated: false,
            deprecationReason: null
          },
          {
            name: "colour",
            description: "",
            args: [],
            type: {
              kind: "NON_NULL",
              name: null,
              ofType: { kind: "OBJECT", name: "Colour", ofType: null }
            },
            isDeprecated: false,
            deprecationReason: null
          }
        ],
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSection", ofType: null },
          { kind: "OBJECT", name: "NewsSection", ofType: null },
          { kind: "OBJECT", name: "CommentSection", ofType: null },
          { kind: "OBJECT", name: "PuzzleSection", ofType: null },
          { kind: "OBJECT", name: "RegisterSection", ofType: null },
          { kind: "OBJECT", name: "MagazineSection", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "PuffMainLink",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "Tile", ofType: null },
          { kind: "OBJECT", name: "NamedLink", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "PuffTopicLink",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSection", ofType: null },
          { kind: "OBJECT", name: "NewsSection", ofType: null },
          { kind: "OBJECT", name: "CommentSection", ofType: null },
          { kind: "OBJECT", name: "PuzzleSection", ofType: null },
          { kind: "OBJECT", name: "RegisterSection", ofType: null },
          { kind: "OBJECT", name: "NamedLink", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "StandardSectionItem",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSlice", ofType: null },
          { kind: "OBJECT", name: "PuffSlice", ofType: null },
          { kind: "OBJECT", name: "FocusSlice", ofType: null },
          { kind: "OBJECT", name: "LeadersSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndOneSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneFullWidthSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "LeadOneNoPicAndOneAndPortraitSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "LeadTwoNoPicAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryTwoAndTwoSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryTwoNoPicAndTwoSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "TwoPicAndSixNoPicSlice", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "NewsSectionItem",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSlice", ofType: null },
          { kind: "OBJECT", name: "InTheNewsSlice", ofType: null },
          { kind: "OBJECT", name: "PuffSlice", ofType: null },
          { kind: "OBJECT", name: "FocusSlice", ofType: null },
          { kind: "OBJECT", name: "LeadersSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndOneSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneFullWidthSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "LeadOneNoPicAndOneAndPortraitSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "LeadTwoNoPicAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryTwoAndTwoSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryTwoNoPicAndTwoSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "TwoPicAndSixNoPicSlice", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "CommentSectionItem",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSlice", ofType: null },
          { kind: "OBJECT", name: "PuffSlice", ofType: null },
          { kind: "OBJECT", name: "DailyUniversalRegister", ofType: null },
          { kind: "OBJECT", name: "CommentLeadAndCartoonSlice", ofType: null },
          { kind: "OBJECT", name: "LetterThundererPodcastSlice", ofType: null },
          { kind: "OBJECT", name: "CommentTwoAndNotebookSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryOneAndColumnistSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "FocusSlice", ofType: null },
          { kind: "OBJECT", name: "LeadersSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndOneSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneFullWidthSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "LeadOneNoPicAndOneAndPortraitSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "LeadTwoNoPicAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryTwoAndTwoSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryTwoNoPicAndTwoSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "TwoPicAndSixNoPicSlice", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "PuzzleSectionItem",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "Puzzle", ofType: null },
          { kind: "OBJECT", name: "PuffSlice", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "RegisterSectionItem",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSlice", ofType: null },
          { kind: "OBJECT", name: "PuffSlice", ofType: null },
          { kind: "OBJECT", name: "ObituariesLeadAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "FocusSlice", ofType: null },
          { kind: "OBJECT", name: "LeadersSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndOneSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneFullWidthSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "LeadOneNoPicAndOneAndPortraitSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "LeadTwoNoPicAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryTwoAndTwoSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryTwoNoPicAndTwoSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "TwoPicAndSixNoPicSlice", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "MagazineSectionItem",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSlice", ofType: null },
          { kind: "OBJECT", name: "PuffSlice", ofType: null },
          { kind: "OBJECT", name: "FocusSlice", ofType: null },
          { kind: "OBJECT", name: "LeadersSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndOneSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneFullWidthSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "LeadOneNoPicAndOneAndPortraitSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "LeadTwoNoPicAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryTwoAndTwoSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryTwoNoPicAndTwoSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "TwoPicAndSixNoPicSlice", ofType: null }
        ]
      }
    ]
  }
};

const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData
});

module.exports.fragmentMatcher = fragmentMatcher;
<commit_msg>chore: update fm (#1392)<commit_after>const { IntrospectionFragmentMatcher } = require("apollo-cache-inmemory");

const introspectionQueryResultData = {
  __schema: {
    types: [
      {
        kind: "UNION",
        name: "Media",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "Image", ofType: null },
          { kind: "OBJECT", name: "Video", ofType: null }
        ]
      },
      {
        kind: "INTERFACE",
        name: "Layout",
        description:
          "A selection of template types that have opinions over how they should be presented. Usually used within the context of an associated list of articles",
        fields: [
          {
            name: "template",
            description: "",
            args: [],
            type: { kind: "ENUM", name: "Template", ofType: null },
            isDeprecated: false,
            deprecationReason: null
          }
        ],
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "LeadAndTwo", ofType: null },
          { kind: "OBJECT", name: "OpinionAndTwo", ofType: null },
          { kind: "OBJECT", name: "Default", ofType: null }
        ]
      },
      {
        kind: "INTERFACE",
        name: "ArticleSlice",
        description: "",
        fields: [
          {
            name: "items",
            description: "",
            args: [],
            type: {
              kind: "NON_NULL",
              name: null,
              ofType: {
                kind: "LIST",
                name: null,
                ofType: {
                  kind: "NON_NULL",
                  name: null,
                  ofType: { kind: "OBJECT", name: "Tile", ofType: null }
                }
              }
            },
            isDeprecated: false,
            deprecationReason: null
          }
        ],
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSlice", ofType: null },
          { kind: "OBJECT", name: "FocusSlice", ofType: null },
          { kind: "OBJECT", name: "LeadersSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndOneSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneFullWidthSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "LeadOneNoPicAndOneAndPortraitSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "LeadTwoNoPicAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryTwoAndTwoSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryTwoNoPicAndTwoSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "TwoPicAndSixNoPicSlice", ofType: null },
          { kind: "OBJECT", name: "CommentLeadAndCartoonSlice", ofType: null },
          { kind: "OBJECT", name: "LetterThundererPodcastSlice", ofType: null },
          { kind: "OBJECT", name: "CommentTwoAndNotebookSlice", ofType: null },
          { kind: "OBJECT", name: "ObituariesLeadAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "OpinionOneAndTwoSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryOneAndColumnistSlice",
            ofType: null
          }
        ]
      },
      {
        kind: "INTERFACE",
        name: "Section",
        description: "",
        fields: [
          {
            name: "id",
            description: "",
            args: [],
            type: {
              kind: "NON_NULL",
              name: null,
              ofType: { kind: "SCALAR", name: "UUID", ofType: null }
            },
            isDeprecated: false,
            deprecationReason: null
          },
          {
            name: "title",
            description: "",
            args: [],
            type: {
              kind: "NON_NULL",
              name: null,
              ofType: { kind: "SCALAR", name: "String", ofType: null }
            },
            isDeprecated: false,
            deprecationReason: null
          },
          {
            name: "slug",
            description: "",
            args: [],
            type: {
              kind: "NON_NULL",
              name: null,
              ofType: { kind: "SCALAR", name: "Slug", ofType: null }
            },
            isDeprecated: false,
            deprecationReason: null
          },
          {
            name: "colour",
            description: "",
            args: [],
            type: {
              kind: "NON_NULL",
              name: null,
              ofType: { kind: "OBJECT", name: "Colour", ofType: null }
            },
            isDeprecated: false,
            deprecationReason: null
          }
        ],
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSection", ofType: null },
          { kind: "OBJECT", name: "PuzzleSection", ofType: null },
          { kind: "OBJECT", name: "MagazineSection", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "PuffMainLink",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "Tile", ofType: null },
          { kind: "OBJECT", name: "NamedLink", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "PuffTopicLink",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSection", ofType: null },
          { kind: "OBJECT", name: "PuzzleSection", ofType: null },
          { kind: "OBJECT", name: "NamedLink", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "StandardSectionItem",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSlice", ofType: null },
          { kind: "OBJECT", name: "PuffSlice", ofType: null },
          { kind: "OBJECT", name: "FocusSlice", ofType: null },
          { kind: "OBJECT", name: "LeadersSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndOneSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneFullWidthSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "LeadOneNoPicAndOneAndPortraitSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "LeadTwoNoPicAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryTwoAndTwoSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryTwoNoPicAndTwoSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "TwoPicAndSixNoPicSlice", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "PuzzleSectionItem",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "Puzzle", ofType: null },
          { kind: "OBJECT", name: "PuffSlice", ofType: null }
        ]
      },
      {
        kind: "UNION",
        name: "MagazineSectionItem",
        description: "",
        fields: null,
        inputFields: null,
        interfaces: null,
        enumValues: null,
        possibleTypes: [
          { kind: "OBJECT", name: "StandardSlice", ofType: null },
          { kind: "OBJECT", name: "PuffSlice", ofType: null },
          { kind: "OBJECT", name: "FocusSlice", ofType: null },
          { kind: "OBJECT", name: "LeadersSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndOneSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "LeadOneFullWidthSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "LeadOneNoPicAndOneAndPortraitSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "LeadTwoNoPicAndTwoSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryOneAndFourSlice", ofType: null },
          { kind: "OBJECT", name: "SecondaryTwoAndTwoSlice", ofType: null },
          {
            kind: "OBJECT",
            name: "SecondaryTwoNoPicAndTwoSlice",
            ofType: null
          },
          { kind: "OBJECT", name: "TwoPicAndSixNoPicSlice", ofType: null }
        ]
      }
    ]
  }
};

const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData
});

module.exports.fragmentMatcher = fragmentMatcher;
<|endoftext|>


<commit_before>import _ from 'lodash/fp'
import { aspects } from './aspect'

const noRearg = _.convert({ rearg: false })
const mutable = _.convert({ immutable: false })
const noCap = _.convert({ cap: false })

// Flips
// ----------
export const getIn = noRearg.get
export const hasIn = noRearg.has
export const pickIn = noRearg.pick
export const includesIn = noRearg.includes
export const inversions = _.mapKeys(k => `${k}In`, noRearg)

// Mutables
// ----------
export const extendOn = mutable.extend
export const defaultsOn = mutable.defaults
export const mergeOn = mutable.merge
export const setOn = mutable.set
// Curry required until https://github.com/lodash/lodash/issues/3440 is resolved
export const unsetOn = _.curryN(2, mutable.unset)
export const pullOn = mutable.pull

// Uncaps
// ------
// Un-prefixed Deprecated
export const reduce = aspects.deprecate('reduce', '1.28.0', 'reduceIndexed')(
  noCap.reduce
)
export const mapValues = aspects.deprecate(
  'mapValues',
  '1.28.0',
  'mapValuesIndexed'
)(noCap.mapValues)
export const each = aspects.deprecate('each', '1.28.0', 'eachIndexed')(
  noCap.each
)

export const mapIndexed = noCap.map
export const findIndexed = noCap.find
export const eachIndexed = noCap.each
export const reduceIndexed = noCap.reduce
export const pickByIndexed = noCap.pickBy
export const mapValuesIndexed = noCap.mapValues
<commit_msg>updateOn<commit_after>import _ from 'lodash/fp'
import { aspects } from './aspect'

const noRearg = _.convert({ rearg: false })
const mutable = _.convert({ immutable: false })
const noCap = _.convert({ cap: false })

// Flips
// ----------
export const getIn = noRearg.get
export const hasIn = noRearg.has
export const pickIn = noRearg.pick
export const includesIn = noRearg.includes
export const inversions = _.mapKeys(k => `${k}In`, noRearg)

// Mutables
// ----------
export const extendOn = mutable.extend
export const defaultsOn = mutable.defaults
export const mergeOn = mutable.merge
export const setOn = mutable.set
// Curry required until https://github.com/lodash/lodash/issues/3440 is resolved
export const unsetOn = _.curryN(2, mutable.unset)
export const pullOn = mutable.pull
export const updateOn = mutable.update

// Uncaps
// ------
// Un-prefixed Deprecated
export const reduce = aspects.deprecate('reduce', '1.28.0', 'reduceIndexed')(
  noCap.reduce
)
export const mapValues = aspects.deprecate(
  'mapValues',
  '1.28.0',
  'mapValuesIndexed'
)(noCap.mapValues)
export const each = aspects.deprecate('each', '1.28.0', 'eachIndexed')(
  noCap.each
)

export const mapIndexed = noCap.map
export const findIndexed = noCap.find
export const eachIndexed = noCap.each
export const reduceIndexed = noCap.reduce
export const pickByIndexed = noCap.pickBy
export const mapValuesIndexed = noCap.mapValues
<|endoftext|>


<commit_before>/**
 * Assumptions:
 * Blocks have a size of 100px x 100px. Modify radius to your liking.
 * Certain lines can cross each other, others cannot.
 * The not straight lines have some manipulations that make
 * it look nice to my humble opinion.
 *
 * yet another visual artist • y-a-v-a.org
 * Vincent Bruijn <vebruijn@gmail.com> - http://www.y-a-v-a.org
 * 2015 • CC BY SA 3.0
 */
(function() {
  var c = document.getElementsByTagName('canvas')[0];
  var ctx = c.getContext('2d');
  var dashes = [12, 6];
  var radius = 100;
  var lineOne;
  var lineTwo;

  var lineTypes = [
    // arcs from corners
    function(c, x, y, radius) {
      drawQuarter(c, x, y, radius, 3, 0);
    },
    function(c, x, y, radius) {
      drawQuarter(c, x, y, radius, 0, 1);
    },
    function(c, x, y, radius) {
      drawQuarter(c, x, y, radius, 1, 2);
    },
    function(c, x, y, radius) {
      drawQuarter(c, x, y, radius, 2, 3);
    },

    // arcs from sides
    function(c, x, y, radius) {
      drawArc(c, x, y, radius, 0);
    },
    function(c, x, y, radius) {
      drawArc(c, x, y, radius, 1);
    },
    function(c, x, y, radius) {
      drawArc(c, x, y, radius, 2);
    },
    function(c, x, y, radius) {
      drawArc(c, x, y, radius, 3);
    },

    // straight
    function(c, x, y, radius) {
      drawVert(c, x, y, radius, false, false);
    },
    function(c, x, y, radius) {
      drawHoriz(c, x, y, radius, false, false);
    },
    function(c, x, y, radius) {
      drawDiagonalRight(c, x, y, radius, false, false);
    },
    function(c, x, y, radius) {
      drawDiagonalLeft(c, x, y, radius, false, false);
    },

    // not straight
    function(c, x, y, radius) {
      drawVert(c, x, y, radius, false, true);
    },
    function(c, x, y, radius) {
      drawHoriz(c, x, y, radius, false, true);
    },
    function(c, x, y, radius) {
      drawDiagonalRight(c, x, y, radius, false, true);
    },
    function(c, x, y, radius) {
      drawDiagonalLeft(c, x, y, radius, false, true);
    },

    // broken
    function(c, x, y, radius) {
      drawVert(c, x, y, radius, true, false);
    },
    function(c, x, y, radius) {
      drawHoriz(c, x, y, radius, true, false);
    },
    function(c, x, y, radius) {
      drawDiagonalRight(c, x, y, radius, true, false);
    },
    function(c, x, y, radius) {
      drawDiagonalLeft(c, x, y, radius, true, false);
    }
  ];

  // arcs from corners
  function drawQuarter(c, x, y, radius, start, end) {
    var clockWise = false;

    var startAngle = 0.5 * Math.PI * start;
    var endAngle = 0.5 * Math.PI * end;
    var newx = start === 0 || start === 3 ? x : x + radius;
    var newy = end === 0 || end === 3 ? y + radius : y;

    c.beginPath();
    c.arc(newx, newy, radius, startAngle, endAngle, clockWise);
    c.stroke();
  }

  // arcs from sides
  function drawArc(c, x, y, radius, start) {
    var startAngle = (- (1/6) + (1/2 * start)) * Math.PI;
    var endAngle = (- (1/6) + (1/2 * start) + (1/3)) * Math.PI;
    var clockWise = false;
    var refx;
    var refy;

    var halfRadius = radius * 0.5;
    var offset = radius * 0.36863;

    switch (start) {
      case 0:
      refx = x - offset;
      refy = y + halfRadius;
      break;
      case 1:
      refx = x + halfRadius;
      refy = y - offset;
      break;
      case 2:
      refx = x + radius + offset;
      refy = y + halfRadius;
      break;
      case 3:
      refx = x + halfRadius;
      refy = y + radius + offset;
      break;
    }

    c.beginPath();
    c.arc(refx, refy, radius, startAngle, endAngle, clockWise);
    c.stroke();
  }

  // narrow limit from 0.2 to 0.8 or from -0.3 to 0.3
  function narrowLimit(signed) {
    var limit = Math.random() * 0.6;
    return !!signed ? limit - 0.3 : limit + 0.2;
  }

  function randomDiagonal(radius) {
    return narrowLimit() * (radius * Math.sqrt(2) * 0.09);
  }

  // straight, not straight and broken
  function drawVert(c, x, y, radius, dashed, random) {
    var offset = 0.5 * radius;
    var threshold = 0.1 * radius;
    if (dashed) {
      c.setLineDash(dashes);
    }
    c.beginPath();
    c.moveTo(x + offset, y);

    if (random) {
      var randx;
      var randy;
      var dx = x + offset;
      var dy = y;
      while (dy < (y + radius - threshold)) {
        randx = narrowLimit(true) * (radius * .09);
        randy = narrowLimit() * radius * .18;
        c.lineTo(dx + randx, dy += randy);
      }
    }

    c.lineTo(x + offset, y + radius);
    c.stroke();
    if (dashed) {
      c.setLineDash([0,0]);
    }
  }

  function drawHoriz(c, x, y, radius, dashed, random) {
    var offset = 0.5 * radius;
    var threshold = 0.1 * radius;
    if (dashed) {
      c.setLineDash(dashes);
    }
    c.beginPath();
    c.moveTo(x, y + offset);

    if (random) {
      var randx;
      var randy;
      var dx = x;
      var dy = y + offset;
      while (dx < (x + radius - threshold)) {
        randx = narrowLimit() * radius * .18;
        randy = narrowLimit(true) * (radius * .09);

        c.lineTo(dx += randx, dy + randy);
      }
    }

    c.lineTo(x + radius, y + offset);
    c.stroke();
    if (dashed) {
      c.setLineDash([0,0]);
    }
  }

  function drawDiagonalRight(c, x, y, radius, dashed, random) {
    var threshold = 0.1 * radius;
    if (dashed) {
      c.setLineDash(dashes);
    }
    c.beginPath();
    c.moveTo(x + radius, y);

    if (random) {
      var randx;
      var randy;
      var dx = x + radius;
      var dy = y;
      while (dx > (x + threshold) && dy < (y + radius - threshold)) {
        randx = randomDiagonal(radius);
        randy = randomDiagonal(radius);
        c.lineTo(dx -= randx, dy += randy);
      }
    }

    c.lineTo(x, y + radius);
    c.stroke();
    if (dashed) {
      c.setLineDash([0,0]);
    }
  }

  function drawDiagonalLeft(c, x, y, radius, dashed, random) {
    var threshold = 0.1 * radius;
    if (dashed) {
      c.setLineDash(dashes);
    }
    c.beginPath();
    c.moveTo(x, y);

    if (random) {
      var randx;
      var randy;
      var dx = x;
      var dy = y;
      while (dx < (x + radius - threshold) && dy < (y + radius - threshold)) {
        randx = randomDiagonal(radius);
        randy = randomDiagonal(radius);
        c.lineTo(dx += randx, dy += randy);
      }
    }

    c.lineTo(x + radius, y + radius);
    c.stroke();
    if (dashed) {
      c.setLineDash([0,0]);
    }
  }

  // which lines do cross, which do not
  var crossMatrix = [
  // ◝ ◞ ◟ ◜  ) ⌣ ( ⌢  | - / \  | - / \  ⋮ ⋯ ⋰ ⋱
    [0,1,0,1, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,1,1,0],
    [1,0,1,0, 1,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1],
    [0,1,0,1, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,1,1,0],
    [1,0,1,0, 1,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1],

    [1,1,1,1, 0,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1],
    [1,1,1,1, 1,0,1,0, 1,0,1,1, 1,0,1,1, 1,0,1,1],
    [1,1,1,1, 0,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1],
    [1,1,1,1, 1,0,1,0, 1,0,1,1, 1,0,1,1, 1,0,1,1],

    [1,1,1,1, 0,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1],
    [1,1,1,1, 1,0,1,0, 1,0,1,1, 1,0,1,1, 1,0,1,1],
    [1,0,1,0, 1,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1],
    [0,1,0,1, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,1,1,0],

    [1,1,1,1, 0,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1],
    [1,1,1,1, 1,0,1,0, 1,0,1,1, 1,0,1,1, 1,0,1,1],
    [1,0,1,0, 1,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1],
    [0,1,0,1, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,1,1,0],

    [1,1,1,1, 0,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1],
    [1,1,1,1, 1,0,1,0, 1,0,1,1, 1,0,1,1, 1,0,1,1],
    [1,0,1,0, 1,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1],
    [0,1,0,1, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,1,1,0]
  ];

  function getUnique(oldVal, total) {
    var newVal;
    do {
      do {
        newVal = Math.floor(Math.random() * total);
      } while (newVal === oldVal);
    } while (crossMatrix[oldVal][newVal] === 0);

    return newVal;
  }

  function draw() {
    var width = ctx.canvas.width = ctx.canvas.clientWidth;
    var height = ctx.canvas.height = ctx.canvas.clientHeight;

    ctx.clearRect(0, 0, c.width, c.height);
    ctx.strokeStyle = '#A5A2B9'; // blue

    var blocksx = Math.floor(width / radius);
    var blocksy = Math.floor(height / radius);

    var marginLeft = (width - (blocksx * radius)) * 0.5; // margin left
    var marginTop = (height - (blocksy * radius)) * 0.5; // margin top

    var x;
    var y;
    var row;
    var col;

    for (row = 0; row < blocksx; row++) {
      for (col = 0; col < blocksy; col++) {
        lineOne = Math.floor(Math.random() * lineTypes.length);
        lineTwo = getUnique(lineOne, lineTypes.length);

        x = row * radius + marginLeft;
        y = col * radius + marginTop;

        lineTypes[lineOne].call(null, ctx, x, y, radius);
        lineTypes[lineTwo].call(null, ctx, x, y, radius);
      }
    }
  }

  window.onresize = draw;
  draw();

}());
<commit_msg>safari fix, syntax fix, better arc creation<commit_after>/**
 * Assumptions:
 * Blocks have a size of 100px x 100px. Modify radius to your liking.
 * Certain lines can cross each other, others cannot.
 * The not straight lines have some manipulations that make
 * it look nice to my humble opinion.
 *
 * yet another visual artist • y-a-v-a.org
 * Vincent Bruijn <vebruijn@gmail.com> - http://www.y-a-v-a.org
 * 2015 • CC BY SA 3.0
 */
(function() {
  var c = document.getElementsByTagName('canvas')[0];
  var ctx = c.getContext('2d');
  var dashes = [12, 6];
  var radius = 100;
  var lineOne;
  var lineTwo;

  var lineTypes = [
    // arcs from corners
    function(c, x, y, radius) {
      drawQuarter(c, x, y, radius, 3, 0);
    },
    function(c, x, y, radius) {
      drawQuarter(c, x, y, radius, 0, 1);
    },
    function(c, x, y, radius) {
      drawQuarter(c, x, y, radius, 1, 2);
    },
    function(c, x, y, radius) {
      drawQuarter(c, x, y, radius, 2, 3);
    },

    // arcs from sides
    function(c, x, y, radius) {
      drawArc(c, x, y, radius, 0, -1, 0);
    },
    function(c, x, y, radius) {
      drawArc(c, x, y, radius, 1, 0, -1);
    },
    function(c, x, y, radius) {
      drawArc(c, x, y, radius, 2, 1, 0);
    },
    function(c, x, y, radius) {
      drawArc(c, x, y, radius, 3, 0, 1);
    },

    // straight
    function(c, x, y, radius) {
      drawVert(c, x, y, radius, false, false);
    },
    function(c, x, y, radius) {
      drawHoriz(c, x, y, radius, false, false);
    },
    function(c, x, y, radius) {
      drawDiagonalRight(c, x, y, radius, false, false);
    },
    function(c, x, y, radius) {
      drawDiagonalLeft(c, x, y, radius, false, false);
    },

    // not straight
    function(c, x, y, radius) {
      drawVert(c, x, y, radius, false, true);
    },
    function(c, x, y, radius) {
      drawHoriz(c, x, y, radius, false, true);
    },
    function(c, x, y, radius) {
      drawDiagonalRight(c, x, y, radius, false, true);
    },
    function(c, x, y, radius) {
      drawDiagonalLeft(c, x, y, radius, false, true);
    },

    // broken
    function(c, x, y, radius) {
      drawVert(c, x, y, radius, true, false);
    },
    function(c, x, y, radius) {
      drawHoriz(c, x, y, radius, true, false);
    },
    function(c, x, y, radius) {
      drawDiagonalRight(c, x, y, radius, true, false);
    },
    function(c, x, y, radius) {
      drawDiagonalLeft(c, x, y, radius, true, false);
    }
  ];

  // arcs from corners
  function drawQuarter(c, x, y, radius, start, end) {
    var clockWise = false;

    var startAngle = 0.5 * Math.PI * start;
    var endAngle = 0.5 * Math.PI * end;
    var newx = start === 0 || start === 3 ? x : x + radius;
    var newy = end === 0 || end === 3 ? y + radius : y;

    c.beginPath();
    c.arc(newx, newy, radius, startAngle, endAngle, clockWise);
    c.stroke();
  }

  // arcs from sides
  function drawArc(c, x, y, radius, start, cx, cy) {
    var startAngle = (- (1/6) + (1/2 * start)) * Math.PI;
    var endAngle = (- (1/6) + (1/2 * start) + (1/3)) * Math.PI;
    var clockWise = false;
    var refx = x + (0.5 * radius);
    var refy = y + (0.5 * radius);

    var halfRadius = radius * 0.5;
    var offset = radius * 0.36863;

    var offsetx = refx + (cx * (halfRadius + offset));
    var offsety = refy + (cy * (halfRadius + offset));

    c.beginPath();
    c.arc(offsetx, offsety, radius, startAngle, endAngle, clockWise);
    c.stroke();
  }

  // narrow limit from 0.2 to 0.8 or from -0.3 to 0.3
  function narrowLimit(signed) {
    var limit = Math.random() * 0.6;
    return !!signed ? limit - 0.3 : limit + 0.2;
  }

  function randomDiagonal(radius) {
    return narrowLimit() * (radius * Math.sqrt(2) * 0.09);
  }

  // straight, not straight and broken
  function drawVert(c, x, y, radius, dashed, random) {
    var offset = 0.5 * radius;
    var threshold = 0.1 * radius;
    if (dashed) {
      c.setLineDash(dashes);
    }
    c.beginPath();
    c.moveTo(x + offset, y);

    if (random) {
      var randx;
      var randy;
      var dx = x + offset;
      var dy = y;
      while (dy < (y + radius - threshold)) {
        randx = narrowLimit(true) * (radius * 0.09);
        randy = narrowLimit() * radius * 0.18;
        c.lineTo(dx + randx, dy += randy);
      }
    }

    c.lineTo(x + offset, y + radius);
    c.stroke();
    if (dashed) {
      c.setLineDash([]);
    }
  }

  function drawHoriz(c, x, y, radius, dashed, random) {
    var offset = 0.5 * radius;
    var threshold = 0.1 * radius;
    if (dashed) {
      c.setLineDash(dashes);
    }
    c.beginPath();
    c.moveTo(x, y + offset);

    if (random) {
      var randx;
      var randy;
      var dx = x;
      var dy = y + offset;
      while (dx < (x + radius - threshold)) {
        randx = narrowLimit() * radius * 0.18;
        randy = narrowLimit(true) * (radius * 0.09);

        c.lineTo(dx += randx, dy + randy);
      }
    }

    c.lineTo(x + radius, y + offset);
    c.stroke();
    if (dashed) {
      c.setLineDash([]);
    }
  }

  function drawDiagonalRight(c, x, y, radius, dashed, random) {
    var threshold = 0.1 * radius;
    if (dashed) {
      c.setLineDash(dashes);
    }
    c.beginPath();
    c.moveTo(x + radius, y);

    if (random) {
      var randx;
      var randy;
      var dx = x + radius;
      var dy = y;
      while (dx > (x + threshold) && dy < (y + radius - threshold)) {
        randx = randomDiagonal(radius);
        randy = randomDiagonal(radius);
        c.lineTo(dx -= randx, dy += randy);
      }
    }

    c.lineTo(x, y + radius);
    c.stroke();
    if (dashed) {
      c.setLineDash([]);
    }
  }

  function drawDiagonalLeft(c, x, y, radius, dashed, random) {
    var threshold = 0.1 * radius;
    if (dashed) {
      c.setLineDash(dashes);
    }
    c.beginPath();
    c.moveTo(x, y);

    if (random) {
      var randx;
      var randy;
      var dx = x;
      var dy = y;
      while (dx < (x + radius - threshold) && dy < (y + radius - threshold)) {
        randx = randomDiagonal(radius);
        randy = randomDiagonal(radius);
        c.lineTo(dx += randx, dy += randy);
      }
    }

    c.lineTo(x + radius, y + radius);
    c.stroke();
    if (dashed) {
      c.setLineDash([]);
    }
  }

  // which lines do cross, which do not
  var crossMatrix = [
  // ◝ ◞ ◟ ◜  ) ⌣ ( ⌢  | - / \  | - / \  ⋮ ⋯ ⋰ ⋱
    [0,1,0,1, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,1,1,0],
    [1,0,1,0, 1,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1],
    [0,1,0,1, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,1,1,0],
    [1,0,1,0, 1,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1],

    [1,1,1,1, 0,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1],
    [1,1,1,1, 1,0,1,0, 1,0,1,1, 1,0,1,1, 1,0,1,1],
    [1,1,1,1, 0,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1],
    [1,1,1,1, 1,0,1,0, 1,0,1,1, 1,0,1,1, 1,0,1,1],

    [1,1,1,1, 0,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1],
    [1,1,1,1, 1,0,1,0, 1,0,1,1, 1,0,1,1, 1,0,1,1],
    [1,0,1,0, 1,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1],
    [0,1,0,1, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,1,1,0],

    [1,1,1,1, 0,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1],
    [1,1,1,1, 1,0,1,0, 1,0,1,1, 1,0,1,1, 1,0,1,1],
    [1,0,1,0, 1,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1],
    [0,1,0,1, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,1,1,0],

    [1,1,1,1, 0,1,0,1, 0,1,1,1, 0,1,1,1, 0,1,1,1],
    [1,1,1,1, 1,0,1,0, 1,0,1,1, 1,0,1,1, 1,0,1,1],
    [1,0,1,0, 1,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,0,1],
    [0,1,0,1, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,1,1,0]
  ];

  function getUnique(oldVal, total) {
    var newVal;
    do {
      do {
        newVal = Math.floor(Math.random() * total);
      } while (newVal === oldVal);
    } while (crossMatrix[oldVal][newVal] === 0);

    return newVal;
  }

  function draw() {
    var width = ctx.canvas.width = ctx.canvas.clientWidth;
    var height = ctx.canvas.height = ctx.canvas.clientHeight;

    ctx.clearRect(0, 0, c.width, c.height);
    ctx.strokeStyle = '#A5A2B9'; // blue

    var blocksx = Math.floor(width / radius);
    var blocksy = Math.floor(height / radius);

    var marginLeft = (width - (blocksx * radius)) * 0.5; // margin left
    var marginTop = (height - (blocksy * radius)) * 0.5; // margin top

    var x;
    var y;
    var row;
    var col;

    for (row = 0; row < blocksx; row++) {
      for (col = 0; col < blocksy; col++) {
        lineOne = Math.floor(Math.random() * lineTypes.length);
        lineTwo = getUnique(lineOne, lineTypes.length);

        x = row * radius + marginLeft;
        y = col * radius + marginTop;

        lineTypes[lineOne].call(null, ctx, x, y, radius);
        lineTypes[lineTwo].call(null, ctx, x, y, radius);
      }
    }
  }

  window.onresize = draw;
  draw();

}());
<|endoftext|>