<commit_before>/*
 * Apache 2.0 License
 *
 * Copyright (c) Sebastian Katzer 2017
 *
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apache License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://opensource.org/licenses/Apache-2.0/ and read it before using this
 * file.
 *
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 */

var exec = require('cordova/exec');

/**
 * Check permission to show notifications.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.hasPermission = function (callback, scope) {
    var fn = this.createCallbackFn(callback, scope);

    exec(fn, null, 'LocalNotification', 'check', []);
};

/**
 * Request permission to show notifications.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.requestPermission = function (callback, scope) {
    var fn = this.createCallbackFn(callback, scope);

    exec(fn, null, 'LocalNotification', 'request', []);
};

/**
 * Schedule notifications.
 *
 * @param [ Array ]    notifications The notifications to schedule.
 * @param [ Function ] callback      The function to be exec as the callback.
 * @param [ Object ]   scope         The callback function's scope.
 * @param [ Object ]   args          Optional flags how to schedule.
 *
 * @return [ Void ]
 */
exports.schedule = function (msgs, callback, scope, args) {
    var fn = function (granted) {

        if (!granted) return;

        var notifications = Array.isArray(msgs) ? msgs : [msgs];

        for (var i = 0; i < notifications.length; i++) {
            var notification = notifications[i];

            this.mergeWithDefaults(notification);
            this.convertProperties(notification);
        }

        this.exec('schedule', notifications, callback, scope);

        //var toasts = this.toArray(msgs);

        //for (var toast of toasts) {
        //    this.mergeWithDefaults(toast);
        //    this.convertProperties(toast);
        //}

        //this.exec('schedule', notifications, callback, scope);
    };

    if (args && args.skipPermission) {
        fn.call(this, true);
    } else {
        this.requestPermission(fn, this);
    }
};

/**
 * Schedule notifications.
 *
 * @param [ Array ]    notifications The notifications to schedule.
 * @param [ Function ] callback      The function to be exec as the callback.
 * @param [ Object ]   scope         The callback function's scope.
 * @param [ Object ]   args          Optional flags how to schedule.
 *
 * @return [ Void ]
 */
exports.update = function (msgs, callback, scope, args) {
    var fn = function(granted) {

        if (!granted) return;

        var notifications = Array.isArray(msgs) ? msgs : [msgs];

        for (var i = 0; i < notifications.length; i++) {
            var notification = notifications[i];

            this.convertProperties(notification);
        }               }

        this.exec('update', notifications, callback, scope);

        //var toasts = this.toArray(msgs);

        //for (var toast of toasts) {
        //    this.convertProperties(toast);        }

        //this.exec('update', toasts, callback, scope);
    };

    if (args && args.skipPermission) {
        fn.call(this, true);
    } else {
        this.requestPermission(fn, this);
    }
};

/**
 * Clear the specified notifications by id.
 *
 * @param [ Array<Int> ] ids      The IDs of the notifications.
 * @param [ Function ]   callback The function to be exec as the callback.
 * @param [ Object ]     scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.clear = function (ids, callback, scope) {
    //ids = this.toArray(ids);
    ids = Array.isArray(ids) ? ids : [ids];
    ids = this.convertIds(ids);

    this.exec('clear', ids, callback, scope);
};

/**
 * Clear all triggered notifications.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.clearAll = function (callback, scope) {
    this.exec('clearAll', null, callback, scope);
};

/**
 * Clear the specified notifications by id.
 *
 * @param [ Array<Int> ] ids      The IDs of the notifications.
 * @param [ Function ]   callback The function to be exec as the callback.
 * @param [ Object ]     scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.cancel = function (ids, callback, scope) {
    //ids = this.toArray(ids);
    ids = Array.isArray(ids) ? ids : [ids];
    ids = this.convertIds(ids);

    this.exec('cancel', ids, callback, scope);
};

/**
 * Cancel all scheduled notifications.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.cancelAll = function (callback, scope) {
    this.exec('cancelAll', null, callback, scope);
};

/**
 * Check if a notification is present.
 *
 * @param [ Int ]      id       The ID of the notification.
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.isPresent = function (id, callback, scope) {
    var fn = this.createCallbackFn(callback, scope);

    this.getType(id, function (type) {
        fn(type != 'unknown');
    });
};

/**
 * Check if a notification has a given type.
 *
 * @param [ Int ]      id       The ID of the notification.
 * @param [ String ]   type     The type of the notification.
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.hasType = function (id, type, callback, scope) {
    var fn = this.createCallbackFn(callback, scope);

    this.getType(id, function (type2) {
        fn(type == type2);
    });
};

/**
 * Get the type (triggered, scheduled) for the notification.
 *
 * @param [ Int ]      id       The ID of the notification.
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.getType = function (id, callback, scope) {
    this.exec('type', id, callback, scope);
};

/**
 * List of all notification ids.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.getIds = function (callback, scope) {
    this.exec('ids', null, callback, scope);
};

/**
 * List of all scheduled notification IDs.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.getScheduledIds = function (callback, scope) {
    this.exec('scheduledIds', null, callback, scope);
};

/**
 * List of all triggered notification IDs.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.getTriggeredIds = function (callback, scope) {
    this.exec('triggeredIds', null, callback, scope);
};

/**
 * List of local notifications specified by id.
 * If called without IDs, all notification will be returned.
 *
 * @param [ Array<Int> ] ids      The IDs of the notifications.
 * @param [ Function ]   callback The function to be exec as the callback.
 * @param [ Object ]     scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.get = function () {
    var args = Array.apply(null, arguments);

    if (typeof args[0] == 'function') {
        args.unshift([]);
    }

    var ids      = args[0],
        callback = args[1],
        scope    = args[2];

    if (!Array.isArray(ids)) {
        this.exec('notification', Number(ids), callback, scope);
        return;
    }

    ids = this.convertIds(ids);

    this.exec('notifications', ids, callback, scope);
};

/**
 * List for all notifications.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.getAll = function (callback, scope) {
    this.exec('notifications', null, callback, scope);
};

/**
 * List of all scheduled notifications.
 *
 * @param [ Function ]   callback The function to be exec as the callback.
 * @param [ Object ]     scope    The callback function's scope.
 */
exports.getScheduled = function (callback, scope) {
    this.exec('scheduledNotifications', null, callback, scope);
};

/**
 * List of all triggered notifications.
 *
 * @param [ Function ]   callback The function to be exec as the callback.
 * @param [ Object ]     scope    The callback function's scope.
 */
exports.getTriggered = function (callback, scope) {
    this.exec('triggeredNotifications', null, callback, scope);
};

/**
 * Register an group of actions by id.
 *
 * @param [ String ]   id       The Id of the group.
 * @param [ Array]     actions  The action config settings.
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.addActionGroup = function (id, actions, callback, scope) {
    var config = { actionGroupId: id, actions: actions };
    this.exec('actions', config, callback, scope);
};

/**
 * The (platform specific) default settings.
 *
 * @return [ Object ]
 */
exports.getDefaults = function () {

    return this._defaults;

    //var map = Object.assign({}, this._defaults);

    //for (var key in map) {
    //    if (Array.isArray(map[key])) {
    //        map[key] = Array.from(map[key]);
    //    } else
    //    if (Object.prototype.isPrototypeOf(map[key])) {
    //        map[key] = Object.assign({}, map[key]);
    //    }
    //}

    //return map;
};

/**
 * Overwrite default settings.
 *
 * @param [ Object ] newDefaults New default values.
 *
 * @return [ Void ]
 */
exports.setDefaults = function (newDefaults) {
    //Object.assign(this._defaults, newDefaults);
    var defaults = this.getDefaults();

     for (var key in defaults) {
         if (newDefaults.hasOwnProperty(key)) {
             defaults[key] = newDefaults[key];
         }
     }
};

/**
 * Register callback for given event.
 *
 * @param [ String ]   event    The name of the event.
 * @param [ Function ] callback The function to be exec as callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.on = function (event, callback, scope) {

    if (typeof callback !== "function")
        return;

    if (!this._listener[event]) {
        this._listener[event] = [];
    }

    var item = [callback, scope || window];

    this._listener[event].push(item);
};

/**
 * Unregister callback for given event.
 *
 * @param [ String ]   event    The name of the event.
 * @param [ Function ] callback The function to be exec as callback.
 *
 * @return [ Void ]
 */
