<commit_before>import { createAction } from 'redux-act'

import { onDatabaseChange } from 'src/pouchdb'
import { filterVisitsByQuery } from 'src/search'
import { deleteVisitAndPage } from 'src/page-storage/deletion'

import { ourState } from './selectors'

// == Simple commands to change the state in reducers ==

export const setQuery = createAction('overview/setQuery')
export const setSearchResult = createAction('overview/setSearchResult')
export const showLoadingIndicator = createAction('overview/showLoadingIndicator')
export const hideLoadingIndicator = createAction('overview/hideLoadingIndicator')
export const setStartDate = createAction('overview/setStartDate')
export const setEndDate = createAction('overview/setEndDate')
export const hideVisit = createAction('overview/hideVisit')

// == Actions that trigger other actions ==

// Initialisation
export function init() {
    return function (dispatch, getState) {
        // Perform an initial search to populate the view (empty query = get all docs)
        dispatch(refreshSearch({loadingIndicator: true}))

        // Track database changes, to e.g. trigger search result refresh
        onDatabaseChange(change => dispatch(handlePouchChange({change})))
    }
}

export function deleteVisit({visitId}) {
    return async function (dispatch, getState) {
        // Hide the visit directly (optimistically).
        dispatch(hideVisit({visitId}))
        // Remove it from the database.
        await deleteVisitAndPage({visitId})
    }
}

// Search for docs matching the current query, update the results
export function refreshSearch({loadingIndicator = false}) {
    return async function (dispatch, getState) {
        const { query, startDate, endDate } = ourState(getState())
        const oldResult = ourState(getState()).searchResult

        if (loadingIndicator) {
            // Show to the user that search is busy
            dispatch(showLoadingIndicator())
        }

        const searchResult = await filterVisitsByQuery({
            query,
            startDate,
            endDate,
            includeContext: true,
        })
        if (loadingIndicator) {
            // Hide our nice loading animation again.
            dispatch(hideLoadingIndicator())
        }

        // First check if the query and result changed in the meantime.
        if (ourState(getState()).query !== query
            && ourState(getState()).searchResult !== oldResult) {
            // The query already changed while we were searching, and the
            // currently displayed result may already be more recent than
            // ours. So we did all that effort for nothing.
            return
        }

        // Set the result to have it displayed to the user.
        dispatch(setSearchResult({searchResult}))
    }
}

// Report a change in the database, to e.g. trigger a search refresh
export const handlePouchChange = createAction('overview/handlePouchChange')
<commit_msg>Hide loading animation in case of error.<commit_after>import { createAction } from 'redux-act'

import { onDatabaseChange } from 'src/pouchdb'
import { filterVisitsByQuery } from 'src/search'
import { deleteVisitAndPage } from 'src/page-storage/deletion'

import { ourState } from './selectors'

// == Simple commands to change the state in reducers ==

export const setQuery = createAction('overview/setQuery')
export const setSearchResult = createAction('overview/setSearchResult')
export const showLoadingIndicator = createAction('overview/showLoadingIndicator')
export const hideLoadingIndicator = createAction('overview/hideLoadingIndicator')
export const setStartDate = createAction('overview/setStartDate')
export const setEndDate = createAction('overview/setEndDate')
export const hideVisit = createAction('overview/hideVisit')

// == Actions that trigger other actions ==

// Initialisation
export function init() {
    return function (dispatch, getState) {
        // Perform an initial search to populate the view (empty query = get all docs)
        dispatch(refreshSearch({loadingIndicator: true}))

        // Track database changes, to e.g. trigger search result refresh
        onDatabaseChange(change => dispatch(handlePouchChange({change})))
    }
}

export function deleteVisit({visitId}) {
    return async function (dispatch, getState) {
        // Hide the visit directly (optimistically).
        dispatch(hideVisit({visitId}))
        // Remove it from the database.
        await deleteVisitAndPage({visitId})
    }
}

// Search for docs matching the current query, update the results
export function refreshSearch({loadingIndicator = false}) {
    return async function (dispatch, getState) {
        const { query, startDate, endDate } = ourState(getState())
        const oldResult = ourState(getState()).searchResult

        if (loadingIndicator) {
            // Show to the user that search is busy
            dispatch(showLoadingIndicator())
        }

        let searchResult
        try {
            searchResult = await filterVisitsByQuery({
                query,
                startDate,
                endDate,
                includeContext: true,
            })
        } catch (err) {
            // TODO give feedback to user that results are not actually updated.
            console.error(`Search for '${query}' erred: ${err}`)
            return
        } finally {
            if (loadingIndicator) {
                // Hide our nice loading animation again.
                dispatch(hideLoadingIndicator())
            }
        }

        // First check if the query and result changed in the meantime.
        if (ourState(getState()).query !== query
            && ourState(getState()).searchResult !== oldResult) {
            // The query already changed while we were searching, and the
            // currently displayed result may already be more recent than
            // ours. So we did all that effort for nothing.
            return
        }

        // Set the result to have it displayed to the user.
        dispatch(setSearchResult({searchResult}))
    }
}

// Report a change in the database, to e.g. trigger a search refresh
export const handlePouchChange = createAction('overview/handlePouchChange')
<|endoftext|>


<commit_before>// vim:ts=4:sts=4:sw=4:
// Tyler Close
// Ported and revised by Kris Kowal
//
// This API varies from Tyler Closes ref_send in the
// following ways:
//
// * Promises can be resolved to function values.
// * Promises can be resolved to null or undefined.
// * Promises are distinguishable from arbitrary functions.
// * The promise API is abstracted with a Promise constructor
//   that accepts a descriptor that receives all of the
//   messages forwarded to that promise and handles the
//   common patterns for message receivers.  The promise
//   constructor also takes optional fallback and valueOf
//   methods which handle the cases for missing handlers on
//   the descriptor (rejection by default) and the valueOf
//   call (which returns the promise itself by default)
// * near(ref) has been changed to Promise.valueOf() in
//   keeping with JavaScript's existing Object.valueOf().
// * variadic arguments are used internally where
//   applicable. However, I have not altered the Q.post()
//   API to expand variadic arguments since Tyler Close
//   informed the CommonJS list that it would restrict
//   usage patterns for web_send, posting arbitrary JSON
//   objects as the "arguments" over HTTP.

/*
 * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
 * at http://www.opensource.org/licenses/mit-license.html
 * ref_send.js version: 2009-05-11
 */

/*
 * Copyright 2009-2010 Kris Kowal under the terms of the MIT
 * license found at http://github.com/kriskowal/q/raw/master/LICENSE
 */

/*whatsupdoc*/

