text:
permalink: /docs/patterns/
---

# Patterns

Shared patterns for dealing with common Hubot scenarios.

## Renaming the Hubot instance

When you rename Hubot, he will no longer respond to his former name. In order to train your users on the new name, you may choose to add a deprecation notice when they try to say the old name. The pattern logic is:

* listen to all messages that start with the old name
* reply to the user letting them know about the new name

Setting this up is very easy:

1. Create a [bundled script](scripting.md) in the `scripts/` directory of your Hubot instance called `rename-hubot.coffee`
2. Add the following code, modified for your needs:

```coffeescript
# Description:
#   Tell people hubot's new name if they use the old one
#
# Commands:
#   None
#
module.exports = (robot) ->
  robot.hear /^hubot:? (.+)/i, (res) ->
    response = "Sorry, I'm a diva and only respond to #{robot.name}"
    response += " or #{robot.alias}" if robot.alias
    res.reply response
    return

```

In the above pattern, modify both the hubot listener and the response message to suit your needs.

Also, it's important to note that the listener should be based on what hubot actually hears, instead of what is typed into the chat program before the Hubot Adapter has processed it. For example, the [HipChat Adapter](https://github.com/hipchat/hubot-hipchat) converts `@hubot` into `hubot:` before passing it to Hubot.

## Deprecating or Renaming Listeners

If you remove a script or change the commands for a script, it can be useful to let your users know about the change. One way is to just tell them in chat or let them discover the change by attempting to use a command that no longer exists. Another way is to have Hubot let people know when they've used a command that no longer works.

This pattern is similar to the Renaming the Hubot Instance pattern above:

* listen to all messages that match the old command
* reply to the user letting them know that it's been deprecated

Here is the setup:

1. Create a [bundled script](scripting.md) in the `scripts/` directory of your Hubot instance called `deprecations.coffee`
2. Copy any old command listeners and add them to that file. For example, if you were to rename the help command for some silly reason:

```coffeescript
# Description:
#   Tell users when they have used commands that are deprecated or renamed
#
# Commands:
#   None
#
module.exports = (robot) ->
  robot.respond /help\s*(.*)?$/i, (res) ->
    res.reply "That means nothing to me anymore. Perhaps you meant `docs` instead?"
    return

```

## Preventing Hubot from Running Scripts Concurrently

Sometimes you have scripts that take several minutes to execute.  If these scripts are doing something that could be interfered
with by running subsequent commands, you may wish to code your scripts to prevent concurrent access.