exports.un = function (event, callback) {
    var listener = this._listener[event];

    if (!listener)
        return;

    for (var i = 0; i < listener.length; i++) {
        var fn = listener[i][0];

        if (fn == callback) {
            listener.splice(i, 1);
            break;
        }
    }
};
<commit_msg>fix typo<commit_after>/*
 * Apache 2.0 License
 *
 * Copyright (c) Sebastian Katzer 2017
 *
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apache License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://opensource.org/licenses/Apache-2.0/ and read it before using this
 * file.
 *
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 */

var exec = require('cordova/exec');

/**
 * Check permission to show notifications.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.hasPermission = function (callback, scope) {
    var fn = this.createCallbackFn(callback, scope);

    exec(fn, null, 'LocalNotification', 'check', []);
};

/**
 * Request permission to show notifications.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.requestPermission = function (callback, scope) {
    var fn = this.createCallbackFn(callback, scope);

    exec(fn, null, 'LocalNotification', 'request', []);
};

/**
 * Schedule notifications.
 *
 * @param [ Array ]    notifications The notifications to schedule.
 * @param [ Function ] callback      The function to be exec as the callback.
 * @param [ Object ]   scope         The callback function's scope.
 * @param [ Object ]   args          Optional flags how to schedule.
 *
 * @return [ Void ]
 */
exports.schedule = function (msgs, callback, scope, args) {
    var fn = function (granted) {

        if (!granted) return;

        var notifications = Array.isArray(msgs) ? msgs : [msgs];

        for (var i = 0; i < notifications.length; i++) {
            var notification = notifications[i];

            this.mergeWithDefaults(notification);
            this.convertProperties(notification);
        }

        this.exec('schedule', notifications, callback, scope);

        //var toasts = this.toArray(msgs);

        //for (var toast of toasts) {
        //    this.mergeWithDefaults(toast);
        //    this.convertProperties(toast);
        //}

        //this.exec('schedule', notifications, callback, scope);
    };

    if (args && args.skipPermission) {
        fn.call(this, true);
    } else {
        this.requestPermission(fn, this);
    }
};

/**
 * Schedule notifications.
 *
 * @param [ Array ]    notifications The notifications to schedule.
 * @param [ Function ] callback      The function to be exec as the callback.
 * @param [ Object ]   scope         The callback function's scope.
 * @param [ Object ]   args          Optional flags how to schedule.
 *
 * @return [ Void ]
 */
exports.update = function (msgs, callback, scope, args) {
    var fn = function(granted) {

        if (!granted) return;

        var notifications = Array.isArray(msgs) ? msgs : [msgs];

        for (var i = 0; i < notifications.length; i++) {
            var notification = notifications[i];

            this.convertProperties(notification);
        }

        this.exec('update', notifications, callback, scope);

        //var toasts = this.toArray(msgs);

        //for (var toast of toasts) {
        //    this.convertProperties(toast);        }

        //this.exec('update', toasts, callback, scope);
    };

    if (args && args.skipPermission) {
        fn.call(this, true);
    } else {
        this.requestPermission(fn, this);
    }
};

/**
 * Clear the specified notifications by id.
 *
 * @param [ Array<Int> ] ids      The IDs of the notifications.
 * @param [ Function ]   callback The function to be exec as the callback.
 * @param [ Object ]     scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.clear = function (ids, callback, scope) {
    //ids = this.toArray(ids);
    ids = Array.isArray(ids) ? ids : [ids];
    ids = this.convertIds(ids);

    this.exec('clear', ids, callback, scope);
};

/**
 * Clear all triggered notifications.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.clearAll = function (callback, scope) {
    this.exec('clearAll', null, callback, scope);
};

/**
 * Clear the specified notifications by id.
 *
 * @param [ Array<Int> ] ids      The IDs of the notifications.
 * @param [ Function ]   callback The function to be exec as the callback.
 * @param [ Object ]     scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.cancel = function (ids, callback, scope) {
    //ids = this.toArray(ids);
    ids = Array.isArray(ids) ? ids : [ids];
    ids = this.convertIds(ids);

    this.exec('cancel', ids, callback, scope);
};

/**
 * Cancel all scheduled notifications.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.cancelAll = function (callback, scope) {
    this.exec('cancelAll', null, callback, scope);
};

/**
 * Check if a notification is present.
 *
 * @param [ Int ]      id       The ID of the notification.
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.isPresent = function (id, callback, scope) {
    var fn = this.createCallbackFn(callback, scope);

    this.getType(id, function (type) {
        fn(type != 'unknown');
    });
};

/**
 * Check if a notification has a given type.
 *
 * @param [ Int ]      id       The ID of the notification.
 * @param [ String ]   type     The type of the notification.
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.hasType = function (id, type, callback, scope) {
    var fn = this.createCallbackFn(callback, scope);

    this.getType(id, function (type2) {
        fn(type == type2);
    });
};

/**
 * Get the type (triggered, scheduled) for the notification.
 *
 * @param [ Int ]      id       The ID of the notification.
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.getType = function (id, callback, scope) {
    this.exec('type', id, callback, scope);
};

/**
 * List of all notification ids.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.getIds = function (callback, scope) {
    this.exec('ids', null, callback, scope);
};

/**
 * List of all scheduled notification IDs.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.getScheduledIds = function (callback, scope) {
    this.exec('scheduledIds', null, callback, scope);
};

/**
 * List of all triggered notification IDs.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.getTriggeredIds = function (callback, scope) {
    this.exec('triggeredIds', null, callback, scope);
};

/**
 * List of local notifications specified by id.
 * If called without IDs, all notification will be returned.
 *
 * @param [ Array<Int> ] ids      The IDs of the notifications.
 * @param [ Function ]   callback The function to be exec as the callback.
 * @param [ Object ]     scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.get = function () {
    var args = Array.apply(null, arguments);

    if (typeof args[0] == 'function') {
        args.unshift([]);
    }

    var ids      = args[0],
        callback = args[1],
        scope    = args[2];

    if (!Array.isArray(ids)) {
        this.exec('notification', Number(ids), callback, scope);
        return;
    }

    ids = this.convertIds(ids);

    this.exec('notifications', ids, callback, scope);
};

/**
 * List for all notifications.
 *
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.getAll = function (callback, scope) {
    this.exec('notifications', null, callback, scope);
};

/**
 * List of all scheduled notifications.
 *
 * @param [ Function ]   callback The function to be exec as the callback.
 * @param [ Object ]     scope    The callback function's scope.
 */
exports.getScheduled = function (callback, scope) {
    this.exec('scheduledNotifications', null, callback, scope);
};

/**
 * List of all triggered notifications.
 *
 * @param [ Function ]   callback The function to be exec as the callback.
 * @param [ Object ]     scope    The callback function's scope.
 */
exports.getTriggered = function (callback, scope) {
    this.exec('triggeredNotifications', null, callback, scope);
};

/**
 * Register an group of actions by id.
 *
 * @param [ String ]   id       The Id of the group.
 * @param [ Array]     actions  The action config settings.
 * @param [ Function ] callback The function to be exec as the callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.addActionGroup = function (id, actions, callback, scope) {
    var config = { actionGroupId: id, actions: actions };
    this.exec('actions', config, callback, scope);
};

/**
 * The (platform specific) default settings.
 *
 * @return [ Object ]
 */
exports.getDefaults = function () {

    return this._defaults;

    //var map = Object.assign({}, this._defaults);

    //for (var key in map) {
    //    if (Array.isArray(map[key])) {
    //        map[key] = Array.from(map[key]);
    //    } else
    //    if (Object.prototype.isPrototypeOf(map[key])) {
    //        map[key] = Object.assign({}, map[key]);
    //    }
    //}

    //return map;
};

/**
 * Overwrite default settings.
 *
 * @param [ Object ] newDefaults New default values.
 *
 * @return [ Void ]
 */
exports.setDefaults = function (newDefaults) {
    //Object.assign(this._defaults, newDefaults);
    var defaults = this.getDefaults();

     for (var key in defaults) {
         if (newDefaults.hasOwnProperty(key)) {
             defaults[key] = newDefaults[key];
         }
     }
};

/**
 * Register callback for given event.
 *
 * @param [ String ]   event    The name of the event.
 * @param [ Function ] callback The function to be exec as callback.
 * @param [ Object ]   scope    The callback function's scope.
 *
 * @return [ Void ]
 */