// - the enclosure ensures that this module will function properly both as a
// CommonJS module and as a script in the browser.  In CommonJS, this module
// exports the "Q" API.  In the browser, this script creates a "Q" object in
// global scope.
// - the use of "undefined" on the enclosure is a micro-optmization for
// compression systems, permitting every occurrence of the "undefined" keyword
// bo be replaced with a single-character.
(function (exports, undefined) {
"use strict";

var enqueue;
try {
    // Narwhal, Node (with a package, wraps process.nextTick)
    enqueue = require("event-queue").enqueue;
} catch(e) {
    // browsers
    enqueue = function (task) {
        setTimeout(task, 0);
    };
}

var print;
if (typeof console !== "undefined") {
    // browsers in debug mode, Node
    print = function (message) {
        console.log(message);
    };
} else if (typeof require !== "undefined") {
    // Narwhal
    print = require("system").print;
} else {
    // browsers otherwise
    print = function () {}
}

// useful for an identity stub and default resolvers
function identity (x) {return x}

// ES5 shims
var freeze = Object.freeze || identity;
var create = Object.create || function create(prototype) {
    var Type = function () {};
    Type.prototype = prototype;
    object = new Type();
}

/**
 * Performs a task in a future turn of the event loop.
 * @param {Function} task
 */
exports.enqueue = enqueue;

/**
 * Constructs a {promise, resolve} object.
 *
 * The resolver is a callback to invoke with a more resolved value for the
 * promise. To fulfill the promise, invoke the resolver with any value that is
 * not a function. To reject the promise, invoke the resolver with a rejection
 * object. To put the promise in the same state as another promise, invoke the
 * resolver with that other promise.
 */
exports.defer = defer;

function defer() {
    // if "pending" is an "Array", that indicates that the promise has not yet
    // been resolved.  If it is "undefined", it has been resolved.  Each
    // element of the pending array is itself an array of complete arguments to
    // forward to the resolved promise.  We coerce the resolution value to a
    // promise using the ref promise because it handles both fully
    // resolved values and other promises gracefully.
    var pending = [], value;

    var promise = create(Promise.prototype);

    promise.emit = function () {
        var args = Array.prototype.slice.call(arguments);
        if (pending) {
            pending.push(args);
        } else {
            forward.apply(undefined, [value].concat(args));
        }
    };

    promise.valueOf = function () {
        if (pending)
            return promise;
        return value.valueOf();
    };

    var resolve = function (resolvedValue) {
        var i, ii, task;
        if (!pending)
            return;
        value = ref(resolvedValue);
        for (i = 0, ii = pending.length; i < ii; ++i) {
            forward.apply(undefined, [value].concat(pending[i]));
        }
        pending = undefined;
    };

    return {
        "promise": freeze(promise),
        "resolve": resolve,
        "reject": function (reason) {
            resolve(reject(reason));
        }
    };
}

/**
 * Constructs a Promise with a promise descriptor object and optional fallback
 * function.  The descriptor contains methods like when(rejected), get(name),
 * put(name, value), post(name, args), and delete(name), which all
 * return either a value, a promise for a value, or a rejection.  The fallback
 * accepts the operation name, a resolver, and any further arguments that would
 * have been forwarded to the appropriate method above had a method been
 * provided with the proper name.  The API makes no guarantees about the nature
 * of the returned object, apart from that it is usable whereever promises are
 * bought and sold.
 */
exports.Promise = Promise;

function Promise(descriptor, fallback, valueOf) {

    if (fallback === undefined) {
        fallback = function (op) {
            return reject("Promise does not support operation: " + op);
        };
    }

    var promise = create(Promise.prototype);

    promise.emit = function (op, resolved /* ...args */) {
        resolved = resolved || identity;
        var args = Array.prototype.slice.call(arguments, 2);
        var result;
        if (descriptor[op])
            result = descriptor[op].apply(descriptor, args);
        else
            result = fallback.apply(descriptor, arguments);
        return resolved(result);
    };

    if (valueOf)
        promise.valueOf = valueOf;

    return freeze(promise);
};

Promise.prototype.toSource = function () {
    return this.toString();
};

Promise.prototype.toString = function () {
    return '[object Promise]';
};

freeze(Promise.prototype);

/**
 * @returns whether the given object is a promise.
 * Otherwise it is a resolved value.
 */
exports.isPromise = isPromise;
function isPromise(object) {
    return object instanceof Promise;
};

/**
 * @returns whether the given object is a fully
 * resolved value.
 */
exports.isResolved = isResolved;
function isResolved(object) {
    if (object === undefined || object === null)
        return true;
    return !isPromise(object.valueOf());
};

/**
 * Constructs a rejected promise.
 * @param reason value describing the failure
 */
exports.reject = reject;
function reject(reason) {
    return Promise({
        "when": function (rejected) {
            return rejected ? rejected(reason) : reject(reason);
        }
    }, function fallback(op, resolved) {
        var rejection = reject(reason);
        return resolved ? resolved(rejection) : rejection;
    });
}

/**
 * Constructs a promise for an immediate reference.
 * @param value immediate reference
 */
exports.ref = ref;
function ref(object) {
    // If the object is already a Promise, return it directly.  This enables
    // the ref function to both be used to created references from
    // objects, but to tolerably coerce non-promises to refs if they are
    // not already Promises.
    if (isPromise(object))
        return object;
    return Promise({
        "when": function (rejected) {
            return object;
        },
        "get": function (name) {
            try {
                return object[name];
            } catch (exception) {
                return reject(exception.message)
            }
        },
        "put": function (name, value) {
            try {
                object[name] = value;
            } catch (exception) {
                return reject(exception.message)
            }
        },
        "delete": function (name) {
            try {
                delete object[name];
            } catch (exception) {
                return reject(exception.message)
            }
        },
        "post": function (name, args) {
            try {
                return object[name].apply(object, args);
            } catch (exception) {
                return reject(exception.message)
            }
        }
    }, undefined, function valueOf() {
        return object;
    });
}

/**
 * Registers an observer on a promise.
 *
 * Guarantees:
 *
 * 1. that resolved and rejected will be called only once.
 * 2. that either the resolved callback or the rejected callback will be
 *    called, but not both.
 * 3. that resolved and rejected will not be called in this turn.
 *
 * @param value     promise or immediate reference to observe
 * @param resolve function to be called with the resolved value
 * @param rejected  function to be called with the rejection reason
 * @return promise for the return value from the invoked callback
 */
exports.when = when;
function when(value, resolved, rejected) {
    var deferred = defer();
    var done = false;   // ensure the untrusted promise makes at most a
                        // single call to one of the callbacks
    forward(ref(value), "when", function (value) {
        if (done)
            return;
        done = true;
        deferred.resolve(ref(value).emit("when", resolved, rejected));
    }, function (reason) {
        if (done)
            return;
        done = true;
        deferred.resolve(rejected ? rejected(reason) : reject(reason));
    });
    return deferred.promise;
}

/**
 * Like "when", but attempts to return a fully resolved
 * value in the same turn. If the given value is fully
 * resolved, and the value returned by the resolved
 * callback is fully resolved, asap returns the latter
 * value in the same turn. Otherwise, it returns a promise
 * that will be resolved in a future turn.
 *
 * This method is an experiment in providing an API
 * that can unify synchronous and asynchronous API's.
 * An API that uses "asap" guarantees that, if it
 * is provided fully resolved values, it would produce
 * fully resolved values, but if it is provided
 * asynchronous promises, it will produce asynchronous
 * promises.
 *
 * /!\ WARNING: this method is expiermental and likely
 * to be removed on the grounds that it probably
 * will result in composition hazards.
 */
exports.asap = function (value, resolved, rejected) {
    resolved = resolved || identity;
    if (isResolved(value))
        return resolved(value.valueOf()).valueOf();
    else
        return when(value, resolved, rejected);
};

/**
 * Constructs a promise method that can be used to safely observe resolution of
 * a promise for an arbitrarily named method like "propfind" in a future turn.
 *
 * "Method" constructs methods like "get(promise, name)" and "put(promise)".
 */
exports.Method = Method;
function Method (methodName) {
    return function (object) {
        var deferred = defer();
        var args = Array.prototype.slice.call(arguments, 1);
        forward.apply(undefined, [
            ref(object),
            methodName,
            deferred.resolve
        ].concat(args));
        return deferred.promise;
    };
}

/**
 * Gets the value of a property in a future turn.
 * @param object    promise or immediate reference for target object
 * @param name      name of property to get
 * @return promise for the property value
 */
exports.get = Method("get");

/**
 * Sets the value of a property in a future turn.
 * @param object    promise or immediate reference for object object
 * @param name      name of property to set
 * @param value     new value of property
 * @return promise for the return value
 */
exports.put = Method("put");

/**
 * Deletes a property in a future turn.
 * @param object    promise or immediate reference for target object
 * @param name      name of property to delete
 * @return promise for the return value
 */
exports.del = Method("del");

/**
 * Invokes a method in a future turn.
 * @param object    promise or immediate reference for target object
 * @param name      name of method to invoke
 * @param argv      array of invocation arguments
 * @return promise for the return value
 */
exports.post = Method("post");

/**
 * Guarantees that the give promise resolves to a defined, non-null value.
 */
exports.defined = function (value) {
    return exports.when(value, function (value) {
        if (value === undefined || value === null)
            return reject("Resolved undefined value: " + value);
        return value;
    });
};

/**
 * Throws an error with the given reason.
 */
exports.error = function (reason) {
    if (!(reason instanceof Error))
        reason = new Error(reason);
    throw reason;
};

/*
 * Enqueues a promise operation for a future turn.
 */
function forward(promise /*, op, resolved, ... */) {
    var args = Array.prototype.slice.call(arguments, 1);
    enqueue(function () {
        try {
            promise.emit.apply(promise, args);
        } catch (exception) {
            print(exception.stack || exception);
        }
    });
}

// Complete the closure: use either CommonJS exports or browser global Q object
// for the exports internally.
})(
    typeof exports !== "undefined" ?
    exports :
    this["/q"] = {}
);

<commit_msg>Adding missing semicolons.<commit_after>// vim:ts=4:sts=4:sw=4:
// Tyler Close
// Ported and revised by Kris Kowal
//
// This API varies from Tyler Closes ref_send in the
// following ways:
//
// * Promises can be resolved to function values.
// * Promises can be resolved to null or undefined.
// * Promises are distinguishable from arbitrary functions.
// * The promise API is abstracted with a Promise constructor
//   that accepts a descriptor that receives all of the
//   messages forwarded to that promise and handles the
//   common patterns for message receivers.  The promise
//   constructor also takes optional fallback and valueOf
//   methods which handle the cases for missing handlers on
//   the descriptor (rejection by default) and the valueOf
//   call (which returns the promise itself by default)
// * near(ref) has been changed to Promise.valueOf() in
//   keeping with JavaScript's existing Object.valueOf().
// * variadic arguments are used internally where
//   applicable. However, I have not altered the Q.post()
//   API to expand variadic arguments since Tyler Close
//   informed the CommonJS list that it would restrict
//   usage patterns for web_send, posting arbitrary JSON
//   objects as the "arguments" over HTTP.

/*
 * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
 * at http://www.opensource.org/licenses/mit-license.html
 * ref_send.js version: 2009-05-11
 */

/*
 * Copyright 2009-2010 Kris Kowal under the terms of the MIT
 * license found at http://github.com/kriskowal/q/raw/master/LICENSE
 */

/*whatsupdoc*/