To do this, you can set up a lock in the Hubot [brain](scripting.md#persistence) object.  The lock is set up here so that different scripts
can share the same lock if necessary.

Setting up the lock looks something like this:

```coffeescript
module.exports = (robot) ->
  robot.brain.on 'loaded', ->
    # Clear the lock on startup in case Hubot has restarted and Hubot's brain has persistence (e.g. redis).
    # We don't want any orphaned locks preventing us from running commands.
    robot.brain.remove('yourLockName')

  robot.respond /longrunningthing/i, (msg) ->
    lock = robot.brain.get('yourLockName')

    if lock?
      msg.send "I'm sorry, #{msg.message.user.name}, I'm afraid I can't do that. I'm busy doing something for #{lock.user.name}."
      return

    robot.brain.set('yourLockName', msg.message)  # includes user, room, etc about who locked

    yourLongClobberingAsyncThing (err, response) ->
      # Clear the lock
      robot.brain.remove('yourLockName')
      msg.reply "Finally Done"
```

## Forwarding all HTTP requests through a proxy

In many corporate environments, a web proxy is required to access the Internet and/or protected resources. For one-off control, use can specify an [Agent](https://nodejs.org/api/http.html) to use with `robot.http`. However, this would require modifying every script your robot uses to point at the proxy. Instead, you can specify the agent at the global level and have all HTTP requests use the agent by default.

Due to the way node.js handles HTTP and HTTPS requests, you need to specify a different Agent for each protocol. ScopedHTTPClient will then automatically choose the right ProxyAgent for each request.

1. Install ProxyAgent. `npm install proxy-agent`
2. Create a [bundled script](scripting.md) in the `scripts/` directory of your Hubot instance called `proxy.coffee`
3. Add the following code, modified for your needs:

```coffeescript
proxy = require 'proxy-agent'
module.exports = (robot) ->
  robot.globalHttpOptions.httpAgent  = proxy('http://my-proxy-server.internal', false)
  robot.globalHttpOptions.httpsAgent = proxy('http://my-proxy-server.internal', true)
```

## Dynamic matching of messages

In some situations, you want to dynamically match different messages (e.g. factoids, JIRA projects). Rather than defining an overly broad regular expression that always matches, you can tell Hubot to only match when certain conditions are met.

In a simple robot, this isn't much different from just putting the conditions in the Listener callback, but it makes a big difference when you are dealing with middleware: with the basic model, middleware will be executed for every match of the generic regex. With the dynamic matching model, middleware will only be executed when the dynamic conditions are matched.

For example, the [factoid lookup command](https://github.com/github/hubot-scripts/blob/bd810f99f9394818a9dcc2ea3729427e4101b96d/src/scripts/factoid.coffee#L95-L99) could be reimplemented as:

```coffeescript
module.exports = (robot) ->
  # Dynamically populated list of factoids
  facts =
    fact1: 'stuff'
    fact2: 'other stuff'

  robot.listen(
    # Matcher
    (message) ->
      match = message.match(/^~(.*)$/)
      # Only match if there is a matching factoid
      if match and match[1] in facts
        match[1]
      else
        false
    # Callback
    (response) ->
      fact = response.match
      res.reply "#{fact} is #{facts[fact]}"
  )
```

## Restricting access to commands

One of the awesome features of Hubot is its ability to make changes to a production environment with a single chat message. However, not everyone with access to your chat service should be able to trigger production changes.

There are a variety of different patterns for restricting access that you can follow depending on your specific needs:

* Two buckets of access: full and restricted with whitelist/blacklist
* Specific access rules for every command (Role-based Access Control)
* Blacklisting/whitelisting commands in specific rooms

### Simple per-listener access

In some organizations, almost all employees are given the same level of access and only a select few need to be restricted (e.g. new hires, contractors, etc.). In this model, you partition the set of all listeners to separate the "power commands" from the "normal commands".

Once you have segregated the listeners, you need to make some tradeoff decisions around whitelisting/blacklisting users and listeners.

The key deciding factors for whitelisting vs blacklisting of users are the number of users in each category, the frequency of change in either category, and the level of security risk your organization is willing to accept.
* Whitelisting users (users X, Y, Z have access to power commands; all other users only get access to normal commands) is a more secure method of access (new users have no default access to power commands), but has higher maintenance overhead (you need to add each new user to the "approved" list).
* Blacklisting users (all users get access to power commands, except for users X, Y, Z, who only get access to normal commands) is a less secure method (new users have default access to power commands until they are added to the blacklist), but has a much lower maintenance overhead if the blacklist is small/rarely updated.

The key deciding factors for selectively allowing vs restricting listeners are the number of listeners in each category, the ratio of internal to external scripts, and the level of security risk your organization is willing to accept.
* Selectively allowing listeners (all listeners are power commands, except for listeners A, B, C, which are considered normal commands) is a more secure method (new listeners are restricted by default), but has a much higher maintenance overhead (every silly/fun listener needs to be explicity downgraded to "normal" status).
* Selectively restricting listeners (listeners A, B, C are power commands, everything else is a normal command) is a less secure method (new listeners are put into the normal category by default, which could give unexpected access; external scripts are particularly scary here), but has a lower maintenance overhead (no need to modify/enumerate all the fun/culture scripts in your access policy).

As an additional consideration, most scripts do not currently have listener IDs, so you will likely need to open PRs (or fork) any external scripts you use to add listener IDs. The actual modification is easy, but coordinating with lots of maintainers can be time consuming.

Once you have decided which of the four possible models to follow, you need to build the appropriate lists of users and listeners to plug into your authorization middleware.

Example: whitelist of users given access to selectively restricted power commands
```coffeescript
POWER_COMMANDS = [
  'deploy.web' # String that matches the listener ID
]

POWER_USERS = [
  'jdoe' # String that matches the user ID set by the adapter
]

module.exports = (robot) ->
  robot.listenerMiddleware (context, next, done) ->
    if context.listener.options.id in POWER_COMMANDS
      if context.response.message.user.id in POWER_USERS
        # User is allowed access to this command
        next()
      else
        # Restricted command, but user isn't in whitelist
        context.response.reply "I'm sorry, @#{context.response.message.user.name}, but you don't have access to do that."
        done()
    else
      # This is not a restricted command; allow everyone
      next()
```

Remember that middleware executes for ALL listeners that match a given message (including `robot.hear /.+/`), so make sure you include them when categorizing your listeners.

### Specific access rules per listener

For larger organizations, a binary categorization of access is usually insufficient and more complex access rules are required.

Example access policy:
* Each development team has access to cut releases and deploy their service
* The Operations group has access to deploy all services (but not cut releases)
* The front desk cannot cut releases nor deploy services

Complex policies like this are currently best implemented in code directly, though there is [ongoing work](https://github.com/michaelansel/hubot-rbac) to build a generalized framework for access management.

### Specific access rules per room

Organizations that have a number of chat rooms that serve different purposes often want to be able to use the same instance of hubot but have a different set of commands allowed in each room.

Work on generalized blacklist solution is [ongoing](https://github.com/kristenmills/hubot-command-blacklist). A whitelist soultion could take a similar approach.


text:
(function () {
    'use strict';

    angular
        .module('app.web')
        .controller('app.views.organizationUnits.users', OrganizationUnitsUsersController);

    OrganizationUnitsUsersController.$inject = ['$stateParams', 'abp.services.app.organizationUnits', '$uibModal'];
    function OrganizationUnitsUsersController($stateParams, _orgUnits, modal) {
        var vm = this;
        vm.orgId = $stateParams.id;
        activate();
        ////////////////
        vm.removeUser = function (userId, orgId) {
            abp.message.confirm(App.localize("UserWillBeRemovedFromOrganizationUnit"),
                App.localize("ConfirmQuestion"),
                function(response) {
                    if (response) {
                        _orgUnits.removeUserFromOrganizationUnit({
                                UserId: userId,
                                OrgUnitId: vm.orgId
                            })
                            .then(function() {
                                abp.notify.success(App.localize("UserRemovedFromOrganizationUnit"), App.localize("Success"));
                                activate();
                            });
                    }
                });
        }
        vm.openAddUserModal = function () {
            var modalInstance = modal.open({
                controller: 'app.views.organizationUnits.addUser as vm',
                templateUrl: '/App/SysAdmin/Main/modules/web/organizationUnits/adduser.cshtml',
                resolve: {
                    items: function () {
                        return {
                            orgUnitId: vm.orgId
                        }
                    }
                },
                size: 'lg'
            });
            modalInstance.result.then(function (response) {
                if (response === "useradded") {
                    abp.notify.success(App.localize("UserAdded"), App.localize("Success"));

                    activate();

                }
            });
        }
        vm.empty = true;

        function activate() {
            vm.id = $stateParams.id;
            _orgUnits.getUsersFromOrganizationUnit(vm.id).then(function (response) {
                vm.orgUnitModel = response.data;
                if (vm.orgUnitModel.users.length > 0) {
                    vm.empty = false;
                }
                else {
                    vm.empty = true;
                }
            });
        }
    }
})();

redpajama_set_name: RedPajamaGithub


text:
<?php
defined('C5_EXECUTE') or die("Access Denied.");
/** @var $control Concrete\Core\Page\Type\Composer\FormLayoutSetControl */

$der = Concrete\Core\Page\Type\Composer\Control\Type\Type::getByID($control->getPageTypeComposerControlTypeID());
$pto = $control->getPageTypeComposerControlObject();
$name = '';
if (strlen($control->getPageTypeComposerFormLayoutSetControlCustomLabel())) {
	$name = $pto->getPageTypeComposerControlName() . ' ';
}

?>
<tr class="ccm-page-type-composer-form-layout-control-set-control" data-page-type-composer-form-layout-control-set-control-id="<?php echo $control->getPageTypeComposerFormLayoutSetControlID()?>">

		<?php echo $control->getPageTypeComposerControlDisplayLabel(); ?>

		<?php echo $der->getPageTypeComposerControlTypeDisplayName() ?>
		<?php if ($name): ?>
			(<?php echo trim($name) ?>)
		<?php endif ?>

<a data-command="edit-form-set-control" href="<?php echo REL_DIR_FILES_TOOLS_REQUIRED?>/page_types/composer/form/edit_control?ptComposerFormLayoutSetControlID=<?php echo $control->getPageTypeComposerFormLayoutSetControlID()?>" class="dialog-launch" dialog-width="400" dialog-height="auto" dialog-modal="true" dialog-title="<?php echo t('Edit Form Control')?>">

<a href="#" data-delete-set-control="<?php echo $control->getPageTypeComposerFormLayoutSetControlID()?>">

			<div data-delete-set-control-dialog="<?php echo $control->getPageTypeComposerFormLayoutSetControlID()?>">
				<?php echo t("Delete this control? This cannot be undone.")?>
				<?php echo Core::make('helper/validation/token')->output('delete_set_control')?>

					<button class="btn btn-default pull-left" onclick="jQuery.fn.dialog.closeTop()"><?php echo t('Cancel')?></button>
					<button class="btn btn-danger pull-right" onclick="Composer.deleteFromLayoutSetControl(<?php echo $control->getPageTypeComposerFormLayoutSetControlID()?>)"><?php echo t('Update Set')?></button>


text:
from contextlib import contextmanager
from functools import wraps
from fabric.colors import green, blue, yellow, red
from fabric.context_managers import cd, prefix, hide
from fabric.decorators import task, roles
from fabric.state import env
from fabric.api import sudo as _sudo

__author__ = 'rudy'

def _print(output):
    print
    print output
    print

def print_command(command):
    _print(blue("$ ", bold=True) +
           yellow(command, bold=True) +
           red(" ->", bold=True))

def log_call(func):
    @wraps(func)
    def logged(*args, **kawrgs):
        header = "-" * len(func.__name__)
        _print(green("\n".join([header, func.__name__, header]), bold=True))
        return func(*args, **kawrgs)
    return logged

@task
@roles('application','cron','database','db_slave')
def sudo(command, show=True):
    """
    Runs a command as sudo.
    """
    if show:
        print_command(command)
    with hide("running"):
        return _sudo(command)

@task
@roles('application','cron')
def pip(packages):
    """
    Installs one or more Python packages within the virtual environment.
    """
    with virtualenv():
        return sudo("pip install %s" % packages)

######################################
# Context for virtualenv and project #
######################################
@contextmanager
def activate_venv():
    with prefix("source %s/bin/activate" % env.venv_path):
        yield

@contextmanager
def virtualenv():
    """
    Runs commands within the project's virtualenv.
    """
    with cd(env.venv_path):
        with prefix("source %s/bin/activate" % env.venv_path):
            yield

@contextmanager
def project():
    """
    Runs commands within the project's directory.
    """
    with activate_venv():
        with cd(env.proj_path):
            yield


text:
import unittest
from mongokit import Document, Connection

class DescriptorsTestCase(unittest.TestCase):
    def setUp(self):
        self.connection = Connection()
        self.col = self.connection['test']['mongokit']

    def tearDown(self):
        self.connection.drop_database('test')

    def test_list_embed_dot_notation(self):
        """Attempt to set a default for a sub element using dot notation

        Either this or test_list_embed_list_notation should pass
        """

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {
                'list': [
                    {
                        'name': basestring,
                        'age': int
                    }
                ]
            }

            default_values = {
                'list.name': 'default'
            }

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list.append({'age': 23})

        self.assertDictEqual(
            doc, {
                'list': [
                    {
                        'name': 'default',
                        'age': 23
                    }
                ]
            }
        )

    def test_list_embed_list_notation(self):
        """Attempt to set a default for a sub element using list notation

        Either this or test_list_embed_dot_notation should pass
        """

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {
                'list': [
                    {
                        'name': basestring,
                        'age': int
                    }
                ]
            }

            default_values = {
                'list': [
                    {
                        'name': 'default'
                    }
                ]
            }

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list.append({'age': 23})

        self.assertDictEqual(
            doc, {
                'list': [
                    {
                        'name': 'default',
                        'age': 23
                    }
                ]
            }
        )

    def test_list_embed_non_required_fields(self):
        """Confirm all fields are not required"""

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {
                'list': [
                    {
                        'name': basestring,
                        'age': int
                    }
                ]
            }

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list.append({'age': 23})

        self.assertDictEqual(
            doc, {
                'list': [
                    {
                        'age': 23
                    }
                ]
            }
        )

        # Should validate fine
        doc.validate()

    def test_list_embed_required_fields_dot_notation(self):
        """Confirm list of object required field validation works"""

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {
                'list': [
                    {
                        'name': basestring,
                        'age': int
                    }
                ]
            }

            required_fields = ['list.name']

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list = [{'name': 'bob'}]

        self.assertDictEqual(
            doc, {
                'list': [
                    {
                        'name': 'bob'
                    }
                ]
            }
        )

        # Should validate fine
        doc.validate()

        doc.list = [{'age': 23}]

        self.assertDictEqual(
            doc, {
                'list': [
                    {
                        'age': 23
                    }
                ]
            }
        )

        try:
            doc.validate()
            self.fail('Not a valid document')
        except:
            pass

if __name__ == '__main__':
    unittest.main()


text:
/**
 *     This code was auto-generated by a Codezu.
 *
 *     Changes to this file may cause incorrect behavior and will be lost if
 *     the code is regenerated.
 */
package com.mozu.api.contracts.commerceruntime.discounts;

import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.joda.time.DateTime;

/**
 *	Properties of an invalid coupon code a shopper attempts to enter for a cart or order.
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class InvalidCoupon implements Serializable
{
	// Default Serial Version UID
	private static final long serialVersionUID = 1L;

	protected String couponCode;

	public String getCouponCode() {
		return this.couponCode;
	}

	public void setCouponCode(String couponCode) {
		this.couponCode = couponCode;
	}

	/**
	 * Date and time when the entity was created, represented in UTC Date/Time.
	 */
	protected DateTime createDate;

	public DateTime getCreateDate() {
		return this.createDate;
	}

	public void setCreateDate(DateTime createDate) {
		this.createDate = createDate;
	}

	protected Integer discountId;

	public Integer getDiscountId() {
		return this.discountId;
	}

	public void setDiscountId(Integer discountId) {
		this.discountId = discountId;
	}

	/**
	 * The reason the coupon was determined to be invalid.
	 */
	protected String reason;

	public String getReason() {
		return this.reason;
	}

	public void setReason(String reason) {
		this.reason = reason;
	}

	/**
	 * The code that identifies the reason the coupon code is invalid.
	 */
	protected Integer reasonCode;

	public Integer getReasonCode() {
		return this.reasonCode;
	}

	public void setReasonCode(Integer reasonCode) {
		this.reasonCode = reasonCode;
	}

}


text:
package rendezvous.federator.datasources;

import java.util.List;
import java.util.Set;

import rendezvous.federator.core.Entity;
import rendezvous.federator.core.Hit;
import rendezvous.federator.core.Value;

public abstract class QueryableDatasource extends Datasource {

	public abstract List<Hit> query(Entity entity, Set<Value> values) throws Exception;
}


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

module dragonBones {
    /**
     * @class dragonBones.EventDispatcher
     * @classdesc
     * 事件派发者
     */
    export class EventDispatcher {
        private _listenersMap:Object;

        constructor() {
        }

        /**
         *是否有指定类型的事件侦听函数
         * @param type 事件类型
         * @returns {boolean}
         */
        public hasEventListener(type:string):boolean {
            if(this._listenersMap && this._listenersMap[type]) {
                return true;
            }
            return false;
        }

        /**
         *添加一个针对指定类型的事件侦听函数
         * @param type 事件类型
         * @param listener 事件侦听函数
         */
        public addEventListener(type:string, listener:Function):void {
            if (type && listener) {
                if (!this._listenersMap) {
                    this._listenersMap = {};
                }
                var listeners:Array<Function> = this._listenersMap[type];
                if (listeners) {
                    this.removeEventListener(type, listener);
                }
                if (listeners) {
                    listeners.push(listener);
                }
                else {
                    this._listenersMap[type] = [listener];
                }
            }
        }

        /**
         *移除一个指定类型的事件侦听函数
         * @param type 事件类型
         * @param listener 需要移除的事件侦听函数
         */
        public removeEventListener(type:string, listener:Function):void {
            if (!this._listenersMap || !type || !listener) {
                return;
            }
            var listeners:Array<Function> = this._listenersMap[type];
            if (listeners) {
                var length:number = listeners.length;
                for (var i:number = 0; i < length; i++) {
                    if (listeners[i] == listener) {
                        if (length == 1) {
                            listeners.length = 0;
                            delete this._listenersMap[type];
                        }
                        else {
                            listeners.splice(i, 1);
                        }
                    }
                }
            }
        }

        /**
         *移除指定类型的所有的事件侦听函数
         * @param type 事件类型
         */
        public removeAllEventListeners(type:string):void {
            if (type) {
                delete this._listenersMap[type];
            }
            else {
                this._listenersMap = null;
            }
        }

        /**
         * 派发事件
         * @param event 被派发的事件
         */
        public dispatchEvent(event:Event):void {
            if (event) {
                var listeners:Array<Function> = this._listenersMap[event.type];
                if (listeners) {
                    event.target = this;
                    var listenersCopy:Array<Function> = listeners.concat();
                    var length:number = listeners.length;
                    for (var i:number = 0; i < length; i++) {
                        listenersCopy[i](event);
                    }
                }
            }
        }
    }
}


text:
<?php

return [
    'placeholder' => 'Choose a country...',
];


text:
<?PHP

// this document configures the sites domain constant

if ($api_load->website != '') {
  $set_domain = $api_load->website;
} else {
  $set_domain = 'http://www.cheaplocaldeals.com/';
}

define('SITE_URL',$set_domain);
define('OVERRIDE_SITE_URL','http://www.cheaplocaldeals.com/');
define('SITE_ADMIN_URL',SITE_URL.'admin/');
define('SITE_AFFILIATE_URL',SITE_URL.'affiliates/');
define('SITE_TEMPLATE_DIR',SITE_URL.'includes/template/');

// assign secure or non-secure page linking as requested by selected port
if($_SERVER['SERVER_PORT'] == 443) {
	define('CONNECTION_TYPE',SITE_SSL_URL);
} else {
	define('CONNECTION_TYPE',OVERRIDE_SITE_URL);
}

//// assign redirect post var if system var is set
//if(!empty($_SERVER['REDIRECT_URL'])) {
//  $_POST['REDIRECT_URL'] = $_SERVER['REDIRECT_URL'];
//}
?>


text:
class CreateProperties < ActiveRecord::Migration[4.2]
  def change
    create_table :properties do |t|
      t.string :key, null: false
      t.string :value, null: false
      t.references :database, index: true, foreign_key: {
        on_delete: :restrict, on_update: :restrict
      }

      t.timestamps null: false
    end
  end
end


text:
database-schema-export
======================

Database Schema Export


text:
namespace extensions {
namespace devtools_util {

namespace {

// Helper to inspect an ExtensionHost after it has been loaded.
void InspectExtensionHost(ExtensionHost* host) {
  if (host)
    DevToolsWindow::OpenDevToolsWindow(host->host_contents());
}

}  // namespace

void InspectBackgroundPage(const Extension* extension, Profile* profile) {
  DCHECK(extension);
  ExtensionSystem* system = ExtensionSystem::Get(profile);
  ExtensionHost* host = ProcessManager::Get(profile)
                            ->GetBackgroundHostForExtension(extension->id());
  if (host) {
    InspectExtensionHost(host);
  } else {
    system->lazy_background_task_queue()->AddPendingTask(
        profile,
        extension->id(),
        base::Bind(&InspectExtensionHost));
  }
}

}  // namespace devtools_util
}  // namespace extensions


text:
package com.clouddoctrina.secretservice;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceFilter;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;

public class ServiceMain {

    private static final int DEFAULT_PORT = 2222;

    public void startServer(int serverPort) throws Exception {
        Server server = new Server(serverPort);
        ServletContextHandler servletContextHandler = new ServletContextHandler(server, "/");
        servletContextHandler.addFilter(GuiceFilter.class, "/*", null);
        servletContextHandler.addServlet(DefaultServlet.class, "/");

        server.start();
        server.join();
    }

    public static void main(String[] args) throws Exception {
        Injector injector = Guice.createInjector(new JerseyModule());

        ServiceMain main = injector.getInstance(ServiceMain.class);
        main.startServer(DEFAULT_PORT);
    }
}


text:
/*  bhoechie tab */
div.bhoechie-tab-container{
  z-index: 0;
  background-color: #ffffff;
  padding: 0 !important;
  border-radius: 4px;
  -moz-border-radius: 4px;
  border:1px solid #ddd;
  margin-top: 0px;
  margin-left: 0px;
  -webkit-box-shadow: 0 6px 12px rgba(0,0,0,.175);
  box-shadow: 0 6px 12px rgba(0,0,0,.175);
  -moz-box-shadow: 0 6px 12px rgba(0,0,0,.175);
  background-clip: padding-box;
  opacity: 0.97;
  filter: alpha(opacity=97);
}
div.bhoechie-tab-menu{
  padding-right: 0;
  padding-left: 0;
  padding-bottom: 0;
}
div.bhoechie-tab-menu div.list-group{
  margin-bottom: 0;
}
div.bhoechie-tab-menu div.list-group>a{
  margin-bottom: 0;
}
div.bhoechie-tab-menu div.list-group>a .glyphicon,
div.bhoechie-tab-menu div.list-group>a .fa {
  color: #5A55A3;
}
div.bhoechie-tab-menu div.list-group>a:first-child{
  border-top-right-radius: 0;
  -moz-border-top-right-radius: 0;
}
div.bhoechie-tab-menu div.list-group>a:last-child{
  border-bottom-right-radius: 0;
  -moz-border-bottom-right-radius: 0;
}
div.bhoechie-tab-menu div.list-group>a.active,
div.bhoechie-tab-menu div.list-group>a.active .glyphicon,
div.bhoechie-tab-menu div.list-group>a.active .fa{
  background-color: #5A55A3;
  background-image: #5A55A3;
  color: #ffffff;
}
div.bhoechie-tab-menu div.list-group>a.active:after{
  content: '';
  position: absolute;
  left: 100%;
  top: 50%;
  margin-top: -13px;
  border-left: 0;
  border-bottom: 13px solid transparent;
  border-top: 13px solid transparent;
  border-left: 10px solid #5A55A3;
}

div.bhoechie-tab-content{
  background-color: #ffffff;
  /* border: 1px solid #eeeeee; */
  padding-left: 20px;
  padding-top: 10px;
}

div.bhoechie-tab div.bhoechie-tab-content:not(.active){
  display: none;
}


text:
/* Yes, it's called "empty" because it has no contents at all.
   Even this comment goes here, rather than in empty.h.  */
#include "empty.h"

int main(void)
{
  return 0;
}


text:
export module M;

int moduleFunction(int x); // ModuleLinkage

static int staticModuleFunction(int x); // ModuleInternalLinkage

export double exportedModuleFunction(double y, int z); // ExternalLinkage


text:
<?php
/**
 * Created by PhpStorm.
 * User: Luiz Eduardo
 * Date: 08/05/2016
 * Time: 16:34
 */

namespace Acl\Entity;

use Doctrine\ORM\Mapping as ORM;
use Zend\Hydrator\ClassMethods;

/**
 * Class Role
 *
 * @ORM\Table(name="role", schema="security")
 * @ORM\Entity
 * @ORM\Entity(repositoryClass="Acl\Repository\Role")
 * @ORM\HasLifecycleCallbacks
 */
class Role
{
	/**
	 * @var integer
	 * @ORM\Column(name="id", type="integer", nullable=false)
	 * @ORM\Id
	 * @ORM\GeneratedValue(strategy="IDENTITY")
	 */
	protected $id;
	/**
	 * @var integer
	 * @ORM\OneToOne(targetEntity="Acl\Entity\Role")
	 * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
	 */
	protected $parent;
	/**
	 * @var string
	 * @ORM\Column(name="name", type="string", length=255, nullable=false)
	 */
	protected $name;
	/**
	 * @var integer
	 * @ORM\Column(name="is_admin", type="integer", nullable=false)
	 */
	protected $isAdmin;
	/**
	 * @var \DateTime
	 * @ORM\Column(name="created_at", type="datetime", nullable=false)
	 */
	protected $createdAt;
	/**
	 * @var \DateTime
	 * @ORM\Column(name="updated_at", type="datetime", nullable=false)
	 */
	protected $updatedAt;

	public function __construct($options = [])
	{
		(new ClassMethods)->hydrate($options, $this);
		$this->createdAt = new \DateTime("now");
		$this->updatedAt = new \DateTime("now");
	}

	/**
	 * @return int
	 */
	public function getId()
	{
		return $this->id;
	}

	/**
	 * @return int
	 */
	public function getParent()
	{
		return $this->parent;
	}

	/**
	 * @return string
	 */
	public function getName()
	{
		return $this->name;
	}

	/**
	 * @return int
	 */
	public function getIsAdmin()
	{
		return $this->isAdmin;
	}

	/**
	 * @return \DateTime
	 */
	public function getCreatedAt()
	{
		return $this->createdAt->format('d/m/Y H:m:i');
	}

	/**
	 * @return \DateTime
	 */
	public function getUpdatedAt()
	{
		return $this->updatedAt->format('d/m/Y H:m:i');
	}

	/**
	 * @param int $id
	 * @return Role
	 */
	public function setId($id)
	{
		$this->id = $id;

		return $this;
	}

	/**
	 * @param int $parent
	 * @return Role
	 */
	public function setParent($parent)
	{
		$this->parent = $parent;

		return $this;
	}

	/**
	 * @param string $name
	 * @return Role
	 */
	public function setName($name)
	{
		$this->name = $name;

		return $this;
	}

	/**
	 * @param int $isAdmin
	 * @return Role
	 */
	public function setIsAdmin($isAdmin)
	{
		$this->isAdmin = $isAdmin;

		return $this;
	}

	/**
	 * @return Role
	 */
	public function setCreatedAt()
	{
		$this->createdAt = new \DateTime('now');

		return $this;
	}

	/**
	 * @ORM\PreUpdate
	 * @ORM\PrePersist
	 * @return Role
	 */
	public function setUpdatedAt()
	{
		$this->updatedAt = new \DateTime('now');

		return $this;
	}

	public function __toString()
	{
		return $this->getName();
	}

	public function toArray()
	{
		//TODO: se não funcionar corretamente esse extract tem que forcar o retorno em array mesmo
		return (new ClassMethods)->extract($this);
	}
}


text:
<?php

//common environment attributes including search paths. not specific to Learnosity
include_once '../env_config.php';

//site scaffolding
include_once 'includes/header.php';

//common Learnosity config elements including API version control vars
include_once '../lrn_config.php';

use LearnositySdk\Request\Init;
use LearnositySdk\Utils\Uuid;

$security = [
    "consumer_key"    => $consumer_key ,
    "domain"          => $domain
];

$request = [
    'activity_id' => 'Activity_Test',
    'activity_template_id' => 'TexttoSpeech_Testing_Activity',

    'rendering_type' => 'assess',
    'user_id' => '$ANONYMIZED_USER_ID',
    'session_id' => Uuid::generate(),
    'type' => 'submit_practice',
    'name' => 'Test Assessment',
    'config'         => [
        'configuration' => [
            'onsubmit_redirect_url' => 'texthelp.php'
        ],
        'region_overrides' => [
            'right' => [
                [
                    'type' => 'save_button'
                ],
                [
                    'type' => 'fullscreen_button'
                ],
                [
                    'type' => 'accessibility_button'
                ],
                [
                    'type' => 'custom_button',
                    'options' => [
                        'name' => 'SpeechStream',
                        'label' => 'SpeechStream',
                        'icon_class' => 'lrn_btn SpeechStream_btn'
                    ]
                ],
                [
                    'type' => 'verticaltoc_element'
                ]
            ]
        ]
    ]
];

$Init = new Init('items', $security, $consumer_secret, $request);
$signedRequest = $Init->generate();

?>

Using Third-Party Assistive Tools: TextHelp

This demo shows how Texthelp's SpeechStream product can be integrated into a Learnosity assessment with ease.

SpeechStream is a cloud based JavaScript software solution that allows publishers to embed text-to-speech read aloud within their products. This feature is used by students with learning disabilities, such as dyslexia, struggling readers, English language learners, auditory learners, and students with mild vision impairments.

If you have a Texthelp license - it integrates effortlessly with Learnosity.

The SpeechStream Toolbar will appear in the upper right corner of the screen, when the assessment is started.

<?php
    include_once 'views/modals/initialisation-preview.php';
    include_once 'includes/footer.php';


text:
package com.gemstone.gemfire.cache30;

import com.gemstone.gemfire.cache.*;

/**
 * A CacheLoader used in testing.  Users should override
 * the "2" method.
 *
 * @see #wasInvoked
 * @see TestCacheWriter
 *
 * @author David Whitlock
 *
 * @since 3.0
 */
public abstract class TestCacheLoader extends TestCacheCallback
  implements CacheLoader {

  public final Object load(LoaderHelper helper)
    throws CacheLoaderException {

    this.invoked = true;
    return load2(helper);
  }

  public abstract Object load2(LoaderHelper helper)
    throws CacheLoaderException;

}


text:
require 'rails_helper'

RSpec.describe 'entries request:' do
  include Auth0UserHelper

  describe 'GET /entries' do
    let(:user) { create(:user) }

    before do
      log_in_as user
    end

    context 'when logged-in user has entries' do
      before do
        3.times do
          song = create(:song, :for_entry, members: [user.member])
          create(:entry, song:)
        end
      end

      it 'responds 200' do
        get entries_path

        expect(response).to have_http_status :ok
      end
    end

    context 'when logged-in user does not have entries' do
      it 'redirects to /entries/new' do
        get entries_path

        expect(response).to redirect_to new_entry_path
      end
    end
  end

  describe 'GET /entries/new' do
    before do
      log_in_as create(:user)
    end

    context 'when an unpublished live exists' do
      before do
        create(:live, :unpublished, :with_entry_guideline)
      end

      it 'responds 200' do
        get new_entry_path

        expect(response).to have_http_status :ok
      end
    end

    context 'when any unpublished lives does not exist' do
      it 'redirects with alert' do
        get new_entry_path

        expect(response).to have_http_status :redirect
        expect(flash.alert).to eq 'エントリー募集中のライブがありません'
      end
    end
  end

  describe 'POST /entries' do
    let(:user) { create(:user) }
    let(:live) { create(:live, :unpublished, :with_entry_guideline) }
    let(:params) do
      {
        entry: {
          notes: '',
          playable_times_attributes:,
        },
        song: {
          live_id: live.id.to_s,
          name: 'アンプラグドのテーマ',
          artist: '',
          original: '1',
          visibility: 'open',
          comment: '',
          plays_attributes: {
            '0' => {
              instrument: '',
              member_id: user.member.id,
              _destroy: '0',
            },
          },
        },
      }
    end

    before do
      stub_auth0_user(user)
      log_in_as user
    end

    context 'with valid params' do
      let(:playable_times_attributes) do
        {
          '0' => {
            lower: live.date.beginning_of_day.iso8601,
            upper: live.date.end_of_day.iso8601,
            _destroy: '0',
          },
        }
      end

      it 'creates entry and redirect_to /entries' do
        expect { post entries_path, params: }
          .to change(Entry, :count).by(1).and change(PlayableTime, :count).by(1).and change(Song, :count).by(1)

        expect(response).to redirect_to entries_path
      end
    end

    context 'with invalid params' do
      let(:playable_times_attributes) { {} }

      it 'responds 422' do
        expect { post entries_path, params: }
          .to not_change(Entry, :count).and not_change(PlayableTime, :count).and not_change(Song, :count)

        expect(response).to have_http_status :unprocessable_entity
      end
    end
  end

  describe 'GET /entries/:id/edit' do
    let(:entry) { create(:entry) }
    let(:user) { create(:user) }

    before do
      log_in_as user
    end

    context 'with submitter' do
      before do
        entry.update!(member_id: user.member_id)
      end

      it 'responds 200' do
        get edit_entry_path(entry)

        expect(response).to have_http_status :ok
      end
    end

    context 'with player' do
      before do
        create(:play, song: entry.song, member: user.member)
      end

      it 'responds 200' do
        get edit_entry_path(entry)

        expect(response).to have_http_status :ok
      end
    end

    context 'with logged-in user' do
      it 'redirects with alert' do
        get edit_entry_path(entry)

        expect(response).to have_http_status :redirect
        expect(flash.alert).to eq '権限がありません'
      end
    end
  end

  describe 'PATCH /entries/:id' do
    let(:entry) { create(:entry, notes: '', song:, member: user.member) }
    let(:song) { create(:song, :for_entry, name: 'before') }
    let(:user) { create(:user) }
    let(:params) do
      {
        entry: {
          notes: entry_notes,
          playable_times_attributes: entry.playable_times.map.with_index do |playable_time, i|
            [
              i.to_s,
              {
                id: playable_time.id.to_s,
                lower: playable_time.lower.iso8601,
                upper: playable_time.upper.iso8601,
                _destroy: '0',
              },
            ]
          end.to_h,
        },
        song: {
          live_id: entry.song.live_id.to_s,
          name: song_name,
          artist: entry.song.artist,
          original: entry.song.original? ? '1' : '0',
          visibility: entry.song.visibility,
          comment: entry.song.comment,
          plays_attributes: entry.song.plays.map.with_index do |play, i|
            [
              i.to_s,
              {
                id: play.id.to_s,
                instrument: play.instrument,
                member_id: play.member_id,
                _destroy: '0',
              },
            ]
          end.to_h,
        },
      }
    end

    before do
      log_in_as user
    end

    context 'with valid params' do
      let(:entry_notes) { 'ボーカルは座って歌います' }
      let(:song_name) { 'after' }

      it 'updates the entry and redirects to /entries' do
        patch entry_path(entry), params: params

        expect(entry.reload.notes).to eq entry_notes
        expect(entry.song.name).to eq song_name
        expect(response).to redirect_to entries_path
      end
    end

    context 'with invalid params' do
      let(:entry_notes) { 'ボーカルは座って歌います' }
      let(:song_name) { '' }

      it 'responds 422' do
        patch entry_path(entry), params: params

        expect(entry.reload.notes).not_to eq entry_notes
        expect(entry.song.name).not_to eq song_name
        expect(response).to have_http_status :unprocessable_entity
      end
    end
  end

  describe 'DELETE /entries/:id' do
    let(:entry) { create(:entry, member: user.member) }
    let(:user) { create(:user) }

    before do
      log_in_as user
    end

    it 'destroys the entry and redirects to /entries' do
      delete entry_path(entry)

      expect(response).to redirect_to entries_path
      expect { entry.song.reload }.to raise_error ActiveRecord::RecordNotFound
      expect { entry.reload }.to raise_error ActiveRecord::RecordNotFound
    end
  end
end


text:
package com.ibm.profiler.mongo;

import com.mongodb.client.MongoIterable;

/**
 * ProfiledMongoIterable
 *
 * @author Steve McDuff
 */
public interface ProfiledMongoIterable <TResult>
{

    public MongoIterable<TResult> getMongoIterable();

}


text:
package org.activiti.api.runtime.model.impl;

import java.util.Objects;

import org.activiti.api.process.model.BPMNSequenceFlow;

public class BPMNSequenceFlowImpl extends BPMNElementImpl implements BPMNSequenceFlow {

    private String sourceActivityElementId;
    private String sourceActivityName;
    private String sourceActivityType;
    private String targetActivityElementId;
    private String targetActivityName;
    private String targetActivityType;

    public BPMNSequenceFlowImpl() {
    }

    public BPMNSequenceFlowImpl(String elementId,
                            String sourceActivityElementId,
                            String targetActivityElementId) {
        this.setElementId(elementId);
        this.sourceActivityElementId = sourceActivityElementId;
        this.targetActivityElementId = targetActivityElementId;
    }

    @Override
    public String getSourceActivityElementId() {
        return sourceActivityElementId;
    }

    @Override
    public String getSourceActivityName() {
        return sourceActivityName;
    }

    public void setSourceActivityName(String sourceActivityName) {
        this.sourceActivityName = sourceActivityName;
    }

    @Override
    public String getSourceActivityType() {
        return sourceActivityType;
    }

    public void setSourceActivityType(String sourceActivityType) {
        this.sourceActivityType = sourceActivityType;
    }

    @Override
    public String getTargetActivityElementId() {
        return targetActivityElementId;
    }

    @Override
    public String getTargetActivityName() {
        return targetActivityName;
    }

    public void setTargetActivityName(String targetActivityName) {
        this.targetActivityName = targetActivityName;
    }

    @Override
    public String getTargetActivityType() {
        return targetActivityType;
    }

    public void setTargetActivityType(String targetActivityType) {
        this.targetActivityType = targetActivityType;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        BPMNSequenceFlowImpl that = (BPMNSequenceFlowImpl) o;
        return Objects.equals(getElementId(),
                              that.getElementId()) &&
                Objects.equals(sourceActivityElementId,
                               that.getSourceActivityElementId()) &&
                Objects.equals(sourceActivityType,
                               that.getSourceActivityType()) &&
                Objects.equals(sourceActivityName,
                               that.getSourceActivityName()) &&
                Objects.equals(targetActivityElementId,
                               that.getTargetActivityElementId()) &&
                Objects.equals(targetActivityType,
                                  that.getTargetActivityType()) &&
                Objects.equals(targetActivityName,
                                  that.getTargetActivityName());
    }

    @Override
    public int hashCode() {

        return Objects.hash(getElementId(),
                            sourceActivityElementId,
                            targetActivityElementId);
    }

    @Override
    public String toString() {
        return "SequenceFlowImpl{" +
                "sourceActivityElementId='" + sourceActivityElementId + '\'' +
                ", sourceActivityName='" + sourceActivityName + '\'' +
                ", sourceActivityType='" + sourceActivityType + '\'' +
                ", targetActivityElementId='" + targetActivityElementId + '\'' +
                ", targetActivityName='" + targetActivityName + '\'' +
                ", targetActivityType='" + targetActivityType + '\'' +
                '}';
    }
}


text:
QUnit.module('Proximity Profile Abnormal Test', {
  before: function() {
    init();
  }
});

/**
 * Proximityプロファイルの異常系テストを行うクラス。
 * @class
 */
let ProximityProfileAbnormalTest = {};

/**
 * サポートしていないPOSTメソッドで、ondeviceproximityにアクセスするテストを行う。
 *
【HTTP通信】 {
    assert.ok(false, 'json: ' + JSON.stringify(json));
    done();
  }).catch(e => {
    checkSuccessErrorCode(assert, e, 3);
    done();
  });
};
QUnit.test('onDeviceProximityAbnormalTest001', ProximityProfileAbnormalTest.onDeviceProximityAbnormalTest001);

/**
 * サポートしていないPOSTメソッドで、onuserproximityにアクセスするテストを行う。
 *
【HTTP通信】 {
    assert.ok(false, 'json: ' + JSON.stringify(json));
    done();
  }).catch(e => {
    checkSuccessErrorCode(assert, e, 3);
    done();
  });
};
QUnit.test('onUserProximityAbnormalTest001', ProximityProfileAbnormalTest.onUserProximityAbnormalTest001);


text:
"use strict";

const express = require('express');
const path = require('path');

const svg = express();

svg.set('views', path.join(__dirname, 'views'));
svg.set('view engine', 'jade');

svg.locals._basePath = 'svg';

let routerConf = {
  listAttr: {
  }
};

require('../autoCreateRouter')(svg, routerConf);

module.exports = svg;


text:
<!DOCTYPE html>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>100% Pure Fire!</title>

                    100% Pure Firestorm Store

            Dashboard

menu

Products

{{product.title}}, {{product.price}}$

                        <button ng-click="addToCart(product);">Add to cart</button>

{{cart.length}} items in cart, {{getCartPrice()}}$

                 1">
                    x{{product.quantity}}

            <button ng-click="checkOut();">Checkout</button>


text:
```js
Faker.GameOfThrones.character() //=> "Tyrion Lannister"

Faker.GameOfThrones.house() //=> "Stark"

Faker.GameOfThrones.city() //=> "Lannisport"

Faker.GameOfThrones.dragon() //=> "Drogon"
```


text:
package com.infunity.isometricgame.core.view.entityRenderers;

import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.infunity.isometricgame.core.IsometricGame;
import com.infunity.isometricgame.shared.model.entities.Coin;

/**
 * Handles rendering coins on screen
 */
public class CoinsRenderer {

    private Sprite spr;

    public CoinsRenderer() {
        this.spr = new Sprite(IsometricGame.assets.get(IsometricGame.assets.CoinTex, Texture.class));
    }

    public void render(SpriteBatch batch, Coin coin) {
        spr.setPosition(coin.getPositionX() - coin.getWidth() / 2,
                coin.getPositionY() - coin.getHeight() / 2);
        spr.draw(batch);
    }
}


text:
module sz {
	export class SzorozzModel extends illa.EventHandler {

		static OPERATOR_MULTIPLY = 'multiply';
		static OPERATOR_DIVIDE = 'divide';

		private count: number = 0;
		private operator: string;
		private factors: [number, number] = [NaN, NaN];
		private product: number;

		constructor() {
			super();
		}

		newQuestion(): void {
			this.count++;
			this.operator = Math.round(Math.random()) == 0 ? SzorozzModel.OPERATOR_MULTIPLY : SzorozzModel.OPERATOR_DIVIDE;
			this.factors = this.getRandomFactors();
			this.product = this.factors[0] * this.factors[1];
			if (this.product == 0) {
				this.operator = SzorozzModel.OPERATOR_MULTIPLY;
			}
		}

		getRandomFactors(): [number, number] {
			var r: [number, number] = [this.getRandomFactor(), this.getRandomFactor()];
			while (r[0] == this.factors[0] || r[0] == this.factors[1]) {
				r[0] = (r[0] + 1) % 10;
			}
			while (r[1] == this.factors[0] || r[1] == this.factors[1]) {
				r[1] = (r[1] + 1) % 10;
			}
			return r;
		}

		getRandomFactor(): number {
			return Math.round(Math.random() * 10.999 - .5);
		}

		getOperator(): string {
			return this.operator;
		}

		getFactors(): [number, number] {
			return this.factors;
		}

		getProduct(): number {
			return this.product;
		}

		getDividend(): number {
			return this.product;
		}

		getDivisor(): number {
			return this.factors[0];
		}

		getQuotient(): number {
			return this.factors[1];
		}

		isResultCorrect(result: number): boolean {
			var correctResult = NaN;
			if (this.operator == SzorozzModel.OPERATOR_MULTIPLY) {
				correctResult = this.getProduct();
			} else if (this.operator == SzorozzModel.OPERATOR_DIVIDE) {
				correctResult = this.getQuotient();
			}
			return result == correctResult;
		}

		getCount(): number {
			return this.count;
		}
	}
}


text:
package com.zbiljic.nodez.utils;

import java.util.function.Function;

/**
 * A generic pair implementation that can be used to cumulatively aggregate a data structure during
 * a promise pipeline.
 *

 * This can sometimes be useful when collecting facts about something as part of a data stream
 * without using mutable data structures.
 *
 * @param <L> the left data type
 * @param <R> the right data type
 */
public final class Pair<L, R> {

  /**
   * The left item of the pair.
   */
  public final L left;

  /**
   * The right item of the pair.
   */
  public final R right;

  private Pair(L left, R right) {
    this.left = left;
    this.right = right;
  }

  /**
   * Creates a new pair.
   *
   * @param left  the left item
   * @param right the right item
   * @param <L>   the type of the left item
   * @param <R>   the type of the right item
   * @return a new pair
   */
  public static <L, R> Pair<L, R> of(L left, R right) {
    return new Pair<>(left, right);
  }

  /**
   * The left item of the pair.
   *
   * @return the left item of the pair
   */
  public L getLeft() {
    return left;
  }

  /**
   * The right item of the pair.
   *
   * @return the right item of the pair
   */
  public R getRight() {
    return right;
  }

  /**
   * The left item of the pair.
   *
   * @return the left item of the pair
   */
  public L left() {
    return left;
  }

  /**
   * The right item of the pair.
   *
   * @return the right item of the pair
   */
  public R right() {
    return right;
  }

  /**
   * Replaces the left item with the given item.
   *
   * @param newLeft the replacement left side of the pair
   * @param <T>     the new left type
   * @return a new pair, with the given item replacing the left of this
   */
  public <T> Pair<T, R> left(T newLeft) {
    return of(newLeft, right);
  }

  /**
   * Replaces the right item with the given item.
   *
   * @param newRight the replacement right side of the pair
   * @param <T>      the new right type
   * @return a new pair, with the given item replacing the right of this
   */
  public <T> Pair<L, T> right(T newRight) {
    return of(left, newRight);
  }

  /**
   * Creates a new pair.
   *
   * @param left  the left item
   * @param right the right item
   * @param <L>   the type of the left item
   * @param <R>   the type of the right item
   * @return a new pair
   */
  public static <L, R> Pair<L, R> pair(L left, R right) {
    return of(left, right);
  }

  /**
   * Creates a new pair, with {@code this} as the right item and the given value as the left.
   *
   * @param t   the left value for the returned pair
   * @param <T> the type of the left value for the returned pair
   * @return a new pair, with {@code this} as the right item and the given value as the left
   */
  public <T> Pair<T, Pair<L, R>> pushLeft(T t) {
    return of(t, this);
  }

  /**
   * Creates a new pair, with {@code this} as the left item and the given value as the right.
   *
   * @param t   the right value for the returned pair
   * @param <T> the type of the right value for the returned pair
   * @return a new pair, with {@code this} as the left item and the given value as the right
   */
  public <T> Pair<Pair<L, R>, T> pushRight(T t) {
    return of(this, t);
  }

  /**
   * Creates a new pair, with {@code pair(t, this.left)} as the left item and the the right value of
   * {@code this} as the right.
   *
   * @param t   the item to nest with the left item of {@code this} pair
   * @param <T> the type of item to nest with the left item of {@code this} pair
   * @return a new pair, with {@code pair(t, this.left)} as the left item and the the right value of
   * {@code this} as the right
   */
  public <T> Pair<Pair<T, L>, R> nestLeft(T t) {
    return of(of(t, left), right);
  }

  /**
   * Creates a new pair, with {@code pair(t, this.right)} as the right item and the the left value
   * of {@code this} as the left.
   *
   * @param t   the item to nest with the right item of {@code this} pair
   * @param <T> the type of item to nest with the right item of {@code this} pair
   * @return a new pair, with {@code pair(t, this.right)} as the right item and the the left value
   * of {@code this} as the left
   */
  public <T> Pair<L, Pair<T, R>> nestRight(T t) {
    return of(left, of(t, right));
  }

  /**
   * Creates a new pair, with the left item being the result of applying the given function to the
   * left item of {@code this}.
   *

   * The right value is unchanged.
   *
   * @param function a transformer for the left value
   * @param <T>      the type of the new left value
   * @return a new pair, with the left item being the result of applying the given function to the
   * left item of {@code this}
   * @throws Exception any thrown by {@code function}
   */
  public <T> Pair<T, R> mapLeft(Function<? super L, ? extends T> function) throws Exception {
    T t = function.apply(left);
    return of(t, right);
  }

  /**
   * Creates a new pair, with the right item being the result of applying the given function to the
   * right item of {@code this}.
   *

   * The left value is unchanged.
   *
   * @param function a transformer for the right value
   * @param <T>      the type of the new right value
   * @return a new pair, with the right item being the result of applying the given function to the
   * right item of {@code this}
   * @throws Exception any thrown by {@code function}
   */
  public <T> Pair<L, T> mapRight(Function<? super R, ? extends T> function) throws Exception {
    T t = function.apply(right);
    return of(left, t);
  }

  /**
   * Applies the given function to {@code this}, returning the result.
   *
   * @param function a function to apply to {@code this}
   * @param <T>      the function result type
   * @return the result of applying {@code function} to {@code this}
   * @throws Exception any thrown by {@code function}
   */

  public <T> T map(Function<? super Pair<L, R>, ? extends T> function) throws Exception {
    return function.apply(this);
  }

  /**
   * Convenience function for returning the left item of a pair.
   *
   * @param <L> the type of the left item
   * @param
 the pair type
   * @return a function that when applied to a pair returns the left item
   */
  public static <L, P extends Pair<L, ?>> Function
 unpackLeft() {
    return pair -> pair.left;
  }

  /**
   * Convenience function for returning the right item of a pair.
   *
   * @param <R> the type of the right item
   * @param
 the pair type
   * @return a function that when applied to a pair returns the right item
   */
  public static <R, P extends Pair<?, R>> Function
 unpackRight() {
    return pair -> pair.right;
  }

  /**
   * A pair is equal if its left and right items are equal to the left and right items of {@code
   * this} respectively.
   *
   * @param o the object to compare to
   * @return the equality
   */
  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    Pair<?, ?> pair = (Pair<?, ?>) o;

    return !(left != null ? !left.equals(pair.left) : pair.left != null) && !(right != null ? !right.equals(pair.right) : pair.right != null);
  }

  /**
   * Hash code.
   *
   * @return hash code.
   */
  @Override
  public int hashCode() {
    int result = left != null ? left.hashCode() : 0;
    result = 31 * result + (right != null ? right.hashCode() : 0);
    return result;
  }

  /**
   * Returns "Pair[«left.toString()»,«right.toString()»].
   *
   * @return "Pair[«left.toString()»,«right.toString()»]
   */
  @Override
  public String toString() {
    return "Pair[" + left + "," + right + ']';
  }

}


text:
#include "phd.h"

#ifdef GUIDE_EQUINOX

#if defined (__APPLE__)
#include <CoreServices/CoreServices.h>
//#include <CoreServices/AppleEvents.h>
//#include <Foundation/Foundation.h>
//#include <AppleEvents.h>
//#include <AEDataModel.h>

// Code originally from Darryl @ Equinox

OSErr ScopeEquinox::E6AESendRoutine(double ewCorrection, double nsCorrection, int mountcode) {
// correction values (+- seconds) to send to E6

    OSErr err;
    FourCharCode E6Sig = 'MPj6';  // the Equinox 6 creator signature
    if (mountcode == SCOPE_EQMAC)
        E6Sig = 'EQMC';
    FourCharCode phdSig = 'PhDG';  // ***** you need to fill in your app signature here ******
    AEAddressDesc addDesc;

    AEEventClass evClass = 'phdG';  // the phd guide class.
    AEEventID evID = 'evGD';  // the phd guide event.
    AEKeyword  keyObject;
    AESendMode mode = kAEWaitReply;  //  you want something back

    // create Apple Event with Equinox 6 signature

    err = AECreateDesc( typeApplSignature, (Ptr) &E6Sig, sizeof(FourCharCode), &addDesc );  // make a description
    if( err != noErr ) return err;

    err = AECreateAppleEvent( evClass, evID, &addDesc, kAutoGenerateReturnID, kAnyTransactionID, &E6Event );  // create the AE
    if( err != noErr ) {
        AEDisposeDesc( &addDesc );
        return err;
    }

    // create the return Apple Event with your signature (so I know where to send it)

    err = AECreateDesc( typeApplSignature, (Ptr) &phdSig, sizeof(FourCharCode), &addDesc );
    if( err != noErr ) {
        AEDisposeDesc( &E6Event );
        return err;
    }

    err = AECreateAppleEvent( evClass, evID, &addDesc, kAutoGenerateReturnID, kAnyTransactionID, &E6Return );
    if( err != noErr ) {
        AEDisposeDesc( &E6Event );
        AEDisposeDesc( &addDesc );
        return err;
    }

    // put the correction values into parameters - I have used doubles for a ew and ns seconds correction

    keyObject = 'prEW';  // EW correction AE parameter (+ = east, - = west)
    err = AEPutParamPtr( &E6Event, keyObject, typeIEEE64BitFloatingPoint,  &ewCorrection, sizeof(double) );
    if( err != noErr ) {
        AEDisposeDesc( &E6Event );
        AEDisposeDesc( &addDesc );
        return err;
    }

    keyObject = 'prNS';  // NS correction AE parameter (+ = north, - = south)
    err = AEPutParamPtr( &E6Event, keyObject, typeIEEE64BitFloatingPoint, &nsCorrection, sizeof(double) );
    if( err != noErr ) {
        AEDisposeDesc( &E6Event );
        AEDisposeDesc( &addDesc );
        return err;
    }

    // you now have the send AE, the return AE and the correction values in AE parameters - so send it!

    err = AESendMessage( &E6Event, &E6Return, mode, kAEDefaultTimeout );  // you can specify a wait time (in ticks)
    if( err != noErr ) {  // Note: an error of -600 means E6 is not currently running
        AEDisposeDesc( &E6Event );
        AEDisposeDesc( &addDesc );
        return err;
    }

    // at this point you have received the return AE from E6, so go read the return code (what do you want returned ??)
    // the return code could indicate that E6 got the AE, can do it, or can't for some reason. You do NOT want to wait
    // until the corrections have been applied - you should time that on your own.

    keyObject = 'prRC';  // get return code
    Size returnSize;
    DescType returnType;
    err = AEGetParamPtr( &E6Return, keyObject, typeSInt16, &returnType, &E6ReturnCode, sizeof(SInt16), &returnSize );

    AEDisposeDesc( &E6Event );
    AEDisposeDesc( &addDesc );
    return 0;
}

bool ScopeEquinox::Connect() {
    // Check the E6 connection by sending 0,0 to it and checking E6Return
    OSErr err = E6AESendRoutine(0.0,0.0,SCOPE_EQUINOX);
    wxString prefix = "E6";
//  if (mountcode == SCOPE_EQMAC) prefix = "EQMAC";
    if (E6ReturnCode == -1) {
        wxMessageBox (prefix + " responded it's not connected to a mount",_("Error"));
        return true;
    }
    else if (err == -600) {
        wxMessageBox (prefix + " not running",_("Error"));
        return true;
    }

    Scope::Connect();

    return false;
}

Mount::MOVE_RESULT ScopeEquinox::Guide(GUIDE_DIRECTION direction, int duration)
{
    double NSTime = 0.0;
    double EWTime = 0.0;

    switch (direction) {
        case NORTH:
            NSTime = (double) duration / 1000.0;
            break;
        case SOUTH:
            NSTime = (double) duration / -1000.0;
            break;
        case EAST:
            EWTime = (double) duration / 1000.0;
            break;
        case WEST:
            EWTime = (double) duration / -1000.0;
            break;
    }
    OSErr err = E6AESendRoutine(EWTime, NSTime,SCOPE_EQUINOX);
    wxString prefix = "E6";
    //if (mountcode == SCOPE_EQMAC) prefix = "EQMAC";
    if (E6ReturnCode == -1) {
        pFrame->Alert(prefix + _(" responded it's not connected to a mount"));
        return MOVE_ERROR;
    }
    else if (err == -600) {
        pFrame->Alert(prefix + _(" not running"));
        return MOVE_ERROR;
    }
    wxMilliSleep(duration);

    return MOVE_OK;
}

#endif
#endif /* GUIDE_EQUINOX */


text:
<?php

    if (!function_exists('array_to_object')) {
        /**
         * Convert an array to an object.
         *
         * @param $data
         *
         * @return mixed
         */
        function array_to_object($data)
        {
            return json_decode(json_encode($data));
        }
    }

    if (!function_exists('object_to_array')) {
        /**
         * Convert an object to an array.
         *
         * @param $data
         *
         * @return mixed
         */
        function object_to_array($data)
        {
            return json_decode(json_encode($data), true);
        }
    }

    if (!function_exists('xml_to_array')) {
        /**
         * Convert an object to an array.
         *
         * @param $data
         *
         * @return mixed
         */
        function xml_to_array($data)
        {
            return object_to_array(simplexml_load_string($data));
        }
    }


text:
import { connectivityReducer, DEFAULT_STATE } from "../reducer";
import { networkUp, networkDown } from "../actions";

describe("connectivityReducer", () => {
  it("ignores `bot.mqtt` because that is handled by PING_OK/PING_NO", () => {
    const state = connectivityReducer(DEFAULT_STATE, networkUp("bot.mqtt"));
    expect(state).toEqual(DEFAULT_STATE);
  });

  it("goes up", () => {
    const state = connectivityReducer(DEFAULT_STATE,
      networkUp("user.mqtt"));
    expect(state).toBeDefined();
    const x = state && state.uptime["user.mqtt"];
    expect(x?.state).toBe("up");
    expect(x?.at).toBeTruthy();
  });

  it("goes down", () => {
    const state = connectivityReducer(DEFAULT_STATE,
      networkDown("user.api"));
    const x = state && state.uptime["user.api"];
    expect(x?.state).toBe("down");
    expect(x?.at).toBeTruthy();
  });
});


text:
"use strict";

/*
 * Performs an insert/update on a CouchDB document.  Where a document
 * with the provided ID already exists, optionally runs user defined
 * functions for either skipping an update (based on the existing document)
 * or merging.
 *
 */

var extend = require("./lib/extend"),
    omit = require("./lib/omit");

module.exports = function () {
    return new NanoDocUpdater();
};

function NanoDocUpdater () {
    this._db = null;
    this._existingDoc = null;
    this._newDoc = null;
    this._shouldUpdate = null;
    this._merge = null;
    this._id = null;
    this._shouldCreate = true;
}

(function () {
    ["db", "existingDoc", "newDoc", "id", "shouldUpdate", "shouldCreate", "merge"].forEach(function (f) {
        NanoDocUpdater.prototype[f] = function (newValue) {
            this["_" + f] = newValue;
            return this;
        };
    }.bind(this));

    NanoDocUpdater.prototype.update = function (callback) {
        updateDocument(
            this._existingDoc,
            this._newDoc,
            this._id,
            this._db,
            this._shouldUpdate,
            this._shouldCreate,
            this._merge,
            callback
        );
    };

    NanoDocUpdater.prototype.updateJob = function () {
        var existingDoc = this._existingDoc;
        var newDoc = this._newDoc;
        var id = this._id;
        var db = this._db;
        var shouldUpdate = this._shouldUpdate;
        var shouldCreate = this._shouldCreate;
        var merge = this._merge;

        return function (callback) {
            updateDocument(
                existingDoc,
                newDoc,
                id,
                db,
                shouldUpdate,
                shouldCreate,
                merge,
                callback
            );
        };
    };
}());

/* Says ``always do something'' */
function always(/*existing, newVer*/) {
    return true;
}

/* Given two documents (an existing one and a new one) returns a new one.
 */
function useNewVersion(existing, newVer) {
    return newVer;
}

/* Create-or-update a document: First fetch the existing revision, then
   insert a new one.  Optional f_ShouldUpdate and f_Merge functions
   control the specifics of merging. */
function updateDocument(existingDoc, newDoc, id, db, f_ShouldUpdate, shouldCreate, f_Merge, callback) {
    if (!f_ShouldUpdate) {
        f_ShouldUpdate = always;
    }

    if (!f_Merge) {
        f_Merge = useNewVersion;
    }

    // If we never grabbed the existing document from the DB, fetch it and try again.
    if (!existingDoc) {
        return db.get(id, function (err, r) {
            // If the fetch came back with nothing, attempt to do a fresh insert unless the user
            // doesn't want documents to be created.
            if (err && (err.error === "not_found")) {
                if (!shouldCreate)
                    // Don't create a document where one didn't exist, if the user so desires.
                    return callback(null, null);

                return db.insert(newDoc, id, function (err, r) {
                    // If someone beat us here, we should retry this whole operation.
                    if (err && err.error === "conflict")
                        return updateDocument(null, newDoc, id, db, f_ShouldUpdate, shouldCreate, f_Merge, callback);

                    // If anything else happened, we should bail.
                    if (err)
                        return callback("Could not fetch existing document: " + err.toString());

                    // The insert worked.  We're done.
                    return callback(null, extend({}, newDoc, {_rev: r.rev}));
                });
            }

            // If the fetch came back with any other error, bail.
            if (err)
                return callback("Could not fetch existing document: " + err.toString());

            // We got the document.  Let's try the update again.
            return updateDocument(r, newDoc, id, db, f_ShouldUpdate, shouldCreate, f_Merge, callback);
        });
    }

    if (!f_ShouldUpdate(existingDoc, newDoc)) {
        return callback(null, existingDoc);
    }

    // Before merging, record that we want to undelete a document that has been deleted.
    var mergedDoc = f_Merge(omit(existingDoc, "_deleted"), newDoc);
    if (!mergedDoc || typeof mergedDoc !== "object" || mergedDoc instanceof Error) {
        // Allow a user defined merge algorithm to say ``sorry...can't merge'' by returning a non-object or Error.
        // Bubble this error, so that the user can then test for it in their callback.
        return callback(mergedDoc);
    }

    // It's essential that we specify a revision or this will never terminate.
    // It's probably not a good idea to trust a user-specified merge function to do this.
    mergedDoc = extend({}, mergedDoc, { _rev: existingDoc._rev });

    // The document exists, and is out of date.  We need to overwrite it.
    db.insert(
        mergedDoc,
        id,
        function (err, result) {
            // If someone beat us here, we need to try the whole thing again.
            if (err && err.error === "conflict")
                return updateDocument(null, newDoc, id, db, f_ShouldUpdate, shouldCreate, f_Merge, callback);

            // If anything else happened, bail.
            if (err)
                return callback("Could not update the document to the proposed version: " + err.toString());

            // Update the new document's _rev
            mergedDoc._rev = result.rev;

            // The replacement worked.  We're done.  Finally!
            return callback(null, mergedDoc);
        }
    );
}


text:
'use strict';

class ContextReadyCommand {
    execute(event) {
        const context = event.context;
        const logger = context.getLogger('app-run');
        logger.info('Context ready command...');
        context.dispatch('media.upload');
        context.dispatch('media.list');
    }

}

ContextReadyCommand.ID = 'ContextReadyCommand';

module.exports = ContextReadyCommand;


text:
layout: post
title:  "Parsing with Clojure and Instaparse"
date:   2018-05-17 12:00:00
tags:   clojure parse parsing instaparse grammar
---

Parsing is fun, and I've covered some simple Parsec-style parsers in previous posts, but this one's about Clojure and Instaparse. Instead of building up parsers with combinators, Instaparse takes a grammar as a string and generates a parser. I think this makes for more concise parser definitions that are both easier to write and understand after the fact.

## Bowling Scores

I'm not much of a bowler, but the game has an interesting scoring notation with some special rules. I don't even know if this parser is totally _correct_ but it should be very close. Generally the grammar definitions start _top to bottom_ so things are declared in reverse dependency order. The top line is the general format—ten frames of bowling where each frame is `F` and `10TH` has special rules. Reading downward you can see more terms are defined and combined.

```clojure
(def bowling-score-parser
  (insta/parser
    "S = F F F F F F F F F 10TH
     F = OPEN | CLOSED
     OPEN = ROLL ROLL
     CLOSED = STRIKE | SPARE
     10TH = OPEN |
            SPARE (STRIKE | ROLL) |
            STRIKE (SPARE | ROLL ROLL) |
            STRIKE STRIKE (STRIKE | ROLL)
     STRIKE = 'X'
     SPARE = ROLL '/'
     ROLL = PINS | MISS
     PINS = #'[1-9]'
     MISS = '-'"))
```

And the parser outputs a tree of tagged values:
```clojure
(bowling-score-parser "6271X9-8/XX3572-/X")
=>
[:S
 [:F [:OPEN [:ROLL [:PINS "6"]] [:ROLL [:PINS "2"]]]]
 [:F [:OPEN [:ROLL [:PINS "7"]] [:ROLL [:PINS "1"]]]]
 [:F [:CLOSED [:STRIKE "X"]]]
 [:F [:OPEN [:ROLL [:PINS "9"]] [:ROLL [:MISS "-"]]]]
 [:F [:CLOSED [:SPARE [:ROLL [:PINS "8"]] "/"]]]
 [:F [:CLOSED [:STRIKE "X"]]]
 [:F [:CLOSED [:STRIKE "X"]]]
 [:F [:OPEN [:ROLL [:PINS "3"]] [:ROLL [:PINS "5"]]]]
 [:F [:OPEN [:ROLL [:PINS "7"]] [:ROLL [:PINS "2"]]]]
 [:10TH [:SPARE [:ROLL [:MISS "-"]] "/"] [:STRIKE "X"]]]

;; some more scores to try
(bowling-score-parser "XXXXX6/XX7/XX5")
(bowling-score-parser "XXXXXXXXXXXX")
(bowling-score-parser "XXXXXXXXXX-/")
(bowling-score-parser "XXXXXXXXX--")
(bowling-score-parser "9-9-9-9-9-9-9-9-9-9-")
(bowling-score-parser "X7/9-X-88/-6XXX81")
(bowling-score-parser "X7/9-X-88/-6XX-/X")
(bowling-score-parser "X-/X5-8/9-X811-4/X")
```

## Nested Infix Expressions

This is a nice example of the power of recursive parsers. Notice how the root `S` term is used several times in other terms. This allows for a simple grammar that can parse complex expressions like `((2*3)+1+2)/4`.

```clojure
(def expr-parser
  (insta/parser
    "<S> = VAL | EXPR | PAR
     PAR = <'('> S <')'>
     <EXPR> = S OP S
     VAL = #'[0-9]+'
     OP = '+' | '-' | '*' | '/'"))
```

The `<`angle brackets`>` around LHS terms indicate we don't want those outputs tagged, and angle brackets on the RHS indicate the parsed value shouldn't be returned at all. Omitting tags can make the output easier to work with, and in this case we don't care about the actual parentheses characters.

```clojure
(expr-parser "((2*3)+1+2)/4")
=> ([:PAR [:PAR [:VAL "2"] [:OP "*"] [:VAL "3"]]
          [:OP "+"] [:VAL "1"] [:OP "+"] [:VAL "2"]]
    [:OP "/"] [:VAL "4"])
```

Then with a simple `prewalk` we can interpret the output, ultimately transforming the string into its pure data structure form:
```clojure
(walk/prewalk
  (fn [e]
    (if (vector? e)
      (let [[tag val :as p] e]
        (case tag
          :PAR (rest p)
          :VAL (Integer/parseInt val)
          :OP (symbol val)
          p))
      e))
  (expr-parser "((2*3)+1+2)/4"))
=> (((2 * 3) + 1 + 2) / 4)
```

Update: after reading [this great article by Carin Meier](http://gigasquidsoftware.com/blog/2013/05/01/growing-a-language-with-clojure-and-instaparse/) I saw Instaparse provides a convenient `transform` function that can be passed a map from tags to value-interpreter functions:
```clojure
(instaparse.transform/transform
  {:PAR list
   :VAL #(Integer/parseInt %)
   :OP symbol}
  (expr-parser "1+(2+3)*(3/3)"))
=> (1 + (2 + 3) * (3 / 3))
```

Happy parsing!


text:
BOOST_AUTO_TEST_SUITE(bech32_tests)

BOOST_AUTO_TEST_CASE(bech32_testvectors_valid)
{
    static const std::string CASES[] = {
        "A12UEL5L",
        "a12uel5l",
        "an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs",
        "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
        "11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j",
        "split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w",
        "?1ezyfcl",
    };
    for (const std::string& str : CASES) {
        const auto dec = bech32::Decode(str);
        BOOST_CHECK(dec.encoding == bech32::Encoding::BECH32);
        std::string recode = bech32::Encode(bech32::Encoding::BECH32, dec.hrp, dec.data);
        BOOST_CHECK(!recode.empty());
        BOOST_CHECK(CaseInsensitiveEqual(str, recode));
    }
}

BOOST_AUTO_TEST_CASE(bech32m_testvectors_valid)
{
    static const std::string CASES[] = {
        "A1LQFN3A",
        "a1lqfn3a",
        "an83characterlonghumanreadablepartthatcontainsthetheexcludedcharactersbioandnumber11sg7hg6",
        "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx",
        "11llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllludsr8",
        "split1checkupstagehandshakeupstreamerranterredcaperredlc445v",
        "?1v759aa"
    };
    for (const std::string& str : CASES) {
        const auto dec = bech32::Decode(str);
        BOOST_CHECK(dec.encoding == bech32::Encoding::BECH32M);
        std::string recode = bech32::Encode(bech32::Encoding::BECH32M, dec.hrp, dec.data);
        BOOST_CHECK(!recode.empty());
        BOOST_CHECK(CaseInsensitiveEqual(str, recode));
    }
}

BOOST_AUTO_TEST_CASE(bech32_testvectors_invalid)
{
    static const std::string CASES[] = {
        " 1nwldj5",
        "\x7f""1axkwrx",
        "\x80""1eym55h",
        "an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx",
        "pzry9x0s0muk",
        "1pzry9x0s0muk",
        "x1b4n0q5v",
        "li1dgmt3",
        "de1lg7wt\xff",
        "A1G7SGD8",
        "10a06t8",
        "1qzzfhee",
        "a12UEL5L",
        "A12uEL5L",
        "abcdef1qpzrz9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
    };
    static const std::pair<std::string, int> ERRORS[] = {
        {"Invalid character or mixed case", 0},
        {"Invalid character or mixed case", 0},
        {"Invalid character or mixed case", 0},
        {"Bech32 string too long", 90},
        {"Missing separator", -1},
        {"Invalid separator position", 0},
        {"Invalid Base 32 character", 2},
        {"Invalid separator position", 2},
        {"Invalid character or mixed case", 8},
        {"Invalid checksum", -1}, // The checksum is calculated using the uppercase form so the entire string is invalid, not just a few characters
        {"Invalid separator position", 0},
        {"Invalid separator position", 0},
        {"Invalid character or mixed case", 3},
        {"Invalid character or mixed case", 3},
        {"Invalid checksum", 11}
    };
    int i = 0;
    for (const std::string& str : CASES) {
        const auto& err = ERRORS[i];
        const auto dec = bech32::Decode(str);
        BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
        std::vector<int> error_locations;
        std::string error = bech32::LocateErrors(str, error_locations);
        BOOST_CHECK_EQUAL(err.first, error);
        if (err.second == -1) BOOST_CHECK(error_locations.empty());
        else BOOST_CHECK_EQUAL(err.second, error_locations[0]);
        i++;
    }
}

BOOST_AUTO_TEST_CASE(bech32m_testvectors_invalid)
{
    static const std::string CASES[] = {
        " 1xj0phk",
        "\x7f""1g6xzxy",
        "\x80""1vctc34",
        "an84characterslonghumanreadablepartthatcontainsthetheexcludedcharactersbioandnumber11d6pts4",
        "qyrz8wqd2c9m",
        "1qyrz8wqd2c9m",
        "y1b0jsk6g",
        "lt1igcx5c0",
        "in1muywd",
        "mm1crxm3i",
        "au1s5cgom",
        "M1VUXWEZ",
        "16plkw9",
        "1p2gdwpf",
        "abcdef1l7aum6echk45nj2s0wdvt2fg8x9yrzpqzd3ryx",
    };
    static const std::pair<std::string, int> ERRORS[] = {
        {"Invalid character or mixed case", 0},
        {"Invalid character or mixed case", 0},
        {"Invalid character or mixed case", 0},
        {"Bech32 string too long", 90},
        {"Missing separator", -1},
        {"Invalid separator position", 0},
        {"Invalid Base 32 character", 2},
        {"Invalid Base 32 character", 3},
        {"Invalid separator position", 2},
        {"Invalid Base 32 character", 8},
        {"Invalid Base 32 character", 7},
        {"Invalid checksum", -1},
        {"Invalid separator position", 0},
        {"Invalid separator position", 0},
        {"Invalid checksum", 21},
    };
    int i = 0;
    for (const std::string& str : CASES) {
        const auto& err = ERRORS[i];
        const auto dec = bech32::Decode(str);
        BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
        std::vector<int> error_locations;
        std::string error = bech32::LocateErrors(str, error_locations);
        BOOST_CHECK_EQUAL(err.first, error);
        if (err.second == -1) BOOST_CHECK(error_locations.empty());
        else BOOST_CHECK_EQUAL(err.second, error_locations[0]);
        i++;
    }
}

BOOST_AUTO_TEST_SUITE_END()


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>Uses of Class name.fraser.neil.plaintext.diff_match_patch.LinesToCharsResult</title>
<meta name="date" content="2014-10-29">
<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes

Uses of Class
name.fraser.neil.plaintext.diff_match_patch.LinesToCharsResult

Packages that use diff_match_patch.LinesToCharsResult

Package
Description

name.fraser.neil.plaintext

External sources.

Uses of diff_match_patch.LinesToCharsResult in name.fraser.neil.plaintext

Methods in name.fraser.neil.plaintext that return diff_match_patch.LinesToCharsResult

Modifier and Type
Method and Description

protected diff_match_patch.LinesToCharsResult
diff_match_patch.diff_linesToChars(java.lang.String text1,
                 java.lang.String text2)

Split two texts into a list of strings.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes


text:
package cn.netkiller.pojo;

import java.util.List;

public class Deploy {

	private String group;
	private String project;
	private String branch;
	private List<String> arguments;
	public Deploy() {
		// TODO Auto-generated constructor stub
	}
	public String getGroup() {
		return group;
	}
	public void setGroup(String group) {
		this.group = group;
	}

	public String getBranch() {
		return branch;
	}
	public void setBranch(String branch) {
		this.branch = branch;
	}
	public String getProject() {
		return project;
	}
	public void setProject(String project) {
		this.project = project;
	}
	public List<String> getArguments() {
		return arguments;
	}
	public void setArguments(List<String> arguments) {
		this.arguments = arguments;
	}
	@Override
	public String toString() {
		return "Deploy [group=" + group + ", project=" + project + ", branch=" + branch + ", arguments=" + arguments + "]";
	}
}


text:
package ru.job4j.userconvert;

import org.junit.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
/**
 * UserConvertTest for task "2. Написать программу преобразования List в Map".
 * @author Wladyslaw Lazin (wladislaw.lazin@gmail.com)
 * @version $Id$
 * @since 27.11.17
 */
public class UserConvertTest {
    /**
     * whenUsersListConvertToMap.
     */
    @Test
    public void  whenUsersListConvertToMap() {
        UserConvert userConvert = new UserConvert();
        List<User> userList = new ArrayList<>();
        User robertSmith = new User("Robert Smith", "New York", 1);
        User angusYoung = new User("Angus Young", "Sidney", 2);
        userList.add(robertSmith);
        userList.add(angusYoung);
        HashMap<Integer, User> result = userConvert.process(userList);
        HashMap<Integer, User> expected = new HashMap<>();
        expected.put(1, robertSmith);
        expected.put(2, angusYoung);
        assertThat(result, is(expected));
    }
}


text:
package com.azhuoinfo.gbf;

import mobi.cangol.mobile.CoreApplication;
import mobi.cangol.mobile.logging.Log;
import mobi.cangol.mobile.service.AppService;
import mobi.cangol.mobile.service.ServiceProperty;
import mobi.cangol.mobile.service.conf.ConfigService;
import mobi.cangol.mobile.service.crash.CrashReportListener;
import mobi.cangol.mobile.service.crash.CrashService;
import mobi.cangol.mobile.service.global.GlobalData;
import mobi.cangol.mobile.service.status.StatusService;
import mobi.cangol.mobile.utils.DeviceInfo;
import mobi.cangol.mobile.utils.FileUtils;
import com.azhuoinfo.gbf.api.ApiContants;
import com.azhuoinfo.gbf.db.DatabaseHelper;
import com.azhuoinfo.gbf.utils.Constants;

import org.OpenUDID.OpenUDID_manager;

import android.content.Context;
import android.content.SharedPreferences;

import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.utils.StorageUtils;

public class MobileApplication extends CoreApplication {
	public final String TAG = "MobileApplication";
	private static final boolean LIFECYCLE = Constants.DEVMODE;
	private GlobalData globalData;
	private StatusService statusService;
	private AccountVerify accountVerify;
	private DatabaseHelper databaseHelper;
	private long starttime;
	private AppStatusListener appStatusListener;
	@Override
	public void onCreate() {
		if (LIFECYCLE)
			Log.v("onCreate "+System.currentTimeMillis());
		this.setDevMode(Constants.DEVMODE);
		super.onCreate();
		init();
        Log.d("test");
	}

	/**
	 *
	 */
	public void init() {
		if (LIFECYCLE)
			Log.v("init");

		Log.v("starttime:"+(starttime=System.currentTimeMillis()));
		initStatus();
		Log.v("initStatus QOS:"+((System.currentTimeMillis()-starttime)/1000.0f));

		Log.v("starttime:"+(starttime=System.currentTimeMillis()));
		initAppService();
		Log.v("initAppService QOS:"+((System.currentTimeMillis()-starttime)/1000.0f));

		Log.v("starttime:"+(starttime=System.currentTimeMillis()));
		initDataBase();
		Log.v("initDataBase QOS:"+((System.currentTimeMillis()-starttime)/1000.0f));

		Log.v("starttime:"+(starttime=System.currentTimeMillis()));
		initDownload();
		Log.v("initDownload QOS:"+((System.currentTimeMillis()-starttime)/1000.0f));

		Log.v("starttime:"+(starttime=System.currentTimeMillis()));
		initPush();
		Log.v("initPush QOS:"+((System.currentTimeMillis()-starttime)/1000.0f));

		Log.v("starttime:"+(starttime=System.currentTimeMillis()));
		initImageLoader();
		Log.v("initImageLoader QOS:"+((System.currentTimeMillis()-starttime)/1000.0f));

		SharedPreferences sharedPreferences=this.getSharedPreferences(Constants.SHARED, Context.MODE_PRIVATE);
		if(!sharedPreferences.contains("CHANNEL_ID")){
			String channel_id=String.valueOf(DeviceInfo.getAppMetaData(this, "CHANNEL_ID")) ;
			sharedPreferences.edit().putString("CHANNEL_ID", channel_id).commit();
		}
	}

	private void initImageLoader(){
		ImageLoaderConfiguration config =null;
		DisplayImageOptions dio = new DisplayImageOptions.Builder()
        .cacheOnDisk(true)
        .imageScaleType(ImageScaleType.EXACTLY)
        .build();
		if(this.isDevMode()){
			config = new ImageLoaderConfiguration.Builder(this)
			.defaultDisplayImageOptions(dio)
			.threadPriority(Thread.NORM_PRIORITY - 2)
			.denyCacheImageMultipleSizesInMemory()
			.diskCache(new UnlimitedDiscCache(StorageUtils.getOwnCacheDirectory(getApplicationContext(), Constants.APP_IMAGE)))
			.diskCacheFileNameGenerator(new Md5FileNameGenerator())
			.diskCacheSize(200*1024*1024)
			.memoryCache(new WeakMemoryCache())
			.tasksProcessingOrder(QueueProcessingType.LIFO)
			//.writeDebugLogs()
			.build();
		}else{

			config = new ImageLoaderConfiguration.Builder(this)
			.defaultDisplayImageOptions(dio)
			.threadPriority(Thread.NORM_PRIORITY - 2)
			.denyCacheImageMultipleSizesInMemory()
			.diskCache(new UnlimitedDiscCache(StorageUtils.getOwnCacheDirectory(getApplicationContext(), Constants.APP_IMAGE)))
			.diskCacheFileNameGenerator(new Md5FileNameGenerator())
			.diskCacheSize(200*1024*1024)
			//.memoryCache(new WeakMemoryCache())
			.tasksProcessingOrder(QueueProcessingType.LIFO)
			.build();
		}
		// Initialize ImageLoader with configuration.
		ImageLoader.getInstance().init(config);
	}

	private void initPush(){
		Log.d("初始化JPush");
	}

	private void initStatus() {
		if (LIFECYCLE)
			Log.v("initStatus");
		Log.d("MD5Fingerprint "+DeviceInfo.getMD5Fingerprint(this));

		Log.d("初始化OpenUDID");
		OpenUDID_manager.sync(this);

		Log.d("初始化AccountVerify");
		accountVerify = AccountVerify.getInstance(this);
	}

	public void initAppService() {
		if (LIFECYCLE)
			Log.v("initAppService");

		Log.d("初始化ConfigService");
		ConfigService configService = (ConfigService) getAppService(AppService.CONFIG_SERVICE);
		ServiceProperty p=configService.getServiceProperty();
		p.putString(ConfigService.APP_DIR, Constants.APP_DIR);
		p.putString(ConfigService.SHARED_NAME, Constants.SHARED);

		Log.v("getAppDir:" + configService.getAppDir());

		Log.d("初始化StatusService");
		statusService = (StatusService) getAppService(AppService.STATUS_SERVICE);
		appStatusListener = new AppStatusListener();
		statusService.registerStatusListener(appStatusListener);

		Log.d("初始化GlobalData");
		globalData=(GlobalData) getAppService(AppService.GLOBAL_DATA);

		Log.d("初始化CrashService");
		CrashService crashService = (CrashService) getAppService(AppService.CRASH_SERVICE);
		crashService.setDebug(false);
		Log.d("开发模式 不报告crash");
		if(this.isDevMode())
			crashService.report(new CrashReportListener(){

				@Override
				public void report(String path,String error,String position,String context,String timestamp,String fatal) {
					Log.d("sendException "+error);
					FileUtils.delFileAsync(path);

				}

		});

	}

	public void initDataBase() {
		databaseHelper=DatabaseHelper.createDataBaseHelper(this);
		Log.d(TAG,"Database: Name="+databaseHelper.getDataBaseName()+", Version="+databaseHelper.getDataBaseVersion());
	}

	public void initDownload() {

	}
	public AccountVerify getAccountVerify() {
		return accountVerify;
	}

	public void setAccountVerify(AccountVerify accountVerify) {
		this.accountVerify = accountVerify;
	}

	@Override
	public void exit() {
		//完全退出,停止PUSH
		//JPushInterface.stopPush(this);
		//JPushInterface.onKillProcess(this);
		ImageLoader.getInstance().destroy();
		super.exit();
	}

}