exports.on = function (event, callback, scope) {

    if (typeof callback !== "function")
        return;

    if (!this._listener[event]) {
        this._listener[event] = [];
    }

    var item = [callback, scope || window];

    this._listener[event].push(item);
};

/**
 * Unregister callback for given event.
 *
 * @param [ String ]   event    The name of the event.
 * @param [ Function ] callback The function to be exec as callback.
 *
 * @return [ Void ]
 */
exports.un = function (event, callback) {
    var listener = this._listener[event];

    if (!listener)
        return;

    for (var i = 0; i < listener.length; i++) {
        var fn = listener[i][0];

        if (fn == callback) {
            listener.splice(i, 1);
            break;
        }
    }
};
<|endoftext|>


<commit_before>import React from 'react';
import {
  Deck,
  Slide,
  Appear,
  CodePane,
  FlexBox,
  Box,
  Image,
  Heading,
  ListItem,
  OrderedList,
  Quote,
  Text,
  UnorderedList,
  Grid,
  Notes,
  FullScreen,
  Progress,
  Markdown
} from '../../src/';

const formidableLogo = require('./formidable.png');
const cppCodeBlock = `#include <iostream>
#include <cstdlib>
#include <sstream>
#include <pthread.h>

struct thread_data_t
{
   int  thread_id;
   std::string message;
};

void *print_thread_message(void *thread_arg)
{
   struct thread_data_t *thread_data;
   thread_data = (struct thread_data_t *) thread_arg;

   cout << "Thread ID: " << thread_data->thread_id;
   cout << "Message: " << thread_data->message << endl;

   pthread_exit(NULL);
}

int main()
{
  pthread_t threads[NUM_THREADS];
  struct thread_data_t thread_data[NUM_THREADS];

  for (int i = 0; i < NUM_THREADS; i++)
  {
    auto curried_add = [](int x) -> function<int(int)> { return [=](int y) { return x + y; }; };
    auto answer = curried_add(i)(5);

    std::stringstream message;
    message << "The math result is " << answer << "!";
    thread_data.thread_id = i;
    thread_data.message = message.str();
    int err = pthread_create(&threads, NULL, print_thread_message, (void *)&thread_data[i]);

    if (err)
    {
      exit(-1)
    }
  }

  return 0;
}`;

const TestJs = () => (
  <Deck
    template={() => (
      <FlexBox
        justifyContent="space-between"
        position="absolute"
        bottom={0}
        width={1}
      >
        <Box padding="0 1em">
          <FullScreen />
        </Box>
        <Box padding="1em">
          <Progress />
        </Box>
      </FlexBox>
    )}
  >
    <Slide>
      <Heading>Spectacle</Heading>
      <Text>Hello There 🤗</Text>
      <Quote>This is a Formidaquote!</Quote>
      <OrderedList>
        <Appear elementNum={0}>
          <ListItem>This is an</ListItem>
        </Appear>
        <Appear elementNum={1}>
          <ListItem>ordered list</ListItem>
        </Appear>
      </OrderedList>
      <UnorderedList>
        <ListItem>This is an</ListItem>
        <ListItem>unordered list</ListItem>
      </UnorderedList>
      <Notes>

          Notes are shown in presenter mode. Open up
          localhost:3000/?presenterMode=true to see them.

      </Notes>
    </Slide>
    <Slide>
      <Heading>Hi There</Heading>
      <CodePane fontSize={18} language="cpp" autoFillHeight>
        {cppCodeBlock}
      </CodePane>
      <Text>Lots of pointers!</Text>
      <Notes>

          This is a code pane! It can support multiple programming languages.

      </Notes>
    </Slide>
    <Slide>
      <Text fontSize="subHeader">Slide 3!</Text>
      <Appear elementNum={0}>
        <Text>{`Hey, just one "animated" slide element here`}</Text>
      </Appear>
    </Slide>
    <Slide>
      <Text>{`I'm a static slide element that should always show`}</Text>
      <Text>{`This means that we don't need a SlideElementWrapper`}</Text>
      <Appear elementNum={0}>
        <Text> ZERO Slide 4 x 3! </Text>
      </Appear>
      <Appear elementNum={1}>
        <Text> ONE Slide 4 x 3! </Text>
      </Appear>
      <Appear elementNum={2}>
        <Text> TWO Slide 4 x 3! </Text>
      </Appear>
      <Text>{`I'm also a static non-animated "slide element"!`}</Text>
    </Slide>
    <Slide>
      <FlexBox>
        <Text>These</Text>
        <Text>Text</Text>
        <Text color="secondary">Items</Text>
        <Text fontWeight="bold">Flex</Text>
      </FlexBox>
      <Grid gridTemplateColumns="1fr 2fr" gridColumnGap={15}>
        <Box backgroundColor="primary">
          <Text color="secondary">Single-size Grid Item</Text>
        </Box>
        <Box backgroundColor="secondary">
          <Text>Double-size Grid Item</Text>
        </Box>
      </Grid>
      <Heading>Lots of Formidables!</Heading>
      <Grid
        gridTemplateColumns="1fr 1fr 1fr"
        gridTemplateRows="1fr 1fr 1fr"
        alignItems="center"
        justifyContent="center"
        gridRowGap={15}
      >
        {Array(9)
          .fill('')
          .map((_, index) => (
            <FlexBox key={`formidable-logo-${index}`} flex={1}>
              <Image src={formidableLogo} width={100} />
            </FlexBox>
          ))}
      </Grid>
    </Slide>
    <Slide>
      <Markdown>
        {`
          ### Paying for too much Lambda memory?
          - Yes you are!

          \`\`\`js
          fields @timestamp, res.duration
          | filter res.duration > 0
          | sort @timestamp desc
          | limit 20
          | stats min(res.duration), avg(res.duration), max(res.duration) by bin(30m)
          \`\`\`
        `}
      </Markdown>
    </Slide>
    <Markdown containsSlides>
      {`
        ### First MD generated Slide
        ---
        ### Second MD Generated Slide
      `}
    </Markdown>
  </Deck>
);

export default TestJs;
<commit_msg>Bug with indentation problem caused by prettier.<commit_after>import React from 'react';
import {
  Deck,
  Slide,
  Appear,
  CodePane,
  FlexBox,
  Box,
  Image,
  Heading,
  ListItem,
  OrderedList,
  Quote,
  Text,
  UnorderedList,
  Grid,
  Notes,
  FullScreen,
  Progress,
  Markdown
} from '../../src/';

const formidableLogo = require('./formidable.png');
const cppCodeBlock = `#include <iostream>
#include <cstdlib>
#include <sstream>
#include <pthread.h>

struct thread_data_t
{
   int  thread_id;
   std::string message;
};

void *print_thread_message(void *thread_arg)
{
   struct thread_data_t *thread_data;
   thread_data = (struct thread_data_t *) thread_arg;

   cout << "Thread ID: " << thread_data->thread_id;
   cout << "Message: " << thread_data->message << endl;

   pthread_exit(NULL);
}

int main()
{
  pthread_t threads[NUM_THREADS];
  struct thread_data_t thread_data[NUM_THREADS];

  for (int i = 0; i < NUM_THREADS; i++)
  {
    auto curried_add = [](int x) -> function<int(int)> { return [=](int y) { return x + y; }; };
    auto answer = curried_add(i)(5);

    std::stringstream message;
    message << "The math result is " << answer << "!";
    thread_data.thread_id = i;
    thread_data.message = message.str();
    int err = pthread_create(&threads, NULL, print_thread_message, (void *)&thread_data[i]);

    if (err)
    {
      exit(-1)
    }
  }

  return 0;
}`;