// - the enclosure ensures that this module will function properly both as a
// CommonJS module and as a script in the browser.  In CommonJS, this module
// exports the "Q" API.  In the browser, this script creates a "Q" object in
// global scope.
// - the use of "undefined" on the enclosure is a micro-optmization for
// compression systems, permitting every occurrence of the "undefined" keyword
// bo be replaced with a single-character.
(function (exports, undefined) {
"use strict";

var enqueue;
try {
    // Narwhal, Node (with a package, wraps process.nextTick)
    enqueue = require("event-queue").enqueue;
} catch(e) {
    // browsers
    enqueue = function (task) {
        setTimeout(task, 0);
    };
}

var print;
if (typeof console !== "undefined") {
    // browsers in debug mode, Node
    print = function (message) {
        console.log(message);
    };
} else if (typeof require !== "undefined") {
    // Narwhal
    print = require("system").print;
} else {
    // browsers otherwise
    print = function () {}
}

// useful for an identity stub and default resolvers
function identity (x) {return x}

// ES5 shims
var freeze = Object.freeze || identity;
var create = Object.create || function create(prototype) {
    var Type = function () {};
    Type.prototype = prototype;
    object = new Type();
}

/**
 * Performs a task in a future turn of the event loop.
 * @param {Function} task
 */
exports.enqueue = enqueue;

/**
 * Constructs a {promise, resolve} object.
 *
 * The resolver is a callback to invoke with a more resolved value for the
 * promise. To fulfill the promise, invoke the resolver with any value that is
 * not a function. To reject the promise, invoke the resolver with a rejection
 * object. To put the promise in the same state as another promise, invoke the
 * resolver with that other promise.
 */
exports.defer = defer;

function defer() {
    // if "pending" is an "Array", that indicates that the promise has not yet
    // been resolved.  If it is "undefined", it has been resolved.  Each
    // element of the pending array is itself an array of complete arguments to
    // forward to the resolved promise.  We coerce the resolution value to a
    // promise using the ref promise because it handles both fully
    // resolved values and other promises gracefully.
    var pending = [], value;

    var promise = create(Promise.prototype);

    promise.emit = function () {
        var args = Array.prototype.slice.call(arguments);
        if (pending) {
            pending.push(args);
        } else {
            forward.apply(undefined, [value].concat(args));
        }
    };

    promise.valueOf = function () {
        if (pending)
            return promise;
        return value.valueOf();
    };

    var resolve = function (resolvedValue) {
        var i, ii, task;
        if (!pending)
            return;
        value = ref(resolvedValue);
        for (i = 0, ii = pending.length; i < ii; ++i) {
            forward.apply(undefined, [value].concat(pending[i]));
        }
        pending = undefined;
    };

    return {
        "promise": freeze(promise),
        "resolve": resolve,
        "reject": function (reason) {
            resolve(reject(reason));
        }
    };
}

/**
 * Constructs a Promise with a promise descriptor object and optional fallback
 * function.  The descriptor contains methods like when(rejected), get(name),
 * put(name, value), post(name, args), and delete(name), which all
 * return either a value, a promise for a value, or a rejection.  The fallback
 * accepts the operation name, a resolver, and any further arguments that would
 * have been forwarded to the appropriate method above had a method been
 * provided with the proper name.  The API makes no guarantees about the nature
 * of the returned object, apart from that it is usable whereever promises are
 * bought and sold.
 */
exports.Promise = Promise;

function Promise(descriptor, fallback, valueOf) {

    if (fallback === undefined) {
        fallback = function (op) {
            return reject("Promise does not support operation: " + op);
        };
    }

    var promise = create(Promise.prototype);

    promise.emit = function (op, resolved /* ...args */) {
        resolved = resolved || identity;
        var args = Array.prototype.slice.call(arguments, 2);
        var result;
        if (descriptor[op])
            result = descriptor[op].apply(descriptor, args);
        else
            result = fallback.apply(descriptor, arguments);
        return resolved(result);
    };

    if (valueOf)
        promise.valueOf = valueOf;

    return freeze(promise);
};

Promise.prototype.toSource = function () {
    return this.toString();
};

Promise.prototype.toString = function () {
    return '[object Promise]';
};

freeze(Promise.prototype);

/**
 * @returns whether the given object is a promise.
 * Otherwise it is a resolved value.
 */
exports.isPromise = isPromise;
function isPromise(object) {
    return object instanceof Promise;
};

/**
 * @returns whether the given object is a fully
 * resolved value.
 */
exports.isResolved = isResolved;
function isResolved(object) {
    if (object === undefined || object === null)
        return true;
    return !isPromise(object.valueOf());
};

/**
 * Constructs a rejected promise.
 * @param reason value describing the failure
 */
exports.reject = reject;
function reject(reason) {
    return Promise({
        "when": function (rejected) {
            return rejected ? rejected(reason) : reject(reason);
        }
    }, function fallback(op, resolved) {
        var rejection = reject(reason);
        return resolved ? resolved(rejection) : rejection;
    });
}

/**
 * Constructs a promise for an immediate reference.
 * @param value immediate reference
 */
exports.ref = ref;
function ref(object) {
    // If the object is already a Promise, return it directly.  This enables
    // the ref function to both be used to created references from
    // objects, but to tolerably coerce non-promises to refs if they are
    // not already Promises.
    if (isPromise(object))
        return object;
    return Promise({
        "when": function (rejected) {
            return object;
        },
        "get": function (name) {
            try {
                return object[name];
            } catch (exception) {
                return reject(exception.message);
            }
        },
        "put": function (name, value) {
            try {
                object[name] = value;
            } catch (exception) {
                return reject(exception.message);
            }
        },
        "delete": function (name) {
            try {
                delete object[name];
            } catch (exception) {
                return reject(exception.message);
            }
        },
        "post": function (name, args) {
            try {
                return object[name].apply(object, args);
            } catch (exception) {
                return reject(exception.message);
            }
        }
    }, undefined, function valueOf() {
        return object;
    });
}

/**
 * Registers an observer on a promise.
 *
 * Guarantees:
 *
 * 1. that resolved and rejected will be called only once.
 * 2. that either the resolved callback or the rejected callback will be
 *    called, but not both.
 * 3. that resolved and rejected will not be called in this turn.
 *
 * @param value     promise or immediate reference to observe
 * @param resolve function to be called with the resolved value
 * @param rejected  function to be called with the rejection reason
 * @return promise for the return value from the invoked callback
 */
exports.when = when;
function when(value, resolved, rejected) {
    var deferred = defer();
    var done = false;   // ensure the untrusted promise makes at most a
                        // single call to one of the callbacks
    forward(ref(value), "when", function (value) {
        if (done)
            return;
        done = true;
        deferred.resolve(ref(value).emit("when", resolved, rejected));
    }, function (reason) {
        if (done)
            return;
        done = true;
        deferred.resolve(rejected ? rejected(reason) : reject(reason));
    });
    return deferred.promise;
}

/**
 * Like "when", but attempts to return a fully resolved
 * value in the same turn. If the given value is fully
 * resolved, and the value returned by the resolved
 * callback is fully resolved, asap returns the latter
 * value in the same turn. Otherwise, it returns a promise
 * that will be resolved in a future turn.
 *
 * This method is an experiment in providing an API
 * that can unify synchronous and asynchronous API's.
 * An API that uses "asap" guarantees that, if it
 * is provided fully resolved values, it would produce
 * fully resolved values, but if it is provided
 * asynchronous promises, it will produce asynchronous
 * promises.
 *
 * /!\ WARNING: this method is expiermental and likely
 * to be removed on the grounds that it probably
 * will result in composition hazards.
 */
exports.asap = function (value, resolved, rejected) {
    resolved = resolved || identity;
    if (isResolved(value))
        return resolved(value.valueOf()).valueOf();
    else
        return when(value, resolved, rejected);
};

/**
 * Constructs a promise method that can be used to safely observe resolution of
 * a promise for an arbitrarily named method like "propfind" in a future turn.
 *
 * "Method" constructs methods like "get(promise, name)" and "put(promise)".
 */
exports.Method = Method;
function Method (methodName) {
    return function (object) {
        var deferred = defer();
        var args = Array.prototype.slice.call(arguments, 1);
        forward.apply(undefined, [
            ref(object),
            methodName,
            deferred.resolve
        ].concat(args));
        return deferred.promise;
    };
}

/**
 * Gets the value of a property in a future turn.
 * @param object    promise or immediate reference for target object
 * @param name      name of property to get
 * @return promise for the property value
 */
exports.get = Method("get");

/**
 * Sets the value of a property in a future turn.
 * @param object    promise or immediate reference for object object
 * @param name      name of property to set
 * @param value     new value of property
 * @return promise for the return value
 */
exports.put = Method("put");

/**
 * Deletes a property in a future turn.
 * @param object    promise or immediate reference for target object
 * @param name      name of property to delete
 * @return promise for the return value
 */
exports.del = Method("del");

/**
 * Invokes a method in a future turn.
 * @param object    promise or immediate reference for target object
 * @param name      name of method to invoke
 * @param argv      array of invocation arguments
 * @return promise for the return value
 */
exports.post = Method("post");

/**
 * Guarantees that the give promise resolves to a defined, non-null value.
 */
exports.defined = function (value) {
    return exports.when(value, function (value) {
        if (value === undefined || value === null)
            return reject("Resolved undefined value: " + value);
        return value;
    });
};

/**
 * Throws an error with the given reason.
 */
exports.error = function (reason) {
    if (!(reason instanceof Error))
        reason = new Error(reason);
    throw reason;
};

/*
 * Enqueues a promise operation for a future turn.
 */
function forward(promise /*, op, resolved, ... */) {
    var args = Array.prototype.slice.call(arguments, 1);
    enqueue(function () {
        try {
            promise.emit.apply(promise, args);
        } catch (exception) {
            print(exception.stack || exception);
        }
    });
}

// Complete the closure: use either CommonJS exports or browser global Q object
// for the exports internally.
})(
    typeof exports !== "undefined" ?
    exports :
    this["/q"] = {}
);

<|endoftext|>