const TestJs = () => (
  <Deck
    template={() => (
      <FlexBox
        justifyContent="space-between"
        position="absolute"
        bottom={0}
        width={1}
      >
        <Box padding="0 1em">
          <FullScreen />
        </Box>
        <Box padding="1em">
          <Progress />
        </Box>
      </FlexBox>
    )}
  >
    <Slide>
      <Slide>
        <Markdown>{`
        # hello there

        | hi   | Supported | Versions |
|-----------|-----------|----------|
| Chrome          | Yes       | Last 2   |
| Firefox         | Yes       | Last 2   |
| Opera           | Yes       | Last 2   |
| Edge (EdgeHTML) | No        |          |
| IE 11           | No        |          |`}</Markdown>
      </Slide>
      <Heading>Spectacle</Heading>
      <Text>Hello There 🤗</Text>
      <Quote>This is a Formidaquote!</Quote>
      <OrderedList>
        <Appear elementNum={0}>
          <ListItem>This is an</ListItem>
        </Appear>
        <Appear elementNum={1}>
          <ListItem>ordered list</ListItem>
        </Appear>
      </OrderedList>
      <UnorderedList>
        <ListItem>This is an</ListItem>
        <ListItem>unordered list</ListItem>
      </UnorderedList>
      <Notes>

          Notes are shown in presenter mode. Open up
          localhost:3000/?presenterMode=true to see them.

      </Notes>
    </Slide>
    <Slide>
      <Heading>Hi There</Heading>
      <CodePane fontSize={18} language="cpp" autoFillHeight>
        {cppCodeBlock}
      </CodePane>
      <Text>Lots of pointers!</Text>
      <Notes>

          This is a code pane! It can support multiple programming languages.

      </Notes>
    </Slide>
    <Slide>
      <Text fontSize="subHeader">Slide 3!</Text>
      <Appear elementNum={0}>
        <Text>{`Hey, just one "animated" slide element here`}</Text>
      </Appear>
    </Slide>
    <Slide>
      <Text>{`I'm a static slide element that should always show`}</Text>
      <Text>{`This means that we don't need a SlideElementWrapper`}</Text>
      <Appear elementNum={0}>
        <Text> ZERO Slide 4 x 3! </Text>
      </Appear>
      <Appear elementNum={1}>
        <Text> ONE Slide 4 x 3! </Text>
      </Appear>
      <Appear elementNum={2}>
        <Text> TWO Slide 4 x 3! </Text>
      </Appear>
      <Text>{`I'm also a static non-animated "slide element"!`}</Text>
    </Slide>
    <Slide>
      <FlexBox>
        <Text>These</Text>
        <Text>Text</Text>
        <Text color="secondary">Items</Text>
        <Text fontWeight="bold">Flex</Text>
      </FlexBox>
      <Grid gridTemplateColumns="1fr 2fr" gridColumnGap={15}>
        <Box backgroundColor="primary">
          <Text color="secondary">Single-size Grid Item</Text>
        </Box>
        <Box backgroundColor="secondary">
          <Text>Double-size Grid Item</Text>
        </Box>
      </Grid>
      <Heading>Lots of Formidables!</Heading>
      <Grid
        gridTemplateColumns="1fr 1fr 1fr"
        gridTemplateRows="1fr 1fr 1fr"
        alignItems="center"
        justifyContent="center"
        gridRowGap={15}
      >
        {Array(9)
          .fill('')
          .map((_, index) => (
            <FlexBox key={`formidable-logo-${index}`} flex={1}>
              <Image src={formidableLogo} width={100} />
            </FlexBox>
          ))}
      </Grid>
    </Slide>
    <Slide>
      <Markdown>
        {`
          ### Paying for too much Lambda memory?
          - Yes you are!

          \`\`\`js
          fields @timestamp, res.duration
          | filter res.duration > 0
          | sort @timestamp desc
          | limit 20
          | stats min(res.duration), avg(res.duration), max(res.duration) by bin(30m)
          \`\`\`
        `}
      </Markdown>
    </Slide>
    <Markdown containsSlides>
      {`
        ### First MD generated Slide
        ---
        ### Second MD Generated Slide
      `}
    </Markdown>
  </Deck>
);

export default TestJs;
<|endoftext|>


<commit_before>module.exports = function(config, lessConfig, pathConfig) {
  'use strict';
  var resolve = require('path').resolve;

  var file = {};
  if(pathConfig.plugin) {
    file[pathConfig.buildTarget+'/plugin.css'] = pathConfig.sourceDir + '/styles.less';
  } else {
    file[pathConfig.buildTarget+'/styles/styles.css'] = pathConfig.sourceDir + '/styles/styles.less';
  }
  if (pathConfig.appName === 'cockpit' && !pathConfig.plugin) {
    file[pathConfig.buildTarget+'/styles/styles-components.css'] = pathConfig.sourceDir + '/styles/styles-components.less';
  }

  var eePrefix = config.pkg.name === 'camunda-bpm-webapp-ee' ? 'node_modules/camunda-bpm-webapp/' : '';
  var includePaths = [
    resolve(process.cwd(), '<%= pkg.gruntConfig.commonsUiDir %>/lib/widgets'),
    resolve(process.cwd(), '<%= pkg.gruntConfig.commonsUiDir %>/resources/less'),
    resolve(process.cwd(), '<%= pkg.gruntConfig.commonsUiDir %>/resources/css'),
    resolve(process.cwd(), '<%= pkg.gruntConfig.commonsUiDir %>/node_modules'),

    resolve(process.cwd(), eePrefix + 'ui/common/styles'),
    resolve(process.cwd(), eePrefix + 'ui/' + pathConfig.appName, 'client/styles'),
    resolve(process.cwd(), eePrefix + 'ui/' + pathConfig.appName, 'client/scripts')
  ];

  lessConfig[pathConfig.appName + (pathConfig.plugin ? '_plugin' : '') + '_styles'] = {
    options: {
      paths: includePaths,

      dumpLineNumbers: '<%= buildMode === "prod" ? "" : "comments" %>',
      compress: '<%= buildMode === "prod" ? "true" : "" %>',
      sourceMap: '<%= buildMode === "prod" ? "true" : "" %>',

      sourceMapURL: './styles.css.map',
      sourceMapFilename: pathConfig.plugin ? pathConfig.buildTarget+'/plugin.css.map' : pathConfig.buildTarget + '/styles/styles.css.map'
    },
    files: file
  };

};
<commit_msg>feat(less-build): add source map generation to less task<commit_after>module.exports = function(config, lessConfig, pathConfig) {
  'use strict';
  var path = require('path');

  var file = {};
  if(pathConfig.plugin) {
    file[pathConfig.buildTarget+'/plugin.css'] = pathConfig.sourceDir + '/styles.less';
  } else {
    file[pathConfig.buildTarget+'/styles/styles.css'] = pathConfig.sourceDir + '/styles/styles.less';
  }

  var ee = config.pkg.name === 'camunda-bpm-webapp-ee';
  var eePrefix = ee ? 'node_modules/camunda-bpm-webapp/' : '';
  var includePaths = [
    '<%= pkg.gruntConfig.commonsUiDir %>/lib/widgets',
    '<%= pkg.gruntConfig.commonsUiDir %>/resources/less',
    '<%= pkg.gruntConfig.commonsUiDir %>/resources/css',
    '<%= pkg.gruntConfig.commonsUiDir %>/node_modules',
    eePrefix + 'ui/common/styles',
    eePrefix + 'ui/' + pathConfig.appName + '/client/styles',
    eePrefix + 'ui/' + pathConfig.appName + '/client/scripts'
  ];

  var outputFilepath = Object.keys(file)[0];

  lessConfig[pathConfig.appName + (pathConfig.plugin ? '_plugin' : '') + '_styles'] = {
    options: {
      paths: includePaths,

      compress: true,

      sourceMap: true,
      sourceMapFilename: (pathConfig.plugin ? 'plugin' : 'styles') + '.css.map',
      sourceMapURL: (pathConfig.plugin ? 'plugin' : 'styles') + '.css.map',
      sourceMapFileInline: false
    },
    files: file
  };

  if (pathConfig.appName === 'cockpit' && !pathConfig.plugin) {
    file = {};
    outputFilepath = pathConfig.buildTarget + '/styles/styles-components.css';
    file[outputFilepath] = pathConfig.sourceDir + '/styles/styles-components.less';

    lessConfig.cockpit_styles_components = {
      options: {
        paths: includePaths,

        compress: true,

        sourceMap: true,
        sourceMapFilename: 'styles-components.css.map',
        sourceMapURL: './styles-components.css.map',
        sourceMapFileInline: false
      },
      files: file
    };
  }
};
<|endoftext|>


<commit_before>export { Bounds, ScaleTranslate };

/**
 * Describe the [ lower, upper ] bounds of a floating-point value
 *
 * @member {number} lower
 *   The lower bound of the range.
 *
 * @member {number} upper
 *   The upper bound of the range.
 *
 * @member {number} difference
 *   The distance between lower and upper.
 */
class Bounds {

  constructor( lower, upper ) {
    this.lower = Math.min( lower, upper ); // Confirm ( lower <= upper ).
    this.upper = Math.max( lower, upper );
  }

  get difference() {
    let difference = this.upper - this.lower;
    return difference;
  }

  /**
   * @return {Bounds}
   *   Return newly created object which is a copy of this Bounds.
   */
  clone() {
    return new Bounds( this.lower, this.upper );
  }

  /**
   * @param {Bounds} aBounds
   *   Set this Bounds by aBounds.
   *
   * @return {Bounds}
   *   Return this (modified) object which copies aBounds.
   */
  set_Bounds( aBounds ) {
    this.lower = aBounds.lower;
    this.upper = aBounds.upper;
    return this;
  }

  /**
   * @param {number} aLower
   *   Set this Bounds.lower by aLower.
   *
   * @param {number} aUpper
   *   Set this Bounds.upper by aUpper.
   *
   * @return {Bounds}
   *   Return this (modified) object which is [ aLower, aUpper ].
   */
  set_LowerUpper( aLower, aUpper ) {
    this.lower = aLower;
    this.upper = aUpper;
    return this;
  }

  /**
   * @param {Bounds} aBounds
   *   Add this Bounds by aBounds.
   *
   * @return {Bounds}
   *   Return this (modified) object which is added by aBounds.
   */
  add_Bounds( aBounds ) {
    this.lower += aBounds.lower;
    this.upper += aBounds.upper;
    return this;
  }

  /**
   * @param {number} aLower
   *   Add this Bounds.lower by aLower.
   *
   * @param {number} aUpper
   *   Add this Bounds.upper by aUpper.
   *
   * @return {Bounds}
   *   Return this (modified) object which is added by Bounds [ aLower, aUpper ].
   */
  add_LowerUpper( aLower, aUpper ) {
    this.lower += aLower;
    this.upper += aUpper;
    return this;
  }

  /**
   * @param {Bounds} aBounds
   *   Multiply this Bounds by aBounds.
   *
   * @return {Bounds}
   *   Return this (modified) object which is multiplied by aBounds.
   */
  multiply_Bounds( aBounds ) {
    this.lower *= aBounds.lower;
    this.upper *= aBounds.upper;
    return this;
  }

  /**
   * @param {number} aLower
   *   Multiply this Bounds.lower by aLower.
   *
   * @param {number} aUpper
   *   Multiply this Bounds.upper by aUpper.
   *
   * @return {Bounds}
   *   Return this (modified) object which is multiplied by Bounds [ aLower, aUpper ].
   */
  multiply_LowerUpper( aLower, aUpper ) {
    this.lower *= aLower;
    this.upper *= aUpper;
    return this;
  }

  /**
   * @param {number} N
   *   The multiplier of this.lower and this.upper.
   *
   * @return {Bounds}
   *   Return this (modified) object which is the same as this.multiply_LowerUpper( N, N ) or repeating N times this.add_Bounds( this ).
   */
  multiply_N( N ) {
    this.lower *= N;
    this.upper *= N;
    return this;
  }

  /**
   * @param {Bounds} aBounds
   *   The first multiplier (a Bounds).
   *
   * @param {number} N
   *   The second multiplier (a number).
   *
   * @return {Bounds}
   *   Return this (modified) object which is the sumed Bounds of repeating N times of multiplying this by aBounds.
   */
  multiply_Bounds_multiply_N( aBounds, N ) {
    this.lower = ( this.lower * aBounds.lower ) * N;
    this.upper = ( this.upper * aBounds.upper ) * N;
    return this;

    // The same as:
    //return this.multiply_Bounds( aBounds ).multiply_N( N );
  }

  /**
   * Confirm:
   *   - Every element is not NaN. (If it is, become 0.)
   *   - Every element is between [ lower, upper ].
   *
   * @param {Float32Array} source
   *   The source Float32Array.
   *
   * @return {Float32Array}
   *   Return a copy of source. Every element (float32):
   *     - If ( Number.isNaN( element ) == true ), let it become 0.
   *     - Otherwise, Math.max( lower, Math.min( element, upper ) ).
   */
  Float32Array_RestrictedClone( sourceArray ) {
    let resultArray = new Float32Array( sourceArray.length );
    for ( let i = 0; i < sourceArray.length; ++i ) {
      let element = sourceArray[ i ];
      if ( !Number.isNaN( element ) ) {
        resultArray[ i ] = Math.max( this.lower, Math.min( element, this.upper ) );
      } // If NaN, let it become 0. (Just do nothing, because Float32Array is initialized to zero by default.)
    }
    return resultArray;
  }

}

/**
 * Describe a scale (i.e. multiplier) value, and then a translate (i.e. offset; bias) value after the scale. Note that the order
 * is important: scale first, translate second.
 *
 * @member {number} scale
 *   The scale (i.e. multiplier) value.
 *
 * @member {number} translate
 *   The translate (i.e. offset) value.
 */
class ScaleTranslate {

  constructor( scale, translate ) {
    this.scale = scale;
    this.translate = translate;
  }

  set_scale_translate( scale, translate ) {
    this.scale = scale;
    this.translate = translate;
  }

  /**
   * Set this.scale and this.translate for mapping values from source bounds to target bounds.
   *
   * @param {Bounds} source
   *   The range of the source value.
   *
   * @param {Bounds} target
   *   The range of the target value.
   */
  setBy_FromTo( source, target ) {
    // Suppose x is a value inside the source range. y is the corresponding value inside the target range.
    //
    //   y = target.lower + ( target.difference * ( x - source.lower ) / source.difference )
    //     = target.lower + ( ( ( target.difference * x ) - ( target.difference * source.lower ) ) / source.difference )
    //     = target.lower + ( ( ( target.difference * x ) / source.difference ) - ( ( target.difference * source.lower ) / source.difference ) )
    //     = target.lower + ( ( ( target.difference / source.difference ) * x ) - ( ( target.difference * source.lower ) / source.difference ) )
    //     = target.lower + ( ( target.difference / source.difference ) * x ) - ( ( target.difference * source.lower ) / source.difference )
    //     = ( ( target.difference / source.difference ) * x ) + ( target.lower - ( ( target.difference * source.lower ) / source.difference ) )
    //     = ( scale * x ) + translate
    //
    // Got:
    //   scale = ( target.difference / source.difference )
    //   translate = ( target.lower - ( ( target.difference * source.lower ) / source.difference ) )
    //             = ( target.lower - ( ( target.difference / source.difference ) * source.lower ) )
    //             = ( target.lower - ( scale * source.lower ) )
    //
    // For example:
    //   - from [ 2, 12 ] to [ -3, -1 ]
    //   - scale  = 0.2
    //   - translate = -3.4
    //
    this.scale = ( target.difference / source.difference );
    this.translate = ( target.lower - ( this.scale * source.lower ) );
  }

  /**
   * @param {Bounds} source
   *   The range of the source value.
   *
   * @param {Bounds} target
   *   The range of the target value.
   *
   * @return {ScaleTranslate}
   *   Create and return a new ScaleTranslate for mapping values from source bounds to target bounds.
   */
  static createBy_FromTo( source, target ) {
    // (Please see ScaleTranslate.setBy_FromTo().)
    let scale = ( target.difference / source.difference );
    let translate = ( target.lower - ( scale * source.lower ) );
    let result = new ScaleTranslate( scale, translate );
    return result;
  }

//!!! (2021/12/11 Remarked) seems not so friendly.
//   /**
//    * Set this.scale and this.translate so that they could undo the specified previous scale-translate.
//    *
//    * @param {ScaleTranslate} previous
//    *   The scale-translate to be undone.
//    */
//   setBy_undo( previous ) {
//     this.scale = ( 1 / previous.scale );  // Reciprocal will undo the scale.
//     this.translate = ( - previous.translate ) * this.scale; // Negative translate, and multiply by undo-scale because translate comes after scale.
//   }

  /**
   * @return {ScaleTranslate}
   *   Create and return a new ScaleTranslate for undoing the this scale-translate.
   */
  createBy_undoThis() {
    let scale = ( 1 / this.scale );               // Reciprocal will undo the scale.
    let translate = ( - this.translate ) * scale; // Negative translate, and multiply by undo-scale because translate comes after scale.
    let result = new ScaleTranslate( scale, translate );
    return result;
  }