<commit_before>angular.module('genie.detail-ctrl', [])
.controller('DetailCtrl', function($scope, $state) {
	$scope.go = function(route) {
		$state.go(route);
	}

    var svg = d3.select("#detailView").append("svg") // The page currently has no svg element. Fix this
		.attr("width", '100%')
		.attr("height", 600) // Arbitrary size
        .on("mouseup", mouseup);
        color = d3.scaleOrdinal(d3.schemeCategory10);

    var width = $("#detailView svg").width();
    var height = $("#detailView svg").height();

    var mouseup_node, mousedown_node;

    var simulation = d3.forceSimulation()
        .force("charge", d3.forceManyBody().strength(-1500))
        .force("link", d3.forceLink().distance(350))
        .force("collide", d3.forceCollide().radius(90).iterations(2))
        .force("x", d3.forceX())
        .force("y", d3.forceY())
        .alphaTarget(1)

    nodes = []
    links = []
    f = {id: "Person", text: "John", children: [], childViz: false};
    g = {id: "Person", text: "Bob", children: [], childViz: false};
    h = {id: "Person", text: "Suzy", children: [], childViz: false};
    i = {id: "Person", text: "Sally", children: [], childViz: false};
    j = {id: "Person", text: "Jane", children: [], childViz: false};

    b = {id: "Hobby", text: "Trumpeting", children: [f, g, h, i, j], childViz: false};
    c = {id: "Profession", text: "Code Monkey", children: [], childViz: false};
    d = {id: "Education", text: "Finished College", children: [], childViz: false};
    e = {id: "Religion", text: "Mormon", children: [], childViz: false};

    a = {id: "Name", text: "Ritter1", fx: 0, fy:0, children: [b, c, d, e], childViz: true};

    function resetLayout() {
        nextList = [a]
        while (nextList.length != 0) {
            parent = nextList.shift()
            nodes.push(parent)
            console.log(parent.childViz);
            if (parent.childViz) {
                for (var i = 0; i < parent.children.length; i++) {
                    links.push({source: parent, target: parent.children[i]})
                    nextList.push(parent.children[i])
                }
            }
        }
        restart(nodes, links)
    }

    function restart(nodes, links) {
        d3.selectAll("svg > *").remove();
        var g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

        var link = g.append("g")
            .classed("links", true)
            .selectAll("g.link")
            .data(links)
            .enter()
            .append("line")
			.attr("marker-end", null);

        var node = g.append("g")
    		.classed("nodes", true)
    		.selectAll("g.node")
    		.data(nodes)
    		.enter()
    		.append("svg")

        // node.exit().remove();
        node.append("rect")
            .attr("fill", "red")
            .attr("width", 100)
            .attr("height", 100)
            .on("mousedown",
                function(d) {
                    mousedown_node = d;
                }
            )
            .on("mouseup",
                function(d) {
                    mouseup_node = d;
                 }
            )

        // Update and restart the simulation.
        simulation.nodes(nodes);
        simulation.on("tick", ticked);
        simulation.force("link").links(links);

        node.each(
            function(d) {
                var descriptionLines = [];
                descriptionLines.push(d.id + ":")
                var textLine = d.text;
                descriptionLines.push(d.text);
                var group = d3.select(this);
                for (var i = 0; i < descriptionLines.length; i++) {
                    group.append("text")
                    .classed("info",true)
                    .attr("x", 5)
                    .attr("y", (i + 1) * 20)
                    .text(descriptionLines[i]);
                }
            }
        );
        // setTimeout(function () {
        //     simulation.stop()
        // }, 350);

        var targetDist = 50;

        function ticked() {

            // connections.attr("d", function(d) {
            // 	var n1 = json.nodes[d.source];
            // 	var n2 = json.nodes[d.target];
            // 	return "M" + n1.x + " " + n1.y + " Q " + n2.x + " " + n1.y + " " + n2.x + " " + n2.y; // Quadratic Bessier Curve
            // });

            link.attr("x1", function(d) {
                        var theta = Math.atan2(d.source.y - d.target.y, d.target.x - d.source.x);
                        return d.source.x + 50 * (Math.abs(Math.abs(theta) - Math.PI / 2) <= Math.PI / 4 ? 1 / Math.tan(Math.abs(theta)) : (Math.abs(theta) > Math.PI / 2 ? -1 : 1));
                })
                .attr("y1",  function(d) {
                        var theta = Math.atan2(d.source.y - d.target.y, d.target.x - d.source.x);
                        return d.source.y - 50 * (Math.abs(Math.abs(theta) - Math.PI / 2) <= Math.PI / 4 ? (theta > 0 ? 1 : -1) : (Math.abs(theta) < Math.PI / 2 ? 1 : -1) * Math.tan(theta));
                })
                .attr("x2",  function(d) {
                        var theta = Math.atan2(d.source.y - d.target.y, d.target.x - d.source.x);
                        return d.target.x - targetDist * (Math.abs(Math.abs(theta) - Math.PI / 2) <= Math.PI / 4 ? 1/Math.tan(Math.abs(theta)) : (Math.abs(theta) > Math.PI / 2 ? -1 : 1));
                    })
                .attr("y2",  function(d) {
                        var theta = Math.atan2(d.source.y - d.target.y, d.target.x - d.source.x);
                        return d.target.y + targetDist * (Math.abs(Math.abs(theta) - Math.PI / 2) <= Math.PI / 4 ? (theta > 0 ? 1 : -1) : (Math.abs(theta) < Math.PI / 2 ? 1 : -1) * Math.tan(theta));
                    });

            node.attr("x", function(d) {return d.x - 50;})
                .attr("y", function(d) {return d.y - 50;});
        }

        simulation.alpha(1).restart();

    }

    function mouseup() {
        if (mouseup_node && mousedown_node && mousedown_node == mousedown_node) {
            if (!mouseup_node.childViz) {
                console.log(nodes[1]);
                nodes[1].childViz = true
            } else {
                nodes[1].childViz = false
            }
            console.log(nodes[1].childViz);
        }
        resetLayout()
        // clear mouse event vars
        mouseup_node = null;
        mousedown_node = null;
    }

    resetLayout()
});
<commit_msg>detail tree<commit_after>angular.module('genie.detail-ctrl', [])
.controller('DetailCtrl', function($scope, $state) {
	$scope.go = function(route) {
		$state.go(route);
	}

    k = {id: "Person", text: "Sue", children: [], childViz: false};
    l = {id: "Person", text: "Bill", children: [], childViz: false};

    f = {id: "Person", text: "John", children: [], childViz: false};
    g = {id: "Person", text: "Bob", children: [k,l], childViz: false};
    h = {id: "Person", text: "Suzy", children: [], childViz: false};
    i = {id: "Person", text: "Sally", children: [k], childViz: false};
    j = {id: "Person", text: "Jane", children: [], childViz: false};

    b = {id: "Hobby", text: "Trumpeting", children: [h, i, j]};
    c = {id: "Profession", text: "Code Monkey", children: [f, g]};
    d = {id: "Education", text: "Finished College", children: [g, i]};
    e = {id: "Religion", text: "Mormon", children: [j, h]};

    treeData = {id: "Name", text: "Ritter1", children: [b, c, d, e]};

    // Set the dimensions and margins of the diagram
    var margin = {top: 20, right: 110, bottom: 30, left: 110},
        width = 1160 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

    // append the svg object to the body of the page
    // appends a 'group' element to 'svg'
    // moves the 'group' element to the top left margin
    var svg = d3.select("#detailView").append("svg") // The page currently has no svg element. Fix this
        .attr("width", width + margin.right + margin.left)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate("
              + margin.left + "," + margin.top + ")");

    var i = 0,
        duration = 750,
        root;

    // declares a tree layout and assigns the size
    var treemap = d3.tree().size([height, width]);

    // Assigns parent, children, height, depth
    root = d3.hierarchy(treeData, function(d) { return d.children; });
    root.x0 = height / 2;
    root.y0 = 0;

    // Collapse after the second level
    root.children.forEach(collapse);

    update(root);

    // Collapse the node and all it's children
    function collapse(d) {
        if(d.children) {
            d._children = d.children
            d._children.forEach(collapse)
            d.children = null
        }
    }

    function update(source) {

        // Assigns the x and y position for the nodes
        var treeData = treemap(root);

        // Compute the new tree layout.
        var nodes = treeData.descendants(),
            links = treeData.descendants().slice(1);

        // Normalize for fixed-depth.
        nodes.forEach(function(d){ d.y = d.depth * 180});

        // ****************** Nodes section ***************************

        // Update the nodes...
        var node = svg.selectAll('g.node')
            .data(nodes, function(d) {return d.id || (d.id = ++i); });

        // Enter any new modes at the parent's previous position.
        var nodeEnter = node.enter().append('g')
            .attr('class', 'node')
            .attr("transform", function(d) {
                return "translate(" + source.y0 + "," + source.x0 + ")";
            })
            .on('click', click);

        // Add Circle for the nodes
        nodeEnter.append('circle')
            .attr('class', 'node')
            .attr('r', 1e-6)
            .style("fill", function(d) {
                return d._children ? "lightsteelblue" : "#fff";
            });

        // Add labels for the nodes
        nodeEnter.append('text')
            .attr("dy", ".35em")
            .attr("x", function(d) {
                return d.children || d._children ? -13 : 13;
            })
            .attr("text-anchor", function(d) {
                return d.children || d._children ? "end" : "start";
            })
            .text(function(d) { return (d.data.id == "Person" ? "" : d.data.id + ": ") + d.data.text; });

        // UPDATE
        var nodeUpdate = nodeEnter.merge(node);

        // Transition to the proper position for the node
        nodeUpdate.transition()
            .duration(duration)
            .attr("transform", function(d) {
                return "translate(" + d.y + "," + d.x + ")";
            });

            // Update the node attributes and style
        nodeUpdate.select('circle.node')
            .attr('r', 10)
            .style("fill", function(d) {
                return d._children ? "lightsteelblue" : "#fff";
            })
            .attr('cursor', 'pointer');

        // Remove any exiting nodes
        var nodeExit = node.exit().transition()
            .duration(duration)
            .attr("transform", function(d) {
                return "translate(" + source.y + "," + source.x + ")";
            })
            .remove();

        // On exit reduce the node circles size to 0
        nodeExit.select('circle')
            .attr('r', 1e-6);

        // On exit reduce the opacity of text labels
        nodeExit.select('text')
            .style('fill-opacity', 1e-6);

        // ****************** links section ***************************

        // Update the links...
        var link = svg.selectAll('path.link')
            .data(links, function(d) { return d.id; });

        // Enter any new links at the parent's previous position.
        var linkEnter = link.enter().insert('path', "g")
            .attr("class", "link")
            .attr('d', function(d){
                var o = {x: source.x0, y: source.y0}
                return diagonal(o, o)
            });

        // UPDATE
        var linkUpdate = linkEnter.merge(link);

        // Transition back to the parent element position
        linkUpdate.transition()
            .duration(duration)
            .attr('d', function(d){ return diagonal(d, d.parent) });

        // Remove any exiting links
        var linkExit = link.exit().transition()
            .duration(duration)
            .attr('d', function(d) {
                var o = {x: source.x, y: source.y}
                return diagonal(o, o)
            })
            .remove();

        // Store the old positions for transition.
        nodes.forEach(function(d){
            d.x0 = d.x;
            d.y0 = d.y;
        });

        // Creates a curved (diagonal) path from parent to the child nodes
        function diagonal(s, d) {

            path = `M ${s.y} ${s.x}
                    C ${(s.y + d.y) / 2} ${s.x},
                    ${(s.y + d.y) / 2} ${d.x},
                    ${d.y} ${d.x}`
            return path
        }

        // Toggle children on click.
        function click(d) {
            if (d.children) {
                d._children = d.children;
                d.children = null;
            } else {
                d.children = d._children;
                d._children = null;
            }
            update(d);
        }
    }
    //
    // var svg = d3.select("#detailView").append("svg") // The page currently has no svg element. Fix this
	// 	.attr("width", '100%')
	// 	.attr("height", 600) // Arbitrary size
    //     .on("mouseup", mouseup);
    //     color = d3.scaleOrdinal(d3.schemeCategory10);
    //
    // var width = $("#detailView svg").width();
    // var height = $("#detailView svg").height();
    //
    // var mouseup_node, mousedown_node;
    //
    // var simulation = d3.forceSimulation()
    //     .force("charge", d3.forceManyBody().strength(-1500))
    //     .force("link", d3.forceLink().distance(350))
    //     .force("collide", d3.forceCollide().radius(90).iterations(2))
    //     .force("x", d3.forceX())
    //     .force("y", d3.forceY())
    //     .alphaTarget(1)
    //
    // nodes = []
    // links = []
    // f = {id: "Person", text: "John", children: [], childViz: false};
    // g = {id: "Person", text: "Bob", children: [], childViz: false};
    // h = {id: "Person", text: "Suzy", children: [], childViz: false};
    // i = {id: "Person", text: "Sally", children: [], childViz: false};
    // j = {id: "Person", text: "Jane", children: [], childViz: false};
    //
    // b = {id: "Hobby", text: "Trumpeting", children: [f, g, h, i, j], childViz: false};
    // c = {id: "Profession", text: "Code Monkey", children: [], childViz: false};
    // d = {id: "Education", text: "Finished College", children: [], childViz: false};
    // e = {id: "Religion", text: "Mormon", children: [], childViz: false};
    //
    // a = {id: "Name", text: "Ritter1", fx: 0, fy:0, children: [b, c, d, e], childViz: true};
    //
    //
    // function resetLayout() {
    //     nextList = [a]
    //     while (nextList.length != 0) {
    //         parent = nextList.shift()
    //         nodes.push(parent)
    //         console.log(parent.childViz);
    //         if (parent.childViz) {
    //             for (var i = 0; i < parent.children.length; i++) {
    //                 links.push({source: parent, target: parent.children[i]})
    //                 nextList.push(parent.children[i])
    //             }
    //         }
    //     }
    //     restart(nodes, links)
    // }
    //
    // function restart(nodes, links) {
    //     d3.selectAll("svg > *").remove();
    //     var g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
    //
    //     var link = g.append("g")
    //         .classed("links", true)
    //         .selectAll("g.link")
    //         .data(links)
    //         .enter()
    //         .append("line")
	// 		.attr("marker-end", null);
    //
    //     var node = g.append("g")
    // 		.classed("nodes", true)
    // 		.selectAll("g.node")
    // 		.data(nodes)
    // 		.enter()
    // 		.append("svg")
    //
    //     // node.exit().remove();
    //     node.append("rect")
    //         .attr("fill", "red")
    //         .attr("width", 100)
    //         .attr("height", 100)
    //         .on("mousedown",
    //             function(d) {
    //                 mousedown_node = d;
    //             }
    //         )
    //         .on("mouseup",
    //             function(d) {
    //                 mouseup_node = d;
    //              }
    //         )
    //
    //     // Update and restart the simulation.
    //     simulation.nodes(nodes);
    //     simulation.on("tick", ticked);
    //     simulation.force("link").links(links);
    //
    //     node.each(
    //         function(d) {
    //             var descriptionLines = [];
    //             descriptionLines.push(d.id + ":")
    //             var textLine = d.text;
    //             descriptionLines.push(d.text);
    //             var group = d3.select(this);
    //             for (var i = 0; i < descriptionLines.length; i++) {
    //                 group.append("text")
    //                 .classed("info",true)
    //                 .attr("x", 5)
    //                 .attr("y", (i + 1) * 20)
    //                 .text(descriptionLines[i]);
    //             }
    //         }
    //     );
    //     // setTimeout(function () {
    //     //     simulation.stop()
    //     // }, 350);
    //
    //     var targetDist = 50;
    //
    //     function ticked() {
    //
    //         // connections.attr("d", function(d) {
    //         // 	var n1 = json.nodes[d.source];
    //         // 	var n2 = json.nodes[d.target];
    //         // 	return "M" + n1.x + " " + n1.y + " Q " + n2.x + " " + n1.y + " " + n2.x + " " + n2.y; // Quadratic Bessier Curve
    //         // });
    //
    //         link.attr("x1", function(d) {
    //                     var theta = Math.atan2(d.source.y - d.target.y, d.target.x - d.source.x);
    //                     return d.source.x + 50 * (Math.abs(Math.abs(theta) - Math.PI / 2) <= Math.PI / 4 ? 1 / Math.tan(Math.abs(theta)) : (Math.abs(theta) > Math.PI / 2 ? -1 : 1));
    //             })
    //             .attr("y1",  function(d) {
    //                     var theta = Math.atan2(d.source.y - d.target.y, d.target.x - d.source.x);
    //                     return d.source.y - 50 * (Math.abs(Math.abs(theta) - Math.PI / 2) <= Math.PI / 4 ? (theta > 0 ? 1 : -1) : (Math.abs(theta) < Math.PI / 2 ? 1 : -1) * Math.tan(theta));
    //             })
    //             .attr("x2",  function(d) {
    //                     var theta = Math.atan2(d.source.y - d.target.y, d.target.x - d.source.x);
    //                     return d.target.x - targetDist * (Math.abs(Math.abs(theta) - Math.PI / 2) <= Math.PI / 4 ? 1/Math.tan(Math.abs(theta)) : (Math.abs(theta) > Math.PI / 2 ? -1 : 1));
    //                 })
    //             .attr("y2",  function(d) {
    //                     var theta = Math.atan2(d.source.y - d.target.y, d.target.x - d.source.x);
    //                     return d.target.y + targetDist * (Math.abs(Math.abs(theta) - Math.PI / 2) <= Math.PI / 4 ? (theta > 0 ? 1 : -1) : (Math.abs(theta) < Math.PI / 2 ? 1 : -1) * Math.tan(theta));
    //                 });
    //
    //         node.attr("x", function(d) {return d.x - 50;})
    //             .attr("y", function(d) {return d.y - 50;});
    //     }
    //
    //     simulation.alpha(1).restart();
    //
    // }
    //
    // function mouseup() {
    //     if (mouseup_node && mousedown_node && mousedown_node == mousedown_node) {
    //         if (!mouseup_node.childViz) {
    //             console.log(nodes[1]);
    //             nodes[1].childViz = true
    //         } else {
    //             nodes[1].childViz = false
    //         }
    //         console.log(nodes[1].childViz);
    //     }
    //     resetLayout()
    //     // clear mouse event vars
    //     mouseup_node = null;
    //     mousedown_node = null;
    // }
    //
    // resetLayout()
});
<|endoftext|>