  /**
   * Scale and translate this object by specified scale-translate.
   *   - this.scale =     ( this.scale     * another.scale ) + another.translate
   *   - this.translate = ( this.translate * another.scale ) + another.translate
   *
   * @param {ScaleTranslate} another
   *   The another scale-translate which will be applied on this object.
   */
  scaleTranslateBy( another ) {
   this.scale =     ( this.scale     * another.scale ) + another.translate;
   this.translate = ( this.translate * another.scale ) + another.translate;
  }

}

<commit_msg>Update FloatValue.js<commit_after>export { Bounds, ScaleTranslate };

/**
 * Describe the [ lower, upper ] bounds of a floating-point value
 *
 * @member {number} lower
 *   The lower bound of the range.
 *
 * @member {number} upper
 *   The upper bound of the range.
 *
 * @member {number} difference
 *   The distance between lower and upper.
 */
class Bounds {

  constructor( lower, upper ) {
    this.lower = Math.min( lower, upper ); // Confirm ( lower <= upper ).
    this.upper = Math.max( lower, upper );
  }

  get difference() {
    let difference = this.upper - this.lower;
    return difference;
  }

  /**
   * @return {Bounds}
   *   Return newly created object which is a copy of this Bounds.
   */
  clone() {
    return new Bounds( this.lower, this.upper );
  }

  /**
   * @param {Bounds} aBounds
   *   Set this Bounds by aBounds.
   *
   * @return {Bounds}
   *   Return this (modified) object which copies aBounds.
   */
  set_Bounds( aBounds ) {
    this.lower = aBounds.lower;
    this.upper = aBounds.upper;
    return this;
  }

  /**
   * @param {number} aLower
   *   Set this Bounds.lower by aLower.
   *
   * @param {number} aUpper
   *   Set this Bounds.upper by aUpper.
   *
   * @return {Bounds}
   *   Return this (modified) object which is [ aLower, aUpper ].
   */
  set_LowerUpper( aLower, aUpper ) {
    this.lower = aLower;
    this.upper = aUpper;
    return this;
  }

  /**
   * @param {Bounds} aBounds
   *   Add this Bounds by aBounds.
   *
   * @return {Bounds}
   *   Return this (modified) object which is added by aBounds.
   */
  add_Bounds( aBounds ) {
    this.lower += aBounds.lower;
    this.upper += aBounds.upper;
    return this;
  }

  /**
   * @param {number} aLower
   *   Add this Bounds.lower by aLower.
   *
   * @param {number} aUpper
   *   Add this Bounds.upper by aUpper.
   *
   * @return {Bounds}
   *   Return this (modified) object which is added by Bounds [ aLower, aUpper ].
   */
  add_LowerUpper( aLower, aUpper ) {
    this.lower += aLower;
    this.upper += aUpper;
    return this;
  }

  /**
   * @param {Bounds} aBounds
   *   Multiply this Bounds by aBounds.
   *
   * @return {Bounds}
   *   Return this (modified) object which is multiplied by aBounds.
   */
  multiply_Bounds( aBounds ) {
    this.lower *= aBounds.lower;
    this.upper *= aBounds.upper;
    return this;
  }

  /**
   * @param {number} aLower
   *   Multiply this Bounds.lower by aLower.
   *
   * @param {number} aUpper
   *   Multiply this Bounds.upper by aUpper.
   *
   * @return {Bounds}
   *   Return this (modified) object which is multiplied by Bounds [ aLower, aUpper ].
   */
  multiply_LowerUpper( aLower, aUpper ) {
    this.lower *= aLower;
    this.upper *= aUpper;
    return this;
  }

  /**
   * @param {number} N
   *   The multiplier of this.lower and this.upper.
   *
   * @return {Bounds}
   *   Return this (modified) object which is the same as this.multiply_LowerUpper( N, N ) or repeating N times this.add_Bounds( this ).
   */
  multiply_N( N ) {
    this.lower *= N;
    this.upper *= N;
    return this;
  }

  /**
   * @param {Bounds} aBounds
   *   The first multiplier (a Bounds).
   *
   * @param {number} N
   *   The second multiplier (a number).
   *
   * @return {Bounds}
   *   Return this (modified) object which is the sumed Bounds of repeating N times of multiplying this by aBounds.
   */
  multiply_Bounds_multiply_N( aBounds, N ) {
    this.lower = ( this.lower * aBounds.lower ) * N;
    this.upper = ( this.upper * aBounds.upper ) * N;
    return this;

    // The same as:
    //return this.multiply_Bounds( aBounds ).multiply_N( N );
  }

  /**
   * Confirm:
   *   - Every element is not NaN. (If it is, become 0.)
   *   - Every element is between [ lower, upper ].
   *
   * @param {Float32Array} source
   *   The source Float32Array.
   *
   * @return {Float32Array}
   *   Return a copy of source. Every element (float32):
   *     - If ( Number.isNaN( element ) == true ), let it become 0.
   *     - Otherwise, Math.max( lower, Math.min( element, upper ) ).
   */
  Float32Array_RestrictedClone( sourceArray ) {
    let resultArray = new Float32Array( sourceArray.length );
    for ( let i = 0; i < sourceArray.length; ++i ) {
      let element = sourceArray[ i ];
      if ( !Number.isNaN( element ) ) {
        resultArray[ i ] = Math.max( this.lower, Math.min( element, this.upper ) );
      } // If NaN, let it become 0. (Just do nothing, because Float32Array is initialized to zero by default.)
    }
    return resultArray;
  }

}

/**
 * Describe a scale (i.e. multiplier) value, and then a translate (i.e. offset; bias) value after the scale. Note that the order
 * is important: scale first, translate second.
 *
 * @member {number} scale
 *   The scale (i.e. multiplier) value.
 *
 * @member {number} translate
 *   The translate (i.e. offset) value.
 */
class ScaleTranslate {

  constructor( scale = 1, translate = 0 ) {
    this.scale = scale;
    this.translate = translate;
  }

  /** (Re)set all scale-translate values. Default is ( scale = 1, translate = 0 ) (i.e. no scale and no translate). */
  set_scale_translate( scale = 1, translate = 0 ) {
    this.scale = scale;
    this.translate = translate;
  }

  /**
   * Set this.scale and this.translate for mapping values from source bounds to target bounds.
   *
   * @param {Bounds} source
   *   The range of the source value.
   *
   * @param {Bounds} target
   *   The range of the target value.
   */
  setBy_FromTo( source, target ) {
    // Suppose x is a value inside the source range. y is the corresponding value inside the target range.
    //
    //   y = target.lower + ( target.difference * ( x - source.lower ) / source.difference )
    //     = target.lower + ( ( ( target.difference * x ) - ( target.difference * source.lower ) ) / source.difference )
    //     = target.lower + ( ( ( target.difference * x ) / source.difference ) - ( ( target.difference * source.lower ) / source.difference ) )
    //     = target.lower + ( ( ( target.difference / source.difference ) * x ) - ( ( target.difference * source.lower ) / source.difference ) )
    //     = target.lower + ( ( target.difference / source.difference ) * x ) - ( ( target.difference * source.lower ) / source.difference )
    //     = ( ( target.difference / source.difference ) * x ) + ( target.lower - ( ( target.difference * source.lower ) / source.difference ) )
    //     = ( scale * x ) + translate
    //
    // Got:
    //   scale = ( target.difference / source.difference )
    //   translate = ( target.lower - ( ( target.difference * source.lower ) / source.difference ) )
    //             = ( target.lower - ( ( target.difference / source.difference ) * source.lower ) )
    //             = ( target.lower - ( scale * source.lower ) )
    //
    // For example:
    //   - from [ 2, 12 ] to [ -3, -1 ]
    //   - scale  = 0.2
    //   - translate = -3.4
    //
    this.scale = ( target.difference / source.difference );
    this.translate = ( target.lower - ( this.scale * source.lower ) );
  }

  /**
   * @param {Bounds} source
   *   The range of the source value.
   *
   * @param {Bounds} target
   *   The range of the target value.
   *
   * @return {ScaleTranslate}
   *   Create and return a new ScaleTranslate for mapping values from source bounds to target bounds.
   */
  static createBy_FromTo( source, target ) {
    // (Please see ScaleTranslate.setBy_FromTo().)
    let scale = ( target.difference / source.difference );
    let translate = ( target.lower - ( scale * source.lower ) );
    let result = new ScaleTranslate( scale, translate );
    return result;
  }

//!!! (2021/12/11 Remarked) seems not so friendly.
//   /**
//    * Set this.scale and this.translate so that they could undo the specified previous scale-translate.
//    *
//    * @param {ScaleTranslate} previous
//    *   The scale-translate to be undone.
//    */
//   setBy_undo( previous ) {
//     this.scale = ( 1 / previous.scale );  // Reciprocal will undo the scale.
//     this.translate = ( - previous.translate ) * this.scale; // Negative translate, and multiply by undo-scale because translate comes after scale.
//   }

  /**
   * @return {ScaleTranslate}
   *   Create and return a new ScaleTranslate for undoing the this scale-translate.
   */
  createBy_undoThis() {
    let scale = ( 1 / this.scale );               // Reciprocal will undo the scale.
    let translate = ( - this.translate ) * scale; // Negative translate, and multiply by undo-scale because translate comes after scale.
    let result = new ScaleTranslate( scale, translate );
    return result;
  }

  /**
   * Scale and translate this object by specified scale-translate.
   *   - this.scale =     ( this.scale     * another.scale ) + another.translate
   *   - this.translate = ( this.translate * another.scale ) + another.translate
   *
   * @param {ScaleTranslate} another
   *   The another scale-translate which will be applied on this object.
   */
  scaleTranslateBy( another ) {
   this.scale =     ( this.scale     * another.scale ) + another.translate;
   this.translate = ( this.translate * another.scale ) + another.translate;
  }

}

<|endoftext|>


<commit_before>var path = require('path');

module.exports = function (grunt) {

    var public_dir = 'public/';
    var dist_dir = 'dist/';
    var pkg = grunt.file.readJSON('package.json');

    // Load grunt tasks automatically
    require('load-grunt-tasks')(grunt);

    // Time how long tasks take. Can help when optimizing build times
    require('time-grunt')(grunt);

    var config = require('load-grunt-config')(grunt, {
        init: true,
        configPath: path.join(process.cwd(), 'grunt', 'options'),
        data: {}
    });
    grunt.config.set('public_dir', public_dir);
    grunt.config.set('dist_dir', dist_dir);
    grunt.config.set('pkg', pkg);

    grunt.registerTask('default', ['build']);
    grunt.registerTask('build-public', [
        'clean:public',
        'copy:public',
        'concat:public',
        'replace:config',
        'sass:public'
    ]);
    var _baseUrlEnvMapping = {
        dev: "devapi.dbs.bh.org.il",
        local: "localhost:5000",
        live: "api.dbs.bh.org.il"
    };
    grunt.registerTask('build', function (env) {

        var mappedBaseUrl = _baseUrlEnvMapping[env];
        if (mappedBaseUrl) {

            grunt.config.set('config', {baseUrl: mappedBaseUrl});

        }
        else {
            grunt.config.set('config', {baseUrl: "localhost:5000"});

        }
        var buildTasks = [
            'clean:public',
            'clean:dist',
            'sass:public',
            'copy:public',
            'copy:dist',
            'concat:public',
            'replace:config',
            'ngAnnotate',
            'useminPrepare',
            'concat:generated',
            'cssmin',
            'uglify',
            'postcss',
            'rev',
            'usemin'];
        grunt.task.run(buildTasks)
    })
};

<commit_msg>also add replace to public folder build<commit_after>var path = require('path');

module.exports = function (grunt) {

    var public_dir = 'public/';
    var dist_dir = 'dist/';
    var pkg = grunt.file.readJSON('package.json');

    // Load grunt tasks automatically
    require('load-grunt-tasks')(grunt);

    // Time how long tasks take. Can help when optimizing build times
    require('time-grunt')(grunt);

    var config = require('load-grunt-config')(grunt, {
        init: true,
        configPath: path.join(process.cwd(), 'grunt', 'options'),
        data: {}
    });
    grunt.config.set('public_dir', public_dir);
    grunt.config.set('dist_dir', dist_dir);
    grunt.config.set('pkg', pkg);

    var _baseUrlEnvMapping = {
        dev: "devapi.dbs.bh.org.il",
        local: "localhost:5000",
        live: "api.dbs.bh.org.il"
    };

    grunt.registerTask('default', ['build']);
    grunt.registerTask('build-public', function (env) {
        var mappedBaseUrl = _baseUrlEnvMapping[env];
        if (mappedBaseUrl) {

            grunt.config.set('config', {baseUrl: mappedBaseUrl});

        }
        else {
            grunt.config.set('config', {baseUrl: "localhost:5000"});

        }
        var buildTasks = [
            'clean:public',
            'copy:public',
            'concat:public',
            'replace:config',
            'sass:public'
        ];
        grunt.task.run(buildTasks)
    });

    grunt.registerTask('build', function (env) {

        var mappedBaseUrl = _baseUrlEnvMapping[env];
        if (mappedBaseUrl) {

            grunt.config.set('config', {baseUrl: mappedBaseUrl});

        }
        else {
            grunt.config.set('config', {baseUrl: "localhost:5000"});

        }
        var buildTasks = [
            'clean:public',
            'clean:dist',
            'sass:public',
            'copy:public',
            'copy:dist',
            'concat:public',
            'replace:config',
            'ngAnnotate',
            'useminPrepare',
            'concat:generated',
            'cssmin',
            'uglify',
            'postcss',
            'rev',
            'usemin'];
        grunt.task.run(buildTasks)
    })
};

<|endoftext|>


<commit_before>import getProp from 'get-prop';
import {logger} from '../aurelia-orm';
import {inject} from 'aurelia-dependency-injection';
import {bindingMode, BindingEngine} from 'aurelia-binding';
import {bindable, customElement} from 'aurelia-templating';
import {EntityManager} from '../entity-manager';
import {Entity} from '../entity';
import {OrmMetadata} from '../orm-metadata';
import extend from 'extend';

@customElement('association-select')
@inject(BindingEngine, EntityManager, Element)
export class AssociationSelect {
  @bindable criteria = null;

  @bindable repository;

  @bindable identifier;

  @bindable property = 'name';

  @bindable resource;

  @bindable options;

  @bindable association;

  @bindable manyAssociation;

  @bindable({defaultBindingMode: bindingMode.twoWay}) value;

  multiple = false;

  ownMeta;

  /**
   * Create a new select element.
   *
   * @param {BindingEngine} bindingEngine
   * @param {EntityManager} entityManager
   * @param {Element}       element
   */
  constructor(bindingEngine, entityManager, element) {
    this._subscriptions = [];
    this.bindingEngine  = bindingEngine;
    this.entityManager  = entityManager;
    this.multiple       = typeof element.getAttribute('multiple') === 'string';
    this.element        = element;
  }

  /**
   * (Re)Load the data for the select.
   *
   * @param {string|Array} [reservedValue]
   *
   * @return {Promise}
   */
  load(reservedValue) {
    return this.buildFind()
      .then(options => {
        let result   = options;
        this.options = Array.isArray(result) ? result : [result];

        this.setValue(reservedValue);
      });
  }

  /**
   * Set the value for the select.
   *
   * @param {string|Array} value
   */
  setValue(value) {
    if (!value) {
      return;
    }

    if (!Array.isArray(value)) {
      this.value = (typeof value === 'object') ? getProp(value, this.identifier || 'id') : value;

      return;
    }

    let selectedValues = [];

    value.forEach(selected => {
      selectedValues.push(selected instanceof Entity ? selected.id : selected);
    });

    this.value = selectedValues;
  }

  /**
   * Get criteria, or default to empty object.
   *
   * @return {{}}
   */
  getCriteria() {
    if (typeof this.criteria !== 'object') {
      return {};
    }

    return extend(true, {}, this.criteria);
  }