<commit_before>define([
    'require',
    '../lib/jquery.form/jquery.form',
    '../logging',
    './inject'
], function(require) {
    var log = require('../logging').getLogger('ajaxify');

    var init = function($el, opts) {
        // skip elements that are covered by old-style injection
        if ($el.is('.injection,[data-injection]')) {
            log.debug('skipping element claimed by old injection', $el);
            return false;
        }

        // ajaxify form
        if ($el.is('form')) {
            $el.ajaxForm({
                context: $el,
                // in plone we use this to figure out whether a form is
                // requested or submitted
                // XXX: consider setting this via $.ajaxSetup in a
                // specific application
                data: {submit: "submit"},
                type: $el.attr('method') || 'POST',
                url: $el.attr('action')
            });
        } else {
            $el.on('click.ajaxify', function(ev, opts) {
                ev.preventDefault();
                $.ajax({
                    context: $el,
                    url: $el.attr('href')
                });
            });
        }

        $el.ajaxError(function(ev, jqxhr, opts, error) {
            log.debug('error', ev, jqxhr, opts, error);
            // ajaxHandlers are global, we are only interested in our form
            if (!(ev.target === $el[0])) return;

            // XXX: this needs to be solved differently
            var msg = [jqxhr.status, jqxhr.statusText, error, opts.url].join(' '),
                // XXX: error notification pattern!
                $error = $('
'
                           + '
Error
'
                           + '
'+msg+'
'
                           + '
');
            var inject = require('./inject');
            inject.append($error, $('body'));
        });

        $el.ajaxSuccess(function(ev, jqxhr, opts, data) {
            log.debug('success', ev, jqxhr, opts);
            // ajaxHandlers are global, we are only interested in our form
            // XXX: figure out how much of this is true with a multi-form test
            if (!(ev.target === $el[0])) return;

            // XXX: this needs to be solved differently
            if (!data) return;
            var $forms = $(data).find('form[id]');
            $forms.each(function() {
                var $form = $(this),
                    id = $(this).attr('id'),
                    $ourform = $('#' + id);
                if ($ourform.length > 0) {
                    $ourform.attr({action: $form.attr('action')});
                } else {
                    console.warn(
                        'Ignored form in respone data: not matching id', $form);
                }
            });
        });

        return $el;
    };

    return {
        markup_trigger: 'form, a.ajaxify',
        initialised_class: 'ajaxified',
        init: init
    };
});<commit_msg>not all forms<commit_after>define([
    'require',
    '../lib/jquery.form/jquery.form',
    '../logging',
    './inject'
], function(require) {
    var log = require('../logging').getLogger('ajaxify');

    var init = function($el, opts) {
        // skip elements that are covered by old-style injection
        if ($el.is('.injection,[data-injection]')) {
            log.debug('skipping element claimed by old injection', $el);
            return false;
        }

        // ajaxify form
        if ($el.is('form')) {
            $el.ajaxForm({
                context: $el,
                // in plone we use this to figure out whether a form is
                // requested or submitted
                // XXX: consider setting this via $.ajaxSetup in a
                // specific application
                data: {submit: "submit"},
                type: $el.attr('method') || 'POST',
                url: $el.attr('action')
            });
        } else {
            $el.on('click.ajaxify', function(ev, opts) {
                ev.preventDefault();
                $.ajax({
                    context: $el,
                    url: $el.attr('href')
                });
            });
        }

        $el.ajaxError(function(ev, jqxhr, opts, error) {
            log.debug('error', ev, jqxhr, opts, error);
            // ajaxHandlers are global, we are only interested in our form
            if (!(ev.target === $el[0])) return;

            // XXX: this needs to be solved differently
            var msg = [jqxhr.status, jqxhr.statusText, error, opts.url].join(' '),
                // XXX: error notification pattern!
                $error = $('
'
                           + '
Error
'
                           + '
'+msg+'
'
                           + '
');
            var inject = require('./inject');
            inject.append($error, $('body'));
        });

        $el.ajaxSuccess(function(ev, jqxhr, opts, data) {
            log.debug('success', ev, jqxhr, opts);
            // ajaxHandlers are global, we are only interested in our form
            // XXX: figure out how much of this is true with a multi-form test
            if (!(ev.target === $el[0])) return;

            // XXX: this needs to be solved differently
            if (!data) return;
            var $forms = $(data).find('form[id]');
            $forms.each(function() {
                var $form = $(this),
                    id = $(this).attr('id'),
                    $ourform = $('#' + id);
                if ($ourform.length > 0) {
                    $ourform.attr({action: $form.attr('action')});
                } else {
                    console.warn(
                        'Ignored form in respone data: not matching id', $form);
                }
            });
        });

        return $el;
    };

    return {
        markup_trigger: 'form.ajaxify, a.ajaxify',
        initialised_class: 'ajaxified',
        init: init
    };
});
<|endoftext|>


<commit_before>/*
 *    Copyright (C) 2017    IC Manage Inc.
 *
 *    See the file 'COPYING' for license information.
 */
 /**
 * Starts server to get DA messages using POST method of REST API
 *
 * Run file: node app.js --postServer=POST,host,port
 *                                       --logfile=<path_to_da_messages.log> -
 *                                                    path_to_console_ouput.log
 *  @param --postServer=POST,host,port - POST - using REST API method
 *                                              (if it's not POST exit with Error);
 *                                              host - server IP;
 *                                              port - listening port
 *  @param --logFile=log-file          - log-file - contains all data post by DA in json-format;
 *
 */

// Include the necessary modules.
const http = require('http');
const fs = require('fs');
const mkdirp = require('mkdirp');
const json = require('JSON');
const path = require('path');
//
const jsu = require('./src/lib/vcncSamplerUtils');
const conf = require('./src/vcncSampler.conf');
const vs = require('./src/lib/vcncSampling');

//
//  Initialize the C++ extension
//
const extensionPath = '../js-extension/build/Release/cnctrq_client';
const CnctrqClient = require(extensionPath).CnctrqClient;
const cnctrqClient = new CnctrqClient();
cnctrqClient.call_me_first(path.join(__dirname, '..'));

const cmdl = jsu.cmd_line();
const validKeys = conf.vcncSamplerKeys();
const args = cmdl.Input(validKeys);

// TODO: get vcnc version

console.log('\nStart Vcnc Sampler');
// console.log(`Input arguments: ' + json.stringify(args));
const options = cmdl.JSNode('vda');
const logDir = cmdl.JSparam('logDir');
const samplePeriod = cmdl.JSparam('samplePeriod', conf.DefSamplePeriod());
const latency = cmdl.JSparam('latency', conf.DefLatency());

console.log(json.stringify(options));
console.log(`logDir = ${logDir}`);

// Validate input parameters
//

if (logDir === undefined) { // || options.method === 'INVALID') {
  console.log('Invalid input parameters');
  process.exit(1);
}

if (!options.host || !options.port) {
  console.log(`Invalid host/port: ${json.stringify(options)}`);
  process.exit(1);
}

mkdirp(logDir, (err) => {
  if (err) {
    console.log(`Directory ${logDir} could not be created: ${err}`);
    process.exit(1);
  }
});
fs.access(logDir, fs.W_OK, (err) => {
  if (err !== null) {
    console.log(`No directory or no permission to create ${logDir}`);
    console.log('Invalid input parameters');
    process.exit(1);
  }
});

const host = options.host;
const port = options.port;
console.log(`host=${host} port=${port}`);

const tsStart = Date.now();
console.log(`Time (ms):${tsStart}`);
console.log(`Sample period:  ${samplePeriod}`);
console.log(`Output latency:  ${latency}`);

const vcncSample = vs.CreateVcncSampling(samplePeriod, latency);
vcncSample.Init();

// Process buffered messages from VDA
//
function requestHandler(request, response) {
  request.setEncoding('utf8');
  request.on('data', (data) => {
//    console.log(data);
    setInterval(() => {
      vcncSample.Run(data)
    }, 0);
//    .catch (err => {
//      console.log('Warning: VDa data corrupted: ${err}');
//    });

  });
  response.on('error', (err) => {
    console.error(err);
  });
  response.end();
}

const server = http.createServer(requestHandler);
server.setTimeout(5000, () => {
});

server.listen(port, host, () => {
  console.log(`Listening on ${host}:${port}`);
});

// Pass data to rethinkdb
const pushTimeout = vcncSample.PushTimeout();
const trimTimeout = vcncSample.TrimTimeout();
// console.log('pushTimeout = ' + pushTimeout +  ' trimTimeout = ' + trimTimeout);

setInterval(() => {
  vcncSample.Send();
}, pushTimeout);

// Remove old data from rethinkdb table

setInterval(() => {
  vcncSample.Trim();
}, trimTimeout);

// Process Linux signals
//
// Processing of Linux signals
//
process.on('SIGINT', () => {
  console.log('Caught SIGINT interrupt signal');
  delete cnctrqClient;
  process.exit(0);
});

process.on('SIGTERM', () => {
  console.log('Caught SIGTERM interrupt signal');
  delete cnctrqClient;
  process.exit(0);
});

process.on('SIGUSR1', () => {
  console.log('Caught SIGUSR1 interrupt signal');
});

<commit_msg>Resolved merging issues<commit_after>/*
 *    Copyright (C) 2017    IC Manage Inc.
 *
 *    See the file 'COPYING' for license information.
 */
 /**
 * Starts server to get DA messages using POST method of REST API
 *
 * Run file: node app.js --postServer=POST,host,port
 *                                       --logfile=<path_to_da_messages.log> -
 *                                                    path_to_console_ouput.log
 *  @param --postServer=POST,host,port - POST - using REST API method
 *                                              (if it's not POST exit with Error);
 *                                              host - server IP;
 *                                              port - listening port
 *  @param --logFile=log-file          - log-file - contains all data post by DA in json-format;
 *
 */

// Include the necessary modules.
const http = require('http');
const fs = require('fs');
const mkdirp = require('mkdirp');
const json = require('JSON');
const path = require('path');
//
const jsu = require('./src/lib/vcncSamplerUtils');
const conf = require('./src/vcncSampler.conf');
const vs = require('./src/lib/vcncSampling');

//
//  Initialize the C++ extension
//
const extensionPath = '../js-extension/build/Release/cnctrq_client';
const CnctrqClient = require(extensionPath).CnctrqClient;
const cnctrqClient = new CnctrqClient();
cnctrqClient.call_me_first(path.join(__dirname, '..'));

const cmdl = jsu.cmd_line();
const validKeys = conf.vcncSamplerKeys();
const args = cmdl.Input(validKeys);

// TODO: get vcnc version

console.log('\nStart Vcnc Sampler');
// console.log(`Input arguments: ' + json.stringify(args));
const options = cmdl.JSNode('vda');
const logDir = cmdl.JSparam('logDir');
const samplePeriod = cmdl.JSparam('samplePeriod', conf.DefSamplePeriod());
const latency = cmdl.JSparam('latency', conf.DefLatency());

console.log(json.stringify(options));
console.log(`logDir = ${logDir}`);

// Validate input parameters
//

if (logDir === undefined) { // || options.method === 'INVALID') {
  console.log('Invalid input parameters');
  process.exit(1);
}

if (!options.host || !options.port) {
  console.log(`Invalid host/port: ${json.stringify(options)}`);
  process.exit(1);
}

mkdirp(logDir, (err) => {
  if (err) {
    console.log(`Directory ${logDir} could not be created: ${err}`);
    process.exit(1);
  }
});
fs.access(logDir, fs.W_OK, (err) => {
  if (err !== null) {
    console.log(`No directory or no permission to create ${logDir}`);
    console.log('Invalid input parameters');
    process.exit(1);
  }
});

const host = options.host;
const port = options.port;
console.log(`host=${host} port=${port}`);

const tsStart = Date.now();
console.log(`Time (ms):${tsStart}`);
console.log(`Sample period:  ${samplePeriod}`);
console.log(`Output latency:  ${latency}`);

const vcncSample = vs.CreateVcncSampling(samplePeriod, latency);
vcncSample.Init();

// Process buffered messages from VDA
//
function requestHandler(request, response) {
  request.setEncoding('utf8');
  request.on('data', (data) => {
//    console.log(data);
    setInterval(() => {
      vcncSample.Run(data)
    }, 0);
//    .catch (err => {
//      console.log('Warning: VDa data corrupted: ${err}');
//    });

  });
  response.on('error', (err) => {
    console.error(err);
  });
  response.end();
}

const server = http.createServer(requestHandler);
server.setTimeout(5000, () => {
});

server.listen(port, host, () => {
  console.log(`Listening on ${host}:${port}`);
});

// Pass data to rethinkdb
const pushTimeout = vcncSample.PushTimeout();
const trimTimeout = vcncSample.TrimTimeout();
// console.log('pushTimeout = ' + pushTimeout +  ' trimTimeout = ' + trimTimeout);

setInterval(() => {
  vcncSample.Send();
}, pushTimeout);

// Remove old data from rethinkdb table
setInterval(() => {
  vcncSample.Trim();
}, trimTimeout);

// Process Linux signals
//
// Processing of Linux signals
//
process.on('SIGINT', () => {
  console.log('Caught SIGINT interrupt signal');
  delete cnctrqClient;
  process.exit(0);
});

process.on('SIGTERM', () => {
  console.log('Caught SIGTERM interrupt signal');
  delete cnctrqClient;
  process.exit(0);
});

process.on('SIGUSR1', () => {
  console.log('Caught SIGUSR1 interrupt signal');
});

<|endoftext|>


<commit_before>app.constant("PROFILEACTIVATION_ENDPOINT", "php/apis/activation/");

/**
 * Initialize the activation service
 */
app.service("ProfileActivationService", function($http, PROFILEACTIVATION_ENDPOINT) {
	function getUrl() {
		return (PROFILEACTIVATION_ENDPOINT);
	}

	function getUrlForId(profileId) {
		return (getUrl() + profileId);
	}

	/**
	 * fetch profile by activation token and profile id
	 */

	this.fetchProfileByProfileActivationToken = function(profileActivationToken) {
		return ($http.get(getUrl() + "?profileActivationToken=" + profileActivationToken));
	};

	this.fetchProfileByProfileId = function(profileId) {
		return ($http.get(getUrl() + "?profileId=" + profileId));
	};

});<commit_msg>added comment/question https://app.asana.com/0/161555263951762/170520114054348<commit_after>app.constant("PROFILEACTIVATION_ENDPOINT", "php/apis/activation/");

/**
 * Initialize the activation service
 */

//not sure if I should use profileActivationToken or ActivationToken
app.service("ProfileActivationService", function($http, PROFILEACTIVATION_ENDPOINT) {
	function getUrl() {
		return (PROFILEACTIVATION_ENDPOINT);
	}

	function getUrlForId(profileId) {
		return (getUrl() + profileId);
	}

	/**
	 * fetch profile by activation token and profile id
	 */

	this.fetchProfileByProfileActivationToken = function(profileActivationToken) {
		return ($http.get(getUrl() + "?profileActivationToken=" + profileActivationToken));
	};

	this.fetchProfileByProfileId = function(profileId) {
		return ($http.get(getUrl() + "?profileId=" + profileId));
	};

});<|endoftext|>


<commit_before>/*
 * grunt-bb_pep_generate
 * https://github.com/jmanuelrp/bb_pep_amdtemplates
 *
 * Copyright (c) 2013 JManuel Ruiz
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  grunt.registerMultiTask('bb_pep_generate', 'The best Grunt plugin ever.', function( name ) {

    var options = this.options({ source: 'app/js/backbone' });

    var elements = (function() {
      var elements = [
        { tplname: 'view.js'       ,extension: '.js'   ,name: 'view'       },
        { tplname: 'model.js'      ,extension: '.js'   ,name: 'model'      },
        { tplname: 'collection.js' ,extension: '.js'   ,name: 'collection' },
        { tplname: 'router.js'     ,extension: '.js'   ,name: 'router'     },
        { tplname: 'module.js'     ,extension: '.js'   ,name: 'module'     },
        { tplname: 'template.js'   ,extension: '.html' ,name: 'template'   }
      ];

      var _get = function(name) {
        if (typeof name === 'undefined' || !name)
        {
          return null;
        }

        for (var i = 0; i < elements.length; i++) {
          if( elements[i].name === name )
          {
            return elements[i];
          }
        }

        return null;
      };

      return {
        has: function(name) {
          return (_get(name)!==null)? true : false;
        },
        get: function(name) {
          return _get(name);
        }
      };
    })();

    var ElementCreator = function (el, options) {
      var template, tplpath;

      tplpath  = __dirname + '/../templates/' + el.tplname;
      template = grunt.file.read( tplpath );

      return {
        make: function( name ) {
          if( typeof name === 'undefined' ){
            grunt.fail.warn('the name has not been specified.');
            // return grunt.log.error('Missing name.');
            name = 'name';
          }
          // BUG: Incluir pluralizacion
          var filepath = options.source +'/'+ el.name +'s/'+ name + el.extension;

          if( grunt.file.exists(filepath) ){
            grunt.fail.warn('File already exists ('+ filepath +').');
          }

          var content, message, data;

          data = {
            name: name,
            options: options
          };

          content = grunt.template.process(template, { data:data });
          grunt.file.write(filepath, content);

          message = 'Great! '+ name +' '+ el.name +' has been created ('+ filepath +').';
          grunt.log.writeln(message);

        }
      };
    };

    if (!elements.has(this.target)) {
      grunt.fail.fatal('Missing arguments');
    }

    var f = new ElementCreator(elements.get(this.target), options);
    f.make( name );
  });

};
<commit_msg>Nombre de archivo incorrecto para el template<commit_after>/*
 * grunt-bb_pep_generate
 * https://github.com/jmanuelrp/bb_pep_amdtemplates
 *
 * Copyright (c) 2013 JManuel Ruiz
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  grunt.registerMultiTask('bb_pep_generate', 'The best Grunt plugin ever.', function( name ) {

    var options = this.options({ source: 'app/js/backbone' });

    var elements = (function() {
      var elements = [
        { tplname: 'view.js'       ,extension: '.js'   ,name: 'view'       },
        { tplname: 'model.js'      ,extension: '.js'   ,name: 'model'      },
        { tplname: 'collection.js' ,extension: '.js'   ,name: 'collection' },
        { tplname: 'router.js'     ,extension: '.js'   ,name: 'router'     },
        { tplname: 'module.js'     ,extension: '.js'   ,name: 'module'     },
        { tplname: 'template.html' ,extension: '.html' ,name: 'template'   }
      ];

      var _get = function(name) {
        if (typeof name === 'undefined' || !name)
        {
          return null;
        }

        for (var i = 0; i < elements.length; i++) {
          if( elements[i].name === name )
          {
            return elements[i];
          }
        }

        return null;
      };

      return {
        has: function(name) {
          return (_get(name)!==null)? true : false;
        },
        get: function(name) {
          return _get(name);
        }
      };
    })();

    var ElementCreator = function (el, options) {
      var template, tplpath;

      tplpath  = __dirname + '/../templates/' + el.tplname;
      template = grunt.file.read( tplpath );

      return {
        make: function( name ) {
          if( typeof name === 'undefined' ){
            grunt.fail.warn('the name has not been specified.');
            // return grunt.log.error('Missing name.');
            name = 'name';
          }
          // BUG: Incluir pluralizacion
          var filepath = options.source +'/'+ el.name +'s/'+ name + el.extension;

          if( grunt.file.exists(filepath) ){
            grunt.fail.warn('File already exists ('+ filepath +').');
          }

          var content, message, data;

          data = {
            name: name,
            options: options
          };

          content = grunt.template.process(template, { data:data });
          grunt.file.write(filepath, content);

          message = 'Great! '+ name +' '+ el.name +' has been created ('+ filepath +').';
          grunt.log.writeln(message);

        }
      };
    };

    if (!elements.has(this.target)) {
      grunt.fail.fatal('Missing arguments');
    }

    var f = new ElementCreator(elements.get(this.target), options);
    f.make( name );
  });

};
<|endoftext|>


<commit_before>/*
 Copyright 2013 Daniel Wirtz <dcode@dcode.io>

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/**
 * grunt-closurecompiler Task (c) 2013 Daniel Wirtz <dcode@dcode.io>
 * Released under the Apache License, Version 2.0
 * see: https://github.com/dcodeIO/ClosureCompiler.js for details
 */

'use strict';

module.exports = function (grunt) {

    grunt.registerMultiTask('closurecompiler', 'Compile through ClosureCompiler.js', function () {

        var options = this.options({
            "compilation_level": "SIMPLE_OPTIMIZATIONS",
            "max_processes": Number.MAX_VALUE
        });
        var banner = "";

        if (options.banner !== undefined) {
            banner = options.banner+"\n";
            delete options.banner;
        }

        var maxProcesses = options.max_processes;
        delete options.max_processes;

        if (maxProcesses < 1) {
            grunt.log.warn("max_processes must be at least 1");
            maxProcesses = 1;
        }

        var ClosureCompiler = require("closurecompiler");
        var done = this.async();
        var running = 0;
        var to = null;

        if (this.files.length === 0) {
            done();
            return;
        }

        var next = 0;

        var startClosure = function() {

            while(next < this.files.length && running < maxProcesses) {
                var file = this.files[next++];
                var sources = file.src;
                var dest = file.dest;

                grunt.log.subhead("Compiling "+sources+" -> "+dest);

                if (sources.length === 0 || !dest) {
                    grunt.log.error("Please provide at least one source and exactly one destination file.");
                } else {
                    running++;
                    ClosureCompiler.compile(sources, options, function(error, result) {
                        if (result) {
                            grunt.file.write(dest, result=banner+result);
                            if (error) {
                                grunt.log.warn(""+error);
                            }
                            grunt.log.ok("Complete: "+result.length);
                        } else if (error) {
                            grunt.fail.warn(error);
                        } else {
                            grunt.log.ok("Complete: no output");
                        }
                        running--;
                        startClosure(); /* When a process exits, see if we can start more */
                    });
                }
            }

            if (running === 0) {
                done();
            }
        }.bind(this);

        startClosure();
    });

};
<commit_msg>wrap with function inside loops<commit_after>/*
 Copyright 2013 Daniel Wirtz <dcode@dcode.io>

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/**
 * grunt-closurecompiler Task (c) 2013 Daniel Wirtz <dcode@dcode.io>
 * Released under the Apache License, Version 2.0
 * see: https://github.com/dcodeIO/ClosureCompiler.js for details
 */

'use strict';

module.exports = function (grunt) {

    grunt.registerMultiTask('closurecompiler', 'Compile through ClosureCompiler.js', function () {

        var options = this.options({
            "compilation_level": "SIMPLE_OPTIMIZATIONS",
            "max_processes": Number.MAX_VALUE
        });
        var banner = "";

        if (options.banner !== undefined) {
            banner = options.banner+"\n";
            delete options.banner;
        }

        var maxProcesses = options.max_processes;
        delete options.max_processes;

        if (maxProcesses < 1) {
            grunt.log.warn("max_processes must be at least 1");
            maxProcesses = 1;
        }

        var ClosureCompiler = require("closurecompiler");
        var done = this.async();
        var running = 0;
        var to = null;

        if (this.files.length === 0) {
            done();
            return;
        }

        var next = 0;

        var startClosure = function() {

            while(next < this.files.length && running < maxProcesses) {
                (function() {
                    var file = this.files[next++];
                    var sources = file.src;
                    var dest = file.dest;

                    grunt.log.subhead("Compiling "+sources+" -> "+dest);

                    if (sources.length === 0 || !dest) {
                        grunt.log.error("Please provide at least one source and exactly one destination file.");
                    } else {
                        running++;
                        ClosureCompiler.compile(sources, options, function(error, result) {
                            if (result) {
                                grunt.file.write(dest, result=banner+result);
                                if (error) {
                                    grunt.log.warn(""+error);
                                }
                                grunt.log.ok("Complete: "+result.length);
                            } else if (error) {
                                grunt.fail.warn(error);
                            } else {
                                grunt.log.ok("Complete: no output");
                            }
                            running--;
                            startClosure(); /* When a process exits, see if we can start more */
                        });
                    }
                }).call(this);
            }

            if (running === 0) {
                done();
            }
        }.bind(this);

        startClosure();
    });

};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {Card, CardActions, CardHeader, CardMedia, CardTitle, CardText} from 'material-ui/Card';
import CustomTitle from '../Cards/CustomTitle';

const i18n_strings = {
  fr: {
    title: "Animations 2016",
    mabotte: {
      title: "Théâtre des Marionnettes de Mabotte",
      headline: "Théâtre de marionnettes liégeoises (Belgique - Wallonie) - Samedi et dimanche / COUR",
      desc: "Un théâtre de marionnettes traditionnelles liégeoises: de quoi réjouir les plus jeunes d'entre nous! Le Théâtre Mabotte rassemble des professionnels qui perpétuent avec talent cette vieille tradition. Avec brio, alors venez les rejoindre!",
      website: "Site web"
    }
  },
  en: {
    title: "Revel 2016",
    mabotte: {
      title: "Puppet Theatre",
      headline: "Puppet Theater from Liege (Wallonia) - Saturday and sunday / COURTYARD",
      desc: "A traditional puppet theater from Liège has enough to delight the youngest among us. The Mabotte Theater brings together professionals who perpetuate this old tradition with talent. Brilliant! So come and join them!",
      website: "Website"
    }
  },
  nl: {
    title: "Animaties 2016",
    mabotte: {
      title: "Poppentheater van de Mabotte (België)",
      headline: "Luiks poppentheater (Wallonië) – Zaterdag en Zondag / BINNENPLAATS",
      desc: "Een traditioneel Luiks poppentheater om de jongsten onder ons te verheugen ! Theater Mabotte brengt professionelen met talent die deze traditie met talent bestendigen. Met brio, dus kom meedoen!",
      website: "Website"
    }
  },

};

export default class ActivitiesPage extends React.Component {

  render() {
    var strings = i18n_strings[this.props.lang] || i18n_strings['fr'];

    return (

        <CustomTitle title={strings.title} />

        <Card>
          <CardTitle title={strings.mabotte.title}
                     subtitle={strings.mabotte.headline} />
          <CardText>

              {strings.mabotte.desc}

              {strings.mabotte.website}:
                www.theatremabotte.be

          </CardText>
        </Card>

    );
  }
}
<commit_msg>Update Activities.js<commit_after>import React, { Component } from 'react';
import {Card, CardActions, CardHeader, CardMedia, CardTitle, CardText} from 'material-ui/Card';
import CustomTitle from '../Cards/CustomTitle';

const i18n_strings = {
  fr: {
    title: "Animations 2016",
    mabotte: {
      title: "Théâtre des Marionnettes de Mabotte",
      headline: "Théâtre de marionnettes liégeoises (Belgique - Wallonie) - Samedi et Dimanche / COUR",
      desc: "Un théâtre de marionnettes traditionnelles liégeoises: de quoi réjouir les plus jeunes d'entre nous! Le Théâtre Mabotte rassemble des professionnels qui perpétuent avec talent cette vieille tradition. Avec brio, alors venez les rejoindre!",
      website: "Site web"
    }
    maquillage: {
      title: "Maquillage pour enfants",
      headline: "(Belgique - Wallonie) - Samedi et Dimanche / MARCHÉ",
      desc: "Des oeuvres d'art éphémères sur les plus belles oeuvres d'art des parents, le temps pour les enfants de jouer à quelqu'un d'autre!",
      desc2: "Maquilleuse : Viviane Desmet"
    }
    initiation: {
      title: "Initiation à l'épinette",
      desc: "Le luthier Peter Verhoeven propose un cours d'initiation à l'épinette, le dimanche 11 septembre, heure à préciser",
    }
    bourse: {
      title: "Bourse musicale",
      desc: (

         Deux musiciens de confiance, André Deru et Thierry Legros (du groupe Salon Ambroisine), proposent cette année une bourse musicale à Marsinne.

        Vous souhaitez vendre un «objet musical» ?

        Venez le confier à ce stand pour la journée (reprise à 18h30 au plus tard). Indiquez le prix demandé ou/et un numéro de gsm où l'acheteur potentiel pourrait vous joindre.
        André Deru et Thierry Legros accueilleront les dépôts avec la plus grande attention et veilleront de leur mieux à ce que ces objets ne subissent aucun dégât.
        Cependant, ils ne pourront être tenus pour responsables en cas de dégât ou de vol.

        Vous souhaitez acheter un «objet musical» ?

        Acquittez-vous du prix demandé ou, s'il y a lieu, contactez le vendeur.

      ),
    },
  },
  en: {
    title: "Revel 2016",
    mabotte: {
      title: "Mabotte Puppet Theatre",
      headline: "Puppet Theater from Liege (Wallonia) - Saturday and Sunday / COURTYARD",
      desc: "A traditional puppet theater from Liège has enough to delight the youngest among us. The Mabotte Theater brings together professionals who perpetuate this old tradition with talent. Brilliant! So come and join them!",
      website: "Website"
    }
    maquillage: {
      title: "Children make-up",
      headline: "(Belgium - Wallonia) - Saturday and Sunday / MARKET",
      desc: "Ephemeral works of art on the most beautiful artworks of parents, time for children to play someone else !",
      desc2: "Make-up artist : Viviane Desmet"
    }
    initiation: {
      title: "Introductory course épinette",
      desc: "Instrument maker Peter Verhoeven proposes an introductory course on Sunday September 11th, hour to be specified",
    }
    bourse: {
      title: "Musical market",
      desc: (

         Two reliable musicians, André Deru et Thierry Legros (from the band Salon Ambroisine), propose this year a musical market in Marsinne.

        Do you wish to sell a musical instrument ?

        Confide it to this stand for the day (taken back at 6:30 pm at the latest). Indicate the asking price or / and a mobile phone number where the potential buyer could contact you.
        André Deru and Thierry Legros will welcome the instruments with the biggest attention and will take care so that these objects undergo no damage.
        However, they cannot be held responsible in case of damage or theft.

        do you wish to buy a musical instrument ?

        Pay the asking price or, if necessary, contact the seller.

      ),
    },
  },
  nl: {
    title: "Animaties 2016",
    mabotte: {
      title: "Poppentheater Mabotte (België)",
      headline: "Luiks poppentheater (Wallonië) – Zaterdag en Zondag / BINNENPLAATS",
      desc: "Het traditioneel Luiks poppentheater zal onze jongsten bekoren ! Theater Mabotte brengt professionelen samen die talentvol de oude traditie voortzetten. Met brio, dus kom meedoen !",
      website: "Website"
    },
    maquillage: {
      title: "Grimeren voor kinderen",
      headline: "(België - Wallonië) – Zaterdag en Zondag / MARKT",
      desc: "Vergankelijke kunstwerken op de mooiste kunstwerken van de ouders, het moment voor de kinderen om met iemand anders te spelen !",
      desc2: "Begeleiding : Viviane Desmet"
    },
    initiation: {
      title: "Introductiecursus épinette",
      desc: "Instrument maker Peter Verhoeven telt een introductiecursus op zondag 11 september, uur te specificeren",
    }
    bourse: {
      title: "Muzikale markt",
      desc: (

         Twee betrouwbare muzikanten, André Deru et Thierry Legros (groep Salon Ambroisine) stellen dit jaar een muzikale markt in Marsinne.

        U wenst een muziekinstrument te verkopen ?

        Laat uw instrument op dit stand voor de dag (hervatting om 18u30 bij het laatste). Geef de vraagprijs of / en een GSM nummer waar de potentiële koper kan uw bellen.
        André Deru en Thierry Legros zullen de instrumenten met de grootste aandacht krijgen en zorgen dat deze objecten niet worden beschadigd.
        Ze kunnen echter niet verantwoordelijk worden gehouden in geval van schade of diefstal.

        U wenst een muziekinstrument te kopen ?

        Betaal de vraagprijs of, indien nodig, neem contact op met de verkoper.

      ),
    },
  },
};

export default class ActivitiesPage extends React.Component {

  render() {
    var strings = i18n_strings[this.props.lang] || i18n_strings['fr'];

    return (

        <CustomTitle title={strings.title} />

        <Card>
          <CardTitle title={strings.mabotte.title}
                     subtitle={strings.mabotte.headline} />
          <CardText>

              {strings.mabotte.desc}

              {strings.mabotte.website}:
                www.theatremabotte.be

          </CardText>
        </Card>

        <Card>
          <CardTitle title={strings.maquillage.title}
                     subtitle={strings.maquillage.headline} />
          <CardText>

              {strings.maquillage.desc}

              {strings.maquillage.desc2}

          </CardText>
        </Card>

        <Card>
          <CardTitle title={strings.initiation.title}
                     subtitle="" />
          <CardText>
            {strings.initiation.desc}
          </CardText>
        </Card>

        <Card>
          <CardTitle title={strings.bourse.title}
                     subtitle="" />
          <CardText>
            {strings.bourse.desc}
          </CardText>
        </Card>

    );
  }
}
<|endoftext|>