  /**
   * Build the find that's going to fetch the option values for the select.
   * This method works well with associations, and reloads when they change.
   *
   * @return {Promise}
   */
  buildFind() {
    let repository    = this.repository;
    let criteria      = this.getCriteria();
    let findPath      = repository.getResource();
    criteria.populate = false;

    // Check if there are `many` associations. If so, the repository find path changes.
    // the path will become `/:association/:id/:entity`.
    if (this.manyAssociation) {
      let assoc = this.manyAssociation;

      // When disabling populate here, the API won't return any data.
      delete criteria.populate;

      let property = this.propertyForResource(assoc.getMeta(), repository.getResource());
      findPath     = `${assoc.getResource()}/${assoc.id}/${property}`;
    } else if (this.association) {
      let associations = Array.isArray(this.association) ? this.association : [this.association];

      associations.forEach(association => {
        criteria[this.propertyForResource(this.ownMeta, association.getResource())] = association.id;
      });
    }

    return repository.findPath(findPath, criteria);
  }

  /**
   * Check if all associations have values set.
   *
   * @return {boolean}
   */
  verifyAssociationValues() {
    if (this.manyAssociation) {
      return !!this.manyAssociation.id;
    }

    if (this.association) {
      let associations = Array.isArray(this.association) ? this.association : [this.association];

      return !associations.some(association => {
        return !association.id;
      });
    }

    return true;
  }

  /**
   * Add a watcher to the list. Whenever given association changes, the select will reload its contents.
   *
   * @param {Entity|Array} association Entity or array of Entity instances.
   *
   * @return {AssociationSelect}
   */
  observe(association) {
    if (Array.isArray(association)) {
      association.forEach(assoc => this.observe(assoc));

      return this;
    }

    this._subscriptions.push(this.bindingEngine.propertyObserver(association, 'id').subscribe(() => {
      if (this.verifyAssociationValues()) {
        return this.load();
      }

      this.options = undefined;

      return Promise.resolve();
    }));

    return this;
  }

  resourceChanged(resource) {
    if (!resource) {
      logger.error(`resource is ${typeof resource}. It should be a string or a reference`);
    }

    this.repository = this.entityManager.getRepository(resource);
  }

  /**
   * When attached to the DOM, initialize the component.
   */
  attached() {
    if (!this.association && !this.manyAssociation) {
      this.load(this.value);

      return;
    }

    this.ownMeta = OrmMetadata.forTarget(this.entityManager.resolveEntityReference(this.repository.getResource()));

    if (this.manyAssociation) {
      this.observe(this.manyAssociation);
    }

    if (this.association) {
      this.observe(this.association);
    }

    if (this.value) {
      this.load(this.value);
    }
  }

  /**
   * Find the name of the property in meta, reversed by resource.
   *
   * @param {Metadata} meta
   * @param {string}   resource
   *
   * @return {string}
   */
  propertyForResource(meta, resource) {
    let associations = meta.fetch('associations');

    return Object.keys(associations).filter(key => {
      return associations[key].entity === resource;
    })[0];
  }

  /**
   * Dispose all subscriptions on unbind.
   */
  unbind() {
    this._subscriptions.forEach(subscription => subscription.dispose());
  }
}
<commit_msg>fix(component): bindable multiple for association select component<commit_after>import getProp from 'get-prop';
import {logger} from '../aurelia-orm';
import {inject} from 'aurelia-dependency-injection';
import {bindingMode, BindingEngine} from 'aurelia-binding';
import {bindable, customElement} from 'aurelia-templating';
import {EntityManager} from '../entity-manager';
import {Entity} from '../entity';
import {OrmMetadata} from '../orm-metadata';
import extend from 'extend';

@customElement('association-select')
@inject(BindingEngine, EntityManager, Element)
export class AssociationSelect {
  @bindable criteria = null;

  @bindable repository;

  @bindable identifier;

  @bindable property = 'name';

  @bindable resource;

  @bindable options;

  @bindable association;

  @bindable manyAssociation;

  @bindable({defaultBindingMode: bindingMode.twoWay}) value;

  @bindable multiple = false;

  ownMeta;

  /**
   * Create a new select element.
   *
   * @param {BindingEngine} bindingEngine
   * @param {EntityManager} entityManager
   * @param {Element}       element
   */
  constructor(bindingEngine, entityManager, element) {
    this._subscriptions = [];
    this.bindingEngine  = bindingEngine;
    this.entityManager  = entityManager;
    this.element        = element;
  }

  /**
   * (Re)Load the data for the select.
   *
   * @param {string|Array} [reservedValue]
   *
   * @return {Promise}
   */
  load(reservedValue) {
    return this.buildFind()
      .then(options => {
        let result   = options;
        this.options = Array.isArray(result) ? result : [result];

        this.setValue(reservedValue);
      });
  }

  /**
   * Set the value for the select.
   *
   * @param {string|Array} value
   */
  setValue(value) {
    if (!value) {
      return;
    }

    if (!Array.isArray(value)) {
      this.value = (typeof value === 'object') ? getProp(value, this.identifier || 'id') : value;

      return;
    }

    let selectedValues = [];

    value.forEach(selected => {
      selectedValues.push(selected instanceof Entity ? selected.id : selected);
    });

    this.value = selectedValues;
  }

  /**
   * Get criteria, or default to empty object.
   *
   * @return {{}}
   */
  getCriteria() {
    if (typeof this.criteria !== 'object') {
      return {};
    }

    return extend(true, {}, this.criteria);
  }

  /**
   * Build the find that's going to fetch the option values for the select.
   * This method works well with associations, and reloads when they change.
   *
   * @return {Promise}
   */
  buildFind() {
    let repository    = this.repository;
    let criteria      = this.getCriteria();
    let findPath      = repository.getResource();
    criteria.populate = false;

    // Check if there are `many` associations. If so, the repository find path changes.
    // the path will become `/:association/:id/:entity`.
    if (this.manyAssociation) {
      let assoc = this.manyAssociation;

      // When disabling populate here, the API won't return any data.
      delete criteria.populate;

      let property = this.propertyForResource(assoc.getMeta(), repository.getResource());
      findPath     = `${assoc.getResource()}/${assoc.id}/${property}`;
    } else if (this.association) {
      let associations = Array.isArray(this.association) ? this.association : [this.association];

      associations.forEach(association => {
        criteria[this.propertyForResource(this.ownMeta, association.getResource())] = association.id;
      });
    }

    return repository.findPath(findPath, criteria);
  }

  /**
   * Check if all associations have values set.
   *
   * @return {boolean}
   */
  verifyAssociationValues() {
    if (this.manyAssociation) {
      return !!this.manyAssociation.id;
    }

    if (this.association) {
      let associations = Array.isArray(this.association) ? this.association : [this.association];

      return !associations.some(association => {
        return !association.id;
      });
    }

    return true;
  }

  /**
   * Add a watcher to the list. Whenever given association changes, the select will reload its contents.
   *
   * @param {Entity|Array} association Entity or array of Entity instances.
   *
   * @return {AssociationSelect}
   */
  observe(association) {
    if (Array.isArray(association)) {
      association.forEach(assoc => this.observe(assoc));

      return this;
    }

    this._subscriptions.push(this.bindingEngine.propertyObserver(association, 'id').subscribe(() => {
      if (this.verifyAssociationValues()) {
        return this.load();
      }

      this.options = undefined;

      return Promise.resolve();
    }));

    return this;
  }

  resourceChanged(resource) {
    if (!resource) {
      logger.error(`resource is ${typeof resource}. It should be a string or a reference`);
    }

    this.repository = this.entityManager.getRepository(resource);
  }

  /**
   * When attached to the DOM, initialize the component.
   */
  attached() {
    if (!this.association && !this.manyAssociation) {
      this.load(this.value);

      return;
    }

    this.ownMeta = OrmMetadata.forTarget(this.entityManager.resolveEntityReference(this.repository.getResource()));

    if (this.manyAssociation) {
      this.observe(this.manyAssociation);
    }

    if (this.association) {
      this.observe(this.association);
    }

    if (this.value) {
      this.load(this.value);
    }
  }

  /**
   * Find the name of the property in meta, reversed by resource.
   *
   * @param {Metadata} meta
   * @param {string}   resource
   *
   * @return {string}
   */
  propertyForResource(meta, resource) {
    let associations = meta.fetch('associations');

    return Object.keys(associations).filter(key => {
      return associations[key].entity === resource;
    })[0];
  }

  /**
   * Dispose all subscriptions on unbind.
   */
  unbind() {
    this._subscriptions.forEach(subscription => subscription.dispose());
  }
}
<|endoftext|>