var UDF = require( '..' )
var BlockDevice = require( 'blockdevice' )
var util = require( 'util' )
var fs = require( 'fs' )
var path = require( 'path' )

function inspect( value ) {
  return util.inspect( value, {
    depth: null,
    colors: process.stdout.isTTY,
  })
}

var EOL = '\n'

console.log( EOL + 'UDF', inspect( UDF ) )

var imagePath = path.join( process.env.HOME, 'Downloads', 'image.iso' )
var stats = fs.statSync( imagePath )

console.log( EOL + 'stats', inspect( stats ) )

var device = new BlockDevice({
  blockSize: 512,
  path: imagePath,
  size: stats.size,
  mode: 'r',
})

var volume = new UDF.Volume( device )

device.open( function( error ) {

  if( error ) throw error

  volume.open( function( error, desc ) {
    console.log( '' )
    // console.log( buffer )
    console.log( desc )
    console.log( '' )
    console.log( error || inspect( volume ) )
  })

})

var UDF = require( '..' )
var BlockDevice = require( 'blockdevice' )
var util = require( 'util' )
var fs = require( 'fs' )
var path = require( 'path' )
var argv = process.argv.slice(2)

function inspect( value ) {
  return util.inspect( value, {
    depth: null,
    colors: process.stdout.isTTY,
  })
}

var EOL = '\n'

console.log( EOL + 'UDF', inspect( UDF ) )

var imagePath = path.resolve( argv.shift() )
var stats = fs.statSync( imagePath )

console.log( EOL + 'stats', inspect( stats ) )

var device = new BlockDevice({
  blockSize: 512,
  path: imagePath,
  size: stats.size,
  mode: 'r',
})

var volume = new UDF.Volume( device )

device.open( function( error ) {

  if( error ) throw error

  volume.open( function( error, desc ) {
    console.log( '' )
    // console.log( buffer )
    console.log( desc )
    console.log( '' )
    console.log( error || inspect( volume ) )
  })

})

Use process argv as inspection source


module.exports = function (req, res) {
	var keystone = req.keystone;
	if (!keystone.security.csrf.validate(req)) {
		return res.apiError(403, 'invalid csrf');
	}
	req.list.model.findById(req.params.id, function (err, item) {
		if (err) return res.status(500).json({ err: 'database error', detail: err });
		if (!item) return res.status(404).json({ err: 'not found', id: req.params.id });
		req.list.validateInput(item, req.body, function (err) {
			if (err) return res.status(400).json(err);
			req.list.updateItem(item, req.body, { files: req.files }, function (err) {
				if (err) return res.status(500).json(err);
				res.json(req.list.getData(item));
			});
		});
	});
};

module.exports = function (req, res) {
	var keystone = req.keystone;
	if (!keystone.security.csrf.validate(req)) {
		return res.apiError(403, 'invalid csrf');
	}
	req.list.model.findById(req.params.id, function (err, item) {
		if (err) return res.status(500).json({ err: 'database error', detail: err });
		if (!item) return res.status(404).json({ err: 'not found', id: req.params.id });
		req.list.validateInput(item, req.body, function (err) {
			if (err) return res.status(400).json(err);
			req.list.updateItem(item, req.body, { files: req.files }, function (err) {
				if (err) return res.apiError(500, err.detail);
				res.json(req.list.getData(item));
			});
		});
	});
};

Fix database errors not displaying


'use strict';

var React = require('react'),
    App = require('./App');

React.render(<App />, document.body);

'use strict';

var React = require('react'),
    App = require('./app');

React.render(<App />, document.body);

Fix bug filename : App -> app


exports = module.exports = function(parse, csrfProtection, loadState, authenticate, proceed) {

  /*
  return [
    require('body-parser').urlencoded({ extended: false }),
    ceremony.loadState('mfa'),
    authenticator.authenticate('session'),
    authenticator.authenticate('mfa-otp'),
    ceremony.complete('mfa'),
    ceremony.completeError('mfa')
  ];
  */

  return [
    parse('application/x-www-form-urlencoded'),
    function(req, res, next) {
      console.log('OTP AUTHENTICATING...');
      console.log(req.body)
      next();
    },
    csrfProtection(),
    //loadState('login'),
    authenticate('www-otp'),
    function(req, res, next) {
      console.log('OTP AUTHENTICATED!');
      next();
    },
    proceed
  ];
};

exports['@require'] = [
  'http://i.bixbyjs.org/http/middleware/parse',
  'http://i.bixbyjs.org/http/middleware/csrfProtection',
  'http://i.bixbyjs.org/http/middleware/loadState',
  'http://i.bixbyjs.org/http/middleware/authenticate',
  '../../workflow/login/resume'
];

exports = module.exports = function(parse, flow, csrfProtection, authenticate) {

  /*
  return [
    require('body-parser').urlencoded({ extended: false }),
    ceremony.loadState('mfa'),
    authenticator.authenticate('session'),
    authenticator.authenticate('mfa-otp'),
    ceremony.complete('mfa'),
    ceremony.completeError('mfa')
  ];
  */

  return [
    parse('application/x-www-form-urlencoded'),
    flow('authenticate-otp',
      function(req, res, next) {
        console.log('OTP AUTHENTICATING...');
        console.log(req.body)
        next();
      },
      csrfProtection(),
      //loadState('login'),
      authenticate('www-otp'),
      function(req, res, next) {
        console.log('OTP AUTHENTICATED!');
        next();
      },
    { through: 'login' })
  ];
};

exports['@require'] = [
  'http://i.bixbyjs.org/http/middleware/parse',
  'http://i.bixbyjs.org/http/middleware/state/flow',
  'http://i.bixbyjs.org/http/middleware/csrfProtection',
  'http://i.bixbyjs.org/http/middleware/authenticate'
];

Switch to DSL for OTP authentication.


module.exports = [
  {
    name: '@storybook/addon-docs/react/preset',
    options: {
      configureJSX: true,
    },
  },
];

module.exports = [
  '@storybook/preset-create-react-app',
  {
    name: '@storybook/addon-docs/react/preset',
    options: {
      configureJSX: true,
    },
  },
];

Add CRA preset to MDX template


/*
 * MapEmAll is licensed under the conditions of the MIT License (MIT)
 *
 * Copyright (c) 2015-2016 Philip Stöhrer
 * All rights reserved.
 *
 * See https://raw.githubusercontent.com/stophi-dev/MapEmAll/master/LICENSE for details.
 */

define(['JSLoader', 'bing/BingMap'], function (loader, BingMap) {
    'use strict';

    function preventMapToBeGloballyAbsolute(htmlElement) {
        var style = window.getComputedStyle(htmlElement, null);
        if (style.position === 'static') {
            htmlElement.style.position = 'relative';
        }
    }

    return {
        loadMap: function (options, callback) {
            var callbackName = 'initBingMap_' + loader.makeId(10);

            // Bing maps positions the map absolute.
            // To prevent overlaps and to get a similar behavior like
            // other providers, we adjust the position of htmlContainer:
            preventMapToBeGloballyAbsolute(options.htmlContainer);

            window[callbackName] = function () {
                delete window[callbackName];
                callback(new BingMap(options));
            };
            loader.loadjsfile('http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&onscriptload=' + callbackName);
        }
    };
});

/*
 * MapEmAll is licensed under the conditions of the MIT License (MIT)
 *
 * Copyright (c) 2015-2016 Philip Stöhrer
 * All rights reserved.
 *
 * See https://raw.githubusercontent.com/stophi-dev/MapEmAll/master/LICENSE for details.
 */

define(['JSLoader', 'bing/BingMap'], function (loader, BingMap) {
    'use strict';

    function preventMapToBeGloballyAbsolute(htmlElement) {
        var style = window.getComputedStyle(htmlElement, null);
        if (style.position === 'static') {
            htmlElement.style.position = 'relative';
        }
    }

    return {
        loadMap: function (options, callback) {
            var callbackName = 'initBingMap_' + loader.makeId(10);

            // Bing maps positions the map absolute.
            // To prevent overlaps and to get a similar behavior like
            // other providers, we adjust the position of htmlContainer:
            preventMapToBeGloballyAbsolute(options.htmlContainer);

            window[callbackName] = function () {
                delete window[callbackName];
                callback(new BingMap(options));
            };
            loader.loadjsfile('https://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&s=1&onscriptload=' + callbackName);
        }
    };
});

Use https URL for bing


/**
 * Start browserSync server
 */
'use strict';

const gulp  = require('gulp'),
      fs    = require('fs');

module.exports = function(options) {

  return () => {
    // If index.html exist - open it, else show folder
    let listDirectory = fs.existsSync(options.mainHtml) ? false : true;

    options.browserSync.init({
      server: {
        baseDir: "./",
        directory: listDirectory
      },
      snippetOptions: {
        // Provide a custom Regex for inserting the snippet
        rule: {
          match: /$/i,
          fn: (snippet, match) => snippet + match
        }
      },
      port: 8080
    });
  };

};

/**
 * Start browserSync server
 */
'use strict';

const gulp  = require('gulp'),
      fs    = require('fs');

module.exports = function(options) {

  return () => {
    // If index.html exist - open it, else show folder
    let listDirectory = fs.existsSync(options.mainHtml) ? false : true;

    options.browserSync.init({
      notify: false,
      server: {
        baseDir: "./",
        directory: listDirectory
      },
      snippetOptions: {
        // Provide a custom Regex for inserting the snippet
        rule: {
          match: /$/i,
          fn: (snippet, match) => snippet + match
        }
      },
      port: 8080
    });
  };

};

Switch off a browsersync label


var replace = require( "../src/str-replace" );

module.exports = {
  replace_all: function( assert ) {
    var actual = replace
      .all( "/" )
      .from( "/home/dir" )
      .to( "\\" );
    var expected = "\\home\\dir";
    assert.strictEqual( actual, expected );
    assert.done();
  },
  replace_all_ignoring_case: function( assert ) {
    var actual = replace
      .all( "G" )
        .ignoreCase()
      .from( "Eggs" )
      .to( "f" );
    var expected = "Effs";
    assert.strictEqual( actual, expected );
    assert.done();
  }
};

var replace = require( "../src/str-replace" );

module.exports = {
  replace_all: function( assert ) {
    var actual = replace
      .all( "/" )
      .from( "/home/dir" )
      .to( "\\" );
    var expected = "\\home\\dir";
    assert.strictEqual( actual, expected );
    assert.done();
  },
  replace_all_ignoring_case: function( assert ) {
    var actual = replace
      .all( "house" )
        .ignoreCase()
      .from( "Many Houses" )
      .to( "Horse" );
    var expected = "Many Horses";
    assert.strictEqual( actual, expected );
    assert.done();
  }
};

Create a better fluent example in the tests


import Rollbar from 'rollbar';

const rollbar = new Rollbar({
  accessToken: 'POST_CLIENT_ITEM_TOKEN',
  captureUncaught: false,
  captureUnhandledRejections: false
})

module.exports = function tool(x) {
  rollbar.log('foobar got data', {x})
}

// Use noconflict so we can embed rollbar.js in this library
var Rollbar = require('rollbar/dist/rollbar.noconflict.umd');

const rollbar = new Rollbar({
  accessToken: 'POST_CLIENT_ITEM_TOKEN',
  captureUncaught: true,
  captureUnhandledRejections: true
})

module.exports = function tool(x) {
  rollbar.log('foobar got data', {x})
}

Use the new noconflict build to show an example of how to embed rollbar.js into a library which will not cause any conflicts with another install of Rollbar @rokob


'use strict';

module.exports = () => ({
    'title': 'Service Resource Definition',
    'description': 'Defines the resources, units, metering, aggregation and rating formulas used to meter a particular service',
    'type': 'object',
    'required': ['id', 'resources', 'aggregations'],
    'properties': {
        'id': {
            'type': 'string'
        },
        'resources': {
            'type': 'array',
            'minItems': 1,
            'items': {
                'type': 'object',
                'required': ['units'],
                'properties': {
                    'name': {
                        'type': 'string'
                    },
                    'units' : {
                        'type': 'array',
                        'minItems': 1,
                        'items': {
                            'type': 'object',
                            'required': ['name', 'quantityType'],
                            'properties': {
                                'name': {
                                    'type': 'string'
                                },
                                'quantityType': {
                                    'enum' : [ 'DELTA', 'CURRENT']
                                }
                            },
                            'additionalProperties': false
                        },
                        'additionalItems': false
                    }
                },
                'additionalProperties': false
            },
            'additionalItems': false
        },
        'aggregations': {
            'type': 'array',
            'items': {
                'type': 'object',
                'required': ['id', 'unit', 'formula'],
                'properties': {
                    'id': {
                      'type': 'string'
                    },
                    'unit': {
                        'type': 'string'
                    },
                    'aggregationGroup': {
                        'type': 'object',
                        'required': ['name'],
                        'properties': {
                            'name': {
                                'enum': ['daily', 'monthly']
                            },
                            'additionalProperties': false
                        }
                    },
                    'formula': {
                    },
                    'accumulate': {
                    },
                    'aggregate': {
                    },
                    'rate': {
                    }
                },
                'additionalProperties': false
            },
            'additionalItems': false
        }
    },
    'additionalProperties':  false
});

'use strict';

// Service resource definition schema

const _ = require('underscore');

const schema = require('cf-abacus-schema');

const clone = _.clone;
const extend = _.extend;

const string = schema.types.string;
const enumType = schema.types.enumType;
const object = schema.types.object;
const arrayOf = schema.types.arrayOf;

// Unit schema
const unit = object({ name: string(), quantityType: enumType(['DELTA', 'CURRENT']) }, ['name', 'quantityType']);

// Resource schema
const resource = object({ name: string(), units: arrayOf(unit) }, ['units']);

// AggregationGroup schema
const aggregationGroup = object({ name: enumType(['daily', 'monthly']) }, ['name']);

// Aggregation schema
const aggregation = object({ id: string(), unit: string(), aggregationGroup: aggregationGroup, formula: {}, accumulate: {}, aggregate: {}, rate: {} }, ['id', 'unit', 'formula']);

// Export our public functions
module.exports = () => extend(clone(object({ id: string(), resources: arrayOf(resource), aggregations: arrayOf(aggregation) }), ['id', 'resources', 'aggregations']),
    { title: 'Service Resource Definition', description : 'Defines the resources, units, metering, accumulation, aggregation and rating formulas used to meter a particular service' }
);

Refactor service resource definition schema to use JSON Schema primitive data type descriptor functions


const {Action, api} = require('actionhero');
const templates = require('../lib/dal/templates');

module.exports.allTemplatesPublic = class TopViewedPublishedDatasetsAction extends Action {
    constructor() {
        super();
        this.name = 'allTemplatesPublic';
        this.description = 'Returns all public templages';
        this.do_not_authenticate = true;
    }

    async run({response}) {
        api.log("Call to get all templates",'info');
        response.data = await templates.getAllTemplates();
        api.log("Results of get all templates",'info',response.data.length);
    }
};

const {Action} = require('actionhero');
const templates = require('../lib/dal/templates');

module.exports.GetAllPublicTemplatesAction = class GetAllPublicTemplatesAction extends Action {
    constructor() {
        super();
        this.name = 'getAllPublicTemplates';
        this.description = 'Returns all public templates';
        this.do_not_authenticate = true;
    }

    async run({response}) {
        response.data = await templates.getAllTemplates();
    }
};

Change templates action to follow our naming convention


const _pick           = require('lodash').pick;

const CORDOVA_OPTS = [
  'release',
  'debug',
  'emulator',
  'device',
  'buildConfig'
];

const IOS_OPTS = [
  'codeSignIdentity',
  'provisioningProfile',
  'codesignResourceRules',
  'developmentTeam',
  'packageType'
];

const ANDROID_OPTS = [
  'keystore',
  'storePassword',
  'alias',
  'password',
  'keystoreType',
  'gradleArg',
  'cdvBuildMultipleApks',
  'cdvVersionCode',
  'cdvReleaseSigningPropertiesFile',
  'cdvDebugSigningPropertiesFile',
  'cdvMinSdkVersion',
  'cdvBuildToolsVersion',
  'cdvCompileSdkVersion'
];

module.exports = function(platform, options) {
  let platformKeys = [];

  if (platform === 'ios') {
    platformKeys = IOS_OPTS;
  } else if (platform === 'android') {
    platformKeys = ANDROID_OPTS;
  }

  let ret = _pick(options, CORDOVA_OPTS.concat(platformKeys));
  ret.argv = [].concat(...platformKeys
    .filter((key) => options.hasOwnProperty(key))
    .map((key) => [`--${key}`, options[key]]));

  return ret;
};

const _pick           = require('lodash').pick;

const CORDOVA_OPTS = [
  'release',
  'debug',
  'emulator',
  'device',
  'buildConfig'
];

const IOS_OPTS = [
  'codeSignIdentity',
  'provisioningProfile',
  'codesignResourceRules',
  'developmentTeam',
  'packageType'
];

const ANDROID_OPTS = [
  'keystore',
  'storePassword',
  'alias',
  'password',
  'keystoreType',
  'gradleArg',
  'cdvBuildMultipleApks',
  'cdvVersionCode',
  'cdvReleaseSigningPropertiesFile',
  'cdvDebugSigningPropertiesFile',
  'cdvMinSdkVersion',
  'cdvBuildToolsVersion',
  'cdvCompileSdkVersion',
  'packageType'
];

module.exports = function(platform, options) {
  let platformKeys = [];

  if (platform === 'ios') {
    platformKeys = IOS_OPTS;
  } else if (platform === 'android') {
    platformKeys = ANDROID_OPTS;
  }

  let ret = _pick(options, CORDOVA_OPTS.concat(platformKeys));
  ret.argv = [].concat(...platformKeys
    .filter((key) => options.hasOwnProperty(key))
    .map((key) => [`--${key}`, options[key]]));

  return ret;
};

Add packageType to the list of flags android builds understand and can parse


// ------------------------------ Dynamic Icons ------------------------------ //

/**
 * Take an icon name (such as "open") and return the HTML code to display the icon
 * @param {string} iconName - the name of the icon
 * @param {string} [iconClass] - an optional class to assign to the icon
 */
Telescope.utils.getIcon = function (iconName, iconClass) {
  var icons = Telescope.utils.icons;
  var iconCode = !!icons[iconName] ? icons[iconName] : iconName;
  var iconClass = (typeof iconClass === 'string') ? ' '+iconClass : '';
  return '<i class="icon fa fa-' + iconCode + ' icon-' + iconName + iconClass+ '" aria-hidden="true"></i>';
};

/**
 * A directory of icon keys and icon codes
 */
Telescope.utils.icons = {
  open: "plus",
  close: "minus",
  upvote: "chevron-up",
  voted: "check",
  downvote: "chevron-down",
  facebook: "facebook-square",
  twitter: "twitter",
  googleplus: "google-plus",
  linkedin: "linkedin-square",
  comment: "comment-o",
  share: "share-square-o",
  more: "ellipsis-h",
  menu: "bars",
  subscribe: "envelope-o",
  delete: "trash-o",
  edit: "pencil",
  popularity: "fire",
  time: "clock-o",
  best: "star",
  search: "search"
};

// ------------------------------ Dynamic Icons ------------------------------ //

/**
 * Take an icon name (such as "open") and return the HTML code to display the icon
 * @param {string} iconName - the name of the icon
 * @param {string} [iconClass] - an optional class to assign to the icon
 */
Telescope.utils.getIcon = function (iconName, iconClass) {
  var icons = Telescope.utils.icons;
  var iconCode = !!icons[iconName] ? icons[iconName] : iconName;
  var iconClass = (typeof iconClass === 'string') ? ' '+iconClass : '';
  return '<i class="icon fa fa-' + iconCode + ' icon-' + iconName + iconClass+ '" aria-hidden="true"></i>';
};

/**
 * A directory of icon keys and icon codes
 */
Telescope.utils.icons = {
  open: "plus",
  close: "minus",
  upvote: "thumbs-o-up",
  voted: "check",
  downvote: "thumbs-o-down",
  facebook: "facebook-square",
  twitter: "twitter",
  googleplus: "google-plus",
  linkedin: "linkedin-square",
  comment: "comment-o",
  share: "share-square-o",
  more: "ellipsis-h",
  menu: "bars",
  subscribe: "envelope-o",
  delete: "trash-o",
  edit: "pencil",
  popularity: "fire",
  time: "clock-o",
  best: "star",
  search: "search"
};

Change the vote up/down buttons into thumbs up/down.


import {createStore, applyMiddleware, compose} from 'redux'
import {combineReducers} from 'redux'
import {routerReducer, routerMiddleware} from 'react-router-redux'
import thunkMiddleware from 'redux-thunk'
import makeQueryExecuter from 'src/shared/middleware/queryExecuter'
import resizeLayout from 'src/shared/middleware/resizeLayout'
import adminReducer from 'src/admin/reducers/admin'
import sharedReducers from 'src/shared/reducers'
import dataExplorerReducers from 'src/data_explorer/reducers'
import rulesReducer from 'src/kapacitor/reducers/rules'
import dashboardUI from 'src/dashboards/reducers/ui'
import persistStateEnhancer from './persistStateEnhancer'

const rootReducer = combineReducers({
  routing: routerReducer,
  ...sharedReducers,
  ...dataExplorerReducers,
  admin: adminReducer,
  rules: rulesReducer,
  dashboardUI,
})

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

export default function configureStore(initialState, browserHistory) {
  const routingMiddleware = routerMiddleware(browserHistory)
  const createPersistentStore = composeEnhancers(
    persistStateEnhancer(),
    applyMiddleware(thunkMiddleware, routingMiddleware, makeQueryExecuter(), resizeLayout),
  )(createStore)

  // https://github.com/elgerlambert/redux-localstorage/issues/42
  // createPersistantStore should ONLY take reducer and initialState
  // any store enhancers must be added to the compose() function.
  return createPersistentStore(
    rootReducer,
    initialState,
  )
}

import {createStore, applyMiddleware, compose} from 'redux'
import {combineReducers} from 'redux'
import {routerReducer, routerMiddleware} from 'react-router-redux'
import thunkMiddleware from 'redux-thunk'
import makeQueryExecuter from 'src/shared/middleware/queryExecuter'
import resizeLayout from 'src/shared/middleware/resizeLayout'
import adminReducer from 'src/admin/reducers/admin'
import sharedReducers from 'src/shared/reducers'
import dataExplorerReducers from 'src/data_explorer/reducers'
import rulesReducer from 'src/kapacitor/reducers/rules'
import dashboardUI from 'src/dashboards/reducers/ui'
import persistStateEnhancer from './persistStateEnhancer'

const rootReducer = combineReducers({
  ...sharedReducers,
  ...dataExplorerReducers,
  admin: adminReducer,
  rules: rulesReducer,
  dashboardUI,
  routing: routerReducer,
})

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

export default function configureStore(initialState, browserHistory) {
  const routingMiddleware = routerMiddleware(browserHistory)
  const createPersistentStore = composeEnhancers(
    persistStateEnhancer(),
    applyMiddleware(thunkMiddleware, routingMiddleware, makeQueryExecuter(), resizeLayout),
  )(createStore)

  // https://github.com/elgerlambert/redux-localstorage/issues/42
  // createPersistantStore should ONLY take reducer and initialState
  // any store enhancers must be added to the compose() function.
  return createPersistentStore(
    rootReducer,
    initialState,
  )
}

Move routing reducer last in redux store


define(function (require, exports, module) {
    "use strict";

    var ExtensionUtils = brackets.getModule("utils/ExtensionUtils");

    ExtensionUtils.addEmbeddedStyleSheet("* { font-size: 22px !important; line-height: 25px !important; }");
});

define(function (require, exports, module) {
    "use strict";

    var ExtensionUtils = brackets.getModule("utils/ExtensionUtils");

    ExtensionUtils.addEmbeddedStyleSheet("#sidebar *, #main-toolbar *, #titlebar *, #problems-panel *,"+
	"#find-in-files-results *, #e4b-main-panel *, #status-bar *,"+
	"#main-toolbar *, #context-menu-bar *, #codehint-menu-bar *,"+
	"#quick-view-container *, #function-hint-container *  { font-size: 22px !important;"+
	" line-height: 25px !important; }"+
	".sidebar li { min-height: 25px !important;}"+
	".sidebar-selection, .filetree-selection { min-height: 30px !important; margin-top: 3px;}"+
	""
	);
});

Fix font size, line height and selection background


Fix file error call parameters


const LOAD = 'hackclub/clubs/LOAD'
const LOAD_SUCCESS = 'hackclub/clubs/LOAD_SUCCESS'
const LOAD_FAIL = 'hackclub/clubs/LOAD_FAIL'

const initialState = {
  loaded: false
}

export default function reducer(state=initialState, action={}) {
  switch (action.type) {
  case LOAD:
    return {
      ...state,
      loading: true
    }
  case LOAD_SUCCESS:
    return {
      ...state,
      loading: false,
      loaded: true,
      data: action.result,
      error: null
    }
  case LOAD_FAIL:
    return {
      ...state,
      loading: false,
      loaded: false,
      data: null,
      error: action.error
    }
  default:
    return state
  }
}

export function isLoaded(globalState) {
  return globalState.clubs && globalState.clubs.loaded
}

export function load() {
  return {
    types: [LOAD, LOAD_SUCCESS, LOAD_FAIL],
    promise: client => client.get('/v1/clubs/to_be_onboarded')
  }
}

const LOAD = 'hackclub/clubs/LOAD'
const LOAD_SUCCESS = 'hackclub/clubs/LOAD_SUCCESS'
const LOAD_FAIL = 'hackclub/clubs/LOAD_FAIL'

const initialState = {
  loaded: false
}

export default function reducer(state=initialState, action={}) {
  switch (action.type) {
  case LOAD:
    return {
      ...state,
      loading: true
    }
  case LOAD_SUCCESS:
    return {
      ...state,
      loading: false,
      loaded: true,
      data: action.result,
      error: null
    }
  case LOAD_FAIL:
    return {
      ...state,
      loading: false,
      loaded: false,
      data: null,
      error: action.error
    }
  default:
    return state
  }
}

export function isLoaded(globalState) {
  return globalState.clubs && globalState.clubs.loaded
}

export function load() {
  return {
    types: [LOAD, LOAD_SUCCESS, LOAD_FAIL],
    promise: client => client.get('/v1/clubs/intake')
  }
}

Update club endpoint for intake form


import path from 'path'

export default {
  src: [
    '{bin,rhizome,datapoints,templates,env_var}/**/*.*',
    'webapp*/public*/**/*.*',
    'docs*/_build/**/*.*',
    'manage.py',
    'requirements.txt',
    'settings.py',
    'initial_data.xlsx'
  ].map(file => {
    return path.join(process.cwd(), '..') + '/' + file
  }),
  dest: path.join(process.cwd(), '../dist'),
  options: {
    filename: 'rhizome.zip'
  }
}

import path from 'path'

export default {
  src: [
    '{bin,rhizome,datapoints,templates,env_var}/**/*.*',
    'webapp*/public*/**/*.*',
    'docs*/_build/**/*.*',
    'manage.py',
    'appspec.yml',
    'requirements.txt',
    'settings.py',
    'initial_data.xlsx'
  ].map(file => {
    return path.join(process.cwd(), '..') + '/' + file
  }),
  dest: path.join(process.cwd(), '../dist'),
  options: {
    filename: 'rhizome.zip'
  }
}

Make sure appspec.yml is bundled


links = document.links;
for(var i = 0; i < links.length; ++i) {
  href = links[i].href;
  if(href) {
    if(href.match(/http:\/\/vkontakte\.ru\/away\.php\?to=/)) {
      links[i].href = unescape(href.substr(32));
    }
    if(href.match(/http:\/\/vk\.com\/away\.php\?to=/)) {
      links[i].href = unescape(href.substr(26));
    }
  }
}

function replace_away_link_at(obj) {
  if(!obj.href) return;

  if( obj.href.match(/^http:\/\/vkontakte\.ru\/away\.php/) ) {
    obj.href = unescape(obj.href.substr(32));
  }
  if( obj.href.match(/^http:\/\/vk\.com\/away\.php/) ) {
    obj.href = unescape(obj.href.substr(26));
  }
}

replace_away_link_at(document.location);

links = document.links;
for(var i = 0; i < links.length; ++i) {
  replace_away_link_at(links[i]);
}

Return support of old algorithm (changing document.location)


function lg(s) { console.log(s); }

var
	elBody = document.body,
	elVideo = document.querySelector( "video" )
;

elBody.ondragover = function() {
	lg("body:ondragover");
	return false;
};

elBody.ondrop = function( e ) {
	lg("body:ondrop");
	elVideo.src = URL.createObjectURL( e.dataTransfer.files[ 0 ] );
	elVideo.play();
	return false;
};

function lg(s) { console.log(s); }

var
	elBody = document.body,
	elVideo = document.querySelector( "video" )
;

elBody.ondragover = function() {
	lg( "body:ondragover" );
	return false;
};

elBody.ondrop = function( e ) {
	lg( "body:ondrop" );

	var
		// Save file's informations
		dropFile = e.dataTransfer.files[ 0 ],
		// Create a temporary fake absolute path to the dropped file
		dropFileUrl = URL.createObjectURL( dropFile )
	;

	// Check type file, eg : "video/mp4" -> "video"
	switch ( dropFile.type.substr( 0, dropFile.type.indexOf( "/" ) ) ) {

		case "video" :
			elVideo.src = dropFileUrl;
			elVideo.play();
		break;

		default :
			switch ( dropFile.name.substr( dropFile.name.lastIndexOf( "." ) + 1 ) ) {

				case "vtt" :
					var elTrack = document.createElement( "track" );
					elTrack.kind = "subtitles";
					elTrack.src = dropFileUrl;
					elTrack.label = "Subtitles " + ( elVideo.textTracks ? elVideo.textTracks.length + 1 : 1 );
					elTrack.srclang = "en"; // TODO: We must find a way to made it generically
					elVideo.appendChild( elTrack );
					elTrack.addEventListener( "load", function() {
						// Set this track to be the active one
						this.mode =
						elVideo.textTracks[ 0 ].mode = "showing";
					});
				break;
			}
	}

	return false;
};

Add WebVTT subtitles drop on each browsers


var default_opacity = 0.2;
var animate_time = 0;
var default_animate_time = 1000;
var num_images = 152;

function fix_resolutions() {
  var img = $('#imgloader').get(0);
  var img_ratio = img.naturalWidth / img.naturalHeight;
  var wnd_ratio = window.innerWidth / window.innerHeight;
  $("#back").css("background-size", img_ratio > wnd_ratio ? "auto 100%" : "100% auto");
}

function set_random_img() {
  var img = $('#imgloader').attr('src');
  var back = $('#back');

  back.animate({opacity: 0}, animate_time, 'swing', function() {
    if(animate_time == 0) { animate_time = default_animate_time; }

    back.css("background-image", "url('" + img + "')");
    fix_resolutions();
    back.animate({opacity: default_opacity}, animate_time);
  });
}

function select_random_img() {
  $('#imgloader').attr('src', "static/imgs/" + (Math.floor(Math.random() * num_images) + 1) + ".jpg");
}

$( document ).ready(function() {
  $('#imgloader').attr('src', '').load(set_random_img);
  select_random_img();

  $(window).resize(fix_resolutions);
  window.setInterval(select_random_img, 10000);
});

var default_opacity = 0.2;
var animate_time = 0;
var default_animate_time = 1000;
var num_images = 152;

function fix_resolutions() {
  var img = $('#imgloader').get(0);
  var img_ratio = img.naturalWidth / img.naturalHeight;
  var wnd_ratio = window.innerWidth / window.innerHeight;
  $("#back").css("background-size", img_ratio > wnd_ratio ? "auto 100%" : "100% auto");
}

function set_random_img() {
  var img = $('#imgloader').attr('src');
  var back = $('#back');

  back.animate({opacity: 0}, animate_time, 'swing', function() {
    back.css("background-image", "url('" + img + "')");
    fix_resolutions();
    back.animate({opacity: default_opacity}, animate_time);

    if(animate_time == 0) { animate_time = default_animate_time; }
  });
}

function select_random_img() {
  $('#imgloader').attr('src', "static/imgs/" + (Math.floor(Math.random() * num_images) + 1) + ".jpg");
}

$( document ).ready(function() {
  $('#imgloader').attr('src', '').load(set_random_img);
  select_random_img();

  $(window).resize(fix_resolutions);
  window.setInterval(select_random_img, 10000);
});

Load background even faster first time


module.exports = {
  port: 3000,
  canvas: {
    apiUrl: 'https://kth.instructure.com/api/v1'
  },
  logging: {
    log: {
      level: 'info',
      src: false
    },
    stdout: {
      enabled: true
    },
    console: {
      enabled: false
    }
  },
  ldap: {
    client: {
      url: 'ldaps://ldap.ug.kth.se',
      timeout: 300000,
      connectTimeout: 3000,
      maxConnections: 10,
      idleTimeout: 300000,
      checkInterval: 10000,
      reconnect: true
    }
  },
  azure: {
    queueName: 'ug-canvas',
    csvBlobName: 'lms-csv-prod',
    msgBlobName: 'lms-msg-prod'
  },
  localFile: {
    csvDir: '/tmp/'
  }
}

module.exports = {
  port: 3000,
  canvas: {
    apiUrl: 'https://kth.instructure.com/api/v1'
  },
  logging: {
    log: {
      level: 'debug',
      src: false
    },
    stdout: {
      enabled: true
    },
    console: {
      enabled: false
    }
  },
  ldap: {
    client: {
      url: 'ldaps://ldap.ug.kth.se',
      timeout: 300000,
      connectTimeout: 3000,
      maxConnections: 10,
      idleTimeout: 300000,
      checkInterval: 10000,
      reconnect: true
    }
  },
  azure: {
    queueName: 'ug-canvas',
    csvBlobName: 'lms-csv-prod',
    msgBlobName: 'lms-msg-prod'
  },
  localFile: {
    csvDir: '/tmp/'
  }
}

Add debug to prod settings


"use strict";
var BaobabControllers; //globals

BaobabControllers
.controller('AppCtrl', ['$scope', '$me', '$inbox', '$auth', '$location', '$cookieStore', '$sce', function($scope, $me, $inbox, $auth, $location, $cookieStore, $sce) {
  var self = this;
  window.AppCtrl = this;

  this.inboxAuthURL = $sce.trustAsResourceUrl('https://beta.inboxapp.com/oauth/authorize');
  this.inboxClientID = $inbox.appId();
  this.inboxRedirectURL = window.location.protocol + "//" + window.location.host + "/";
  this.loginHint = '';

  this.clearToken = $auth.clearToken;
  this.token = function() {
    return $auth.token;
  };
  this.namespace = function() {
    return $me._namespace;
  };

  this.theme = $cookieStore.get('baobab_theme') || 'light';
  this.setTheme = function(theme) {
    self.theme = theme;
    $cookieStore.put('baobab_theme', theme);
  };

  this.cssForTab = function(path) {
    return ($location.path().indexOf(path) != -1) ? 'active' : '';
  };
}]);

"use strict";
var BaobabControllers; //globals

BaobabControllers
.controller('AppCtrl', ['$scope', '$me', '$inbox', '$auth', '$location', '$cookieStore', '$sce', function($scope, $me, $inbox, $auth, $location, $cookieStore, $sce) {
  var self = this;
  window.AppCtrl = this;

  this.inboxAuthURL = $sce.trustAsResourceUrl('https://www.inboxapp.com/oauth/authorize');
  this.inboxClientID = $inbox.appId();
  this.inboxRedirectURL = window.location.protocol + "//" + window.location.host + "/";
  this.loginHint = '';

  this.clearToken = $auth.clearToken;
  this.token = function() {
    return $auth.token;
  };
  this.namespace = function() {
    return $me._namespace;
  };

  this.theme = $cookieStore.get('baobab_theme') || 'light';
  this.setTheme = function(theme) {
    self.theme = theme;
    $cookieStore.put('baobab_theme', theme);
  };

  this.cssForTab = function(path) {
    return ($location.path().indexOf(path) != -1) ? 'active' : '';
  };
}]);

Connect to www not beta (which no longer exists)


define(
[
    'chai',
    'sinon',
    'fixtures',
    'argumenta/widgets/Proposition',
    'argumenta/widgets/Base'
],
function(chai, undefined, fixtures, Proposition, Base) {

    var assert = chai.assert;

    describe('Proposition', function() {

        it('should be a function', function() {
            assert.isFunction(Proposition);
        });

        it('should include a moduleID', function() {
            assert.equal(Proposition.prototype.moduleID, 'Proposition');
        });

        describe('new Proposition( options, element )', function() {

            it('should return a new Proposition widget', function() {
                var data = fixtures.validPropositionData();
                var proposition = new Proposition(data);
                assert.instanceOf(
                    proposition, Base,
                    'Proposition widgets inherit from Base.'
                );
                assert.instanceOf(
                    proposition, Proposition,
                    'Proposition widgets are instances of Proposition.'
                );
            });
        });
    });
});

define(
[
    'chai',
    'sinon',
    'fixtures',
    'argumenta/widgets/Proposition',
    'argumenta/widgets/Base'
],
function(chai, undefined, fixtures, Proposition, Base) {

    var assert = chai.assert;

    describe('Proposition', function() {

        it('should be a function', function() {
            assert.isFunction(Proposition);
        });

        it('should include a moduleID', function() {
            assert.equal(Proposition.prototype.moduleID, 'Proposition');
        });

        describe('new Proposition( options, element )', function() {

            it('should return a new Proposition widget', function() {
                var data = fixtures.validPropositionData();
                var proposition = new Proposition(data);
                assert.instanceOf(
                    proposition, Base,
                    'Proposition widgets inherit from Base.'
                );
                assert.instanceOf(
                    proposition, Proposition,
                    'Proposition widgets are instances of Proposition.'
                );
            });

            it('should display the proposition index', function() {
                var data = fixtures.validPropositionData();
                var proposition = new Proposition(data);
                var $span = proposition.element.find('span.index');
                var html = $span.html();
                assert.include(
                    html, 'P.',
                    'Check index.'
                );
            });

            it('should display the proposition text', function() {
                var data = fixtures.validPropositionData();
                var proposition = new Proposition(data);
                var $span = proposition.element.find('span.text');
                var html = $span.html();
                assert.include(
                    html, data.text,
                    'Check text.'
                );
            });

            it('should display the proposition SHA-1', function() {
                var data = fixtures.validPropositionData();
                var proposition = new Proposition(data);
                var $link = proposition.element.find('span.sha1 a');
                var href = $link.prop('href');
                var sha1 = $link.html();
                assert.include(
                    href, '/propositions/' + data.sha1,
                    'Check object link.'
                );
                assert.include(
                    sha1, data.sha1.substr(0, 20),
                    'Check SHA-1.'
                );
            });
        });
    });
});

Add tests for proposition display.


var http = require('http');
var gpio = require('pi-gpio');
var currentState = false;

var actuator = function(outputValue) {
  console.log('Switching relay: '+outputValue);
  currentState = outputValue;
  gpio.open(11, "output", function(err) {
    gpio.write(11, outputValue, function(err) {
      gpio.close(11);
    });
  });
};

var doPollingReq = function() {
  console.log('Starting request...');
  var pollingReqOpts = {
    host: process.env.SERVER_HOSTNAME || 'localhost',
    port: process.env.SERVER_PORT || 3000,
    path: '/alarm',
    method: 'GET'
  };
  var pollingReq = http.request(pollingReqOpts, function(res) {
    console.log('Request being created...');
    res.on('data', function(data) {
      console.log('Got data: '+data);
      var objData = JSON.parse(data);
      if (objData && objData.value !== undefined) {
        actuator(objData.value);
      }
    });
    res.on('close', doPollingReq);
    res.on('end', doPollingReq);
  });
  pollingReq.end();
};

setImmediate(doPollingReq);

var http = require('http');
var gpio = require('pi-gpio');
var currentState = false;

var actuator = function(outputValue) {
  console.log('Switching relay: '+outputValue);
  currentState = outputValue;
  gpio.open(11, "output", function(err) {
    gpio.write(11, outputValue, function(err) {
      gpio.close(11);
    });
  });
  if (outputValue) {
    // Turn off after 5sec
    setTimeout(actuator, proces.env.DELAY || 5000, false);
  }
};

var doPollingReq = function() {
  console.log('Starting request...');
  var pollingReqOpts = {
    host: process.env.SERVER_HOSTNAME || 'localhost',
    port: process.env.SERVER_PORT || 3000,
    path: '/alarm',
    method: 'GET'
  };
  var pollingReq = http.request(pollingReqOpts, function(res) {
    console.log('Request being created...');
    res.on('data', function(data) {
      console.log('Got data: '+data);
      var objData = JSON.parse(data);
      if (objData && objData.value !== undefined) {
        actuator(objData.value);
      }
    });
    res.on('close', doPollingReq);
    res.on('end', doPollingReq);
    res.on('error', doPollingReq);
  });
  pollingReq.end();
};

setImmediate(doPollingReq);

Handle errors, and turn off after delay


define(['codemirror', 'matchbrackets', 'continuecomment', 'javascripthint', 'javascriptmode'], function() {
    function initEditor($e) {
        return CodeMirror($e.get(0), {
            value: "function effect(cube) {\n    cube().off();\n}",
            mode: 'javascript',
            indentUnit: 4,
            lineWrapping: true,
            lineNumbers: true,
            matchBrackets: true
        });
    }

    return initEditor;
});

define(['codemirror', 'matchbrackets', 'continuecomment', 'javascripthint', 'javascriptmode'], function() {
    function initEditor($e) {
        return CodeMirror($e.get(0), {
            value: "function effect(cube) {\n    cube().on();\n}",
            mode: 'javascript',
            indentUnit: 4,
            lineWrapping: true,
            lineNumbers: true,
            matchBrackets: true
        });
    }

    return initEditor;
});

Make default code more sensible (on instead of off)


function initType(a,b,c,d,e,f){}//IGNORE
function String$(x){}//IGNORE
function ArraySequence(x){}//IGNORE
var exports;//IGNORE

function Callable(wat) {
    return wat;
}
initType(Callable, 'ceylon.language::Callable');
exports.Callable=Callable;

function $JsCallable(callable,targs) {
    callable.getT$all=Callable.getT$all;
    if (targs !== undefined) {
        callable.$$targs$$=targs;
    }
    return callable;
}
initExistingTypeProto($JsCallable, Function, 'ceylon.language::JsCallable', Callable);

function noop() { return null; }

//This is used for plain method references
function JsCallable(o,f) {
	return (o !== null) ? function() { return f.apply(o, arguments); }
	                    : noop;
}

//This is used for spread method references
function JsCallableList(value) {
    return function() {
        var rval = Array(value.length);
        for (var i = 0; i < value.length; i++) {
            var c = value[i];
            rval[i] = c.f.apply(c.o, arguments);
        }
        return ArraySequence(rval);
    };
}

exports.JsCallableList=JsCallableList;
exports.JsCallable=JsCallable;
exports.$JsCallable=$JsCallable;

function initType(a,b,c,d,e,f){}//IGNORE
function String$(x){}//IGNORE
function ArraySequence(x){}//IGNORE
var exports;//IGNORE

function Callable(wat) {
    return wat;
}
Callable.$$metamodel$$={$nm:'Callable',$tp:{Return:{'var':'out'}, Arguments:{'var':'in'}}};
initType(Callable, 'ceylon.language::Callable');
exports.Callable=Callable;

function $JsCallable(callable,targs) {
    callable.getT$all=Callable.getT$all;
    if (targs !== undefined) {
        callable.$$targs$$=targs;
    }
    return callable;
}
initExistingTypeProto($JsCallable, Function, 'ceylon.language::JsCallable', Callable);

function noop() { return null; }

//This is used for plain method references
function JsCallable(o,f) {
	return (o !== null) ? function() { return f.apply(o, arguments); }
	                    : noop;
}
JsCallable.$$metamodel$$={$nm:'Callable',$tp:{Return:{'var':'out'}, Arguments:{'var':'in'}}};

//This is used for spread method references
function JsCallableList(value) {
    return function() {
        var rval = Array(value.length);
        for (var i = 0; i < value.length; i++) {
            var c = value[i];
            rval[i] = c.f.apply(c.o, arguments);
        }
        return ArraySequence(rval);
    };
}
JsCallableList.$$metamodel$$={$nm:'Callable',$tp:{Return:{'var':'out'}, Arguments:{'var':'in'}}};

exports.JsCallableList=JsCallableList;
exports.JsCallable=JsCallable;
exports.$JsCallable=$JsCallable;

Add runtime metamodel to Callable


/**
 * Grunt-Contrib-Uglify
 * @description Minify files with UglifyJS.
 * @docs https://github.com/gruntjs/grunt-contrib-uglify
 */

var config = require("../Config");

module.exports = {
	js: {
		options: {
			banner: config.bannerComment()
		},
		files: [{
			expand: true,
			cwd: config.JavaScripts.paths.devDir,
			src: [
				"**/*.js",
				"!Vendor/almond/**/*.js",
				"!Vendor/modernizr/**/*.js"
			],
			dest:  config.JavaScripts.paths.distDir
		}]
	}
};

/**
 * Grunt-Contrib-Uglify
 * @description Minify files with UglifyJS.
 * @docs https://github.com/gruntjs/grunt-contrib-uglify
 */

var config = require("../Config");

module.exports = {
	js: {
		options: {
			banner: config.bannerComment()
		},
		files: [{
			expand: true,
			cwd: config.JavaScripts.paths.devDir,
			src: [
				"**/*.js",
				"!Vendor/requirejs/bin/**/*.js",
				"!Vendor/almond/**/*.js",
				"!Vendor/modernizr/**/*.js"
			],
			dest:  config.JavaScripts.paths.distDir
		}]
	}
};

Make sure the requirejs binaries wont get uglified since they are breaking the ulgification


/* @flow */
import type { AggregatedReaction, RealmEmojiState, RealmEmojiType } from '../../types';
import emojiMap from '../../emoji/emojiMap';
import template from './template';

const getRealmEmojiHtml = (realmEmoji: RealmEmojiType): string =>
  template`
  `;

export default (
  messageId: number,
  reaction: AggregatedReaction,
  realmEmoji: RealmEmojiState,
): string =>
  template`$!${
    realmEmoji[reaction.name]
      ? getRealmEmojiHtml(realmEmoji[reaction.name])
      : emojiMap[reaction.name]
  } ${reaction.count}
`;

Use non-breaking space to separate emoji and reaction count.


(function(app) {
  'use strict';

  var jCore = require('jcore');
  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');
  var Button = app.Button || require('./button.js');
  var SidebarToggleButton = app.SidebarToggleButton || require('./sidebar-toggle-button.js');

  var LoadButton = helper.inherits(function(props) {
    LoadButton.super_.call(this, props);
  }, Button);

  var ContentHeader = helper.inherits(function(props) {
    ContentHeader.super_.call(this);

    this.element = this.prop(props.element);

    this.sidebarToggleButton = this.prop(new SidebarToggleButton({
      element: this.sidebarToggleButtonElement(),
      collapser: props.sidebarCollapser,
      expander: props.sidebarExpander
    }));

    this.sidebarToggleButton().registerTapListener();
  }, jCore.Component);

  ContentHeader.prototype.sidebarToggleButtonElement = function() {
    return dom.child(this.element(), 0);
  };

  ContentHeader.prototype.loadButtonElement = function() {
    return dom.child(this.element(), 1);
  };

  ContentHeader.prototype.saveButtonElement = function() {
    return dom.child(this.element(), 2);
  };

  ContentHeader.prototype.redraw = function() {
    this.sidebarToggleButton().redraw();
  };

  if (typeof module !== 'undefined' && module.exports)
    module.exports = ContentHeader;
  else
    app.ContentHeader = ContentHeader;
})(this.app || (this.app = {}));

(function(app) {
  'use strict';

  var jCore = require('jcore');
  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');
  var Button = app.Button || require('./button.js');
  var SidebarToggleButton = app.SidebarToggleButton || require('./sidebar-toggle-button.js');

  var LoadButton = helper.inherits(function(props) {
    LoadButton.super_.call(this, props);
  }, Button);

  var SaveButton = helper.inherits(function(props) {
    SaveButton.super_.call(this, props);
  }, Button);

  var ContentHeader = helper.inherits(function(props) {
    ContentHeader.super_.call(this);

    this.element = this.prop(props.element);

    this.sidebarToggleButton = this.prop(new SidebarToggleButton({
      element: this.sidebarToggleButtonElement(),
      collapser: props.sidebarCollapser,
      expander: props.sidebarExpander
    }));

    this.sidebarToggleButton().registerTapListener();
  }, jCore.Component);

  ContentHeader.prototype.sidebarToggleButtonElement = function() {
    return dom.child(this.element(), 0);
  };

  ContentHeader.prototype.loadButtonElement = function() {
    return dom.child(this.element(), 1);
  };

  ContentHeader.prototype.saveButtonElement = function() {
    return dom.child(this.element(), 2);
  };

  ContentHeader.prototype.redraw = function() {
    this.sidebarToggleButton().redraw();
  };

  if (typeof module !== 'undefined' && module.exports)
    module.exports = ContentHeader;
  else
    app.ContentHeader = ContentHeader;
})(this.app || (this.app = {}));

Add a constructor for a component of the save-button


!(function( global ) {

  var Opera = function() {};

  Opera.prototype.REVISION = '1';

  Opera.prototype.version = function() {
    return this.REVISION;
  };

  Opera.prototype.buildNumber = function() {
    return this.REVISION;
  };

  Opera.prototype.postError = function( str ) {
    console.log( str );
  };

  var opera = global.opera || new Opera();

  var manifest = chrome.app.getDetails(); // null in injected scripts / popups

  navigator.browserLanguage=navigator.language; //Opera defines both, some extensions use the former

  var isReady = false;

  var _delayedExecuteEvents = [
    // Example:
    // { 'target': opera.extension, 'methodName': 'message', 'args': event }
  ];

  // Pick the right base URL for new tab generation
  var newTab_BaseURL = 'data:text/html,<!--tab_%s-->';

  function addDelayedEvent(target, methodName, args) {
    if(isReady) {
      target[methodName].apply(target, args);
    } else {
      _delayedExecuteEvents.push({
        "target": target,
        "methodName": methodName,
        "args": args
      });
    }
  };

!(function( global ) {

  var Opera = function() {};

  Opera.prototype.REVISION = '1';

  Opera.prototype.version = function() {
    return this.REVISION;
  };

  Opera.prototype.buildNumber = function() {
    return this.REVISION;
  };

  Opera.prototype.postError = function( str ) {
    console.log( str );
  };

  var opera = global.opera || new Opera();

  var manifest = chrome.app.getDetails(); // null in injected scripts / popups

  navigator.browserLanguage=navigator.language; //Opera defines both, some extensions use the former

  var isReady = false;

  var _delayedExecuteEvents = [
    // Example:
    // { 'target': opera.extension, 'methodName': 'message', 'args': event }
  ];

  // Pick the right base URL for new tab generation
  var newTab_BaseURL = 'data:text/html,<!DOCTYPE html><!--tab_%s--><title>Loading...</title><script>history.forward()</script>';

  function addDelayedEvent(target, methodName, args) {
    if(isReady) {
      target[methodName].apply(target, args);
    } else {
      _delayedExecuteEvents.push({
        "target": target,
        "methodName": methodName,
        "args": args
      });
    }
  };

Update new tab base URL to auto-forward + display user-friendly title


const hyperglue = require('hyperglue')
const html      = require('fs').readFileSync(__dirname + '/index.html')

module.exports = function(movie) {
	return hyperglue(html, {
		'.name': movie.name,
		'.desc': movie.desc,
		'.movie': {
			'data-id': movie.id.toString()
		}
	})
}

const hyperglue = require('hyperglue')
const html      = require('fs').readFileSync(__dirname + '/index.html').toString()

module.exports = function(movie) {
	return hyperglue(html, {
		'.name': movie.name,
		'.desc': movie.desc,
		'.movie': {
			'data-id': movie.id.toString(),
			'data-name': movie.name
		}
	})
}

Make _movie include the id


// @require: OpenLayers/Tile.js
/**
* @class
*/
OpenLayers.Tile.Image = Class.create();
OpenLayers.Tile.Image.prototype =
  Object.extend( new OpenLayers.Tile(), {

    /** @type DOMElement img */
    img:null,

    /**
    * @constructor
    *
    * @param {OpenLayers.Grid} layer
    * @param {OpenLayers.Pixel} position
    * @param {OpenLayers.Bounds} bounds
    * @param {String} url
    * @param {OpenLayers.Size} size
    */
    initialize: function(layer, position, bounds, url, size) {
        OpenLayers.Tile.prototype.initialize.apply(this, arguments);
    },

    destroy: function() {
        this.layer.div.removeChild(this.img);
        this.img = null;
    },

    /**
    */
    draw:function() {
        OpenLayers.Tile.prototype.draw.apply(this, arguments);
        this.img = OpenLayers.Util.createImage(null,
                                               this.position,
                                               this.size,
                                               this.url,
                                               "absolute");
        this.layer.div.appendChild(this.img);
    },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Tile.Image"
  }
);

// @require: OpenLayers/Tile.js
/**
* @class
*/
OpenLayers.Tile.Image = Class.create();
OpenLayers.Tile.Image.prototype =
  Object.extend( new OpenLayers.Tile(), {

    /** @type DOMElement img */
    img:null,

    /**
    * @constructor
    *
    * @param {OpenLayers.Grid} layer
    * @param {OpenLayers.Pixel} position
    * @param {OpenLayers.Bounds} bounds
    * @param {String} url
    * @param {OpenLayers.Size} size
    */
    initialize: function(layer, position, bounds, url, size) {
        OpenLayers.Tile.prototype.initialize.apply(this, arguments);
    },

    destroy: function() {
        if (this.img.parentNode == this.layer.div) {
            this.layer.div.removeChild(this.img);
        }
        this.img = null;
    },

    /**
    */
    draw:function() {
        OpenLayers.Tile.prototype.draw.apply(this, arguments);
        this.img = OpenLayers.Util.createImage(null,
                                               this.position,
                                               this.size,
                                               this.url,
                                               "absolute");
        this.layer.div.appendChild(this.img);
    },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Tile.Image"
  }
);

Fix for bug introduced with r510. Only make the removeChild call if the parentNode is properly set. This way we can zap the grid div contents quickly with the div.innerHTML = "" but still have a valid good destroy() function.


/**
 * Based on: https://github.com/iriscouch/manage_couchdb/
 * License: Apache License 2.0
 **/
function(newDoc, oldDoc, userCtx, secObj) {
  var ddoc = this;

  secObj.admins = secObj.admins || {};
  secObj.admins.names = secObj.admins.names || [];
  secObj.admins.roles = secObj.admins.roles || [];

  var IS_DB_ADMIN = false;
  if(~ userCtx.roles.indexOf('_admin'))
    IS_DB_ADMIN = true;
  if(~ secObj.admins.names.indexOf(userCtx.name))
    IS_DB_ADMIN = true;
  for(var i = 0; i < userCtx.roles; i++)
    if(~ secObj.admins.roles.indexOf(userCtx.roles[i]))
      IS_DB_ADMIN = true;
  // check access.json's write_roles collection
  for(var i = 0; i < userCtx.roles; i++)
    if(~ ddoc.write_roles.indexOf(userCtx.roles[i]))
      IS_DB_ADMIN = true;

  if(ddoc.access && ddoc.access.read_only)
    if(IS_DB_ADMIN)
      log('Admin change on read-only db: ' + newDoc._id);
    else
      throw {'forbidden':'This database is read-only'};
}

/**
 * Based on: https://github.com/iriscouch/manage_couchdb/
 * License: Apache License 2.0
 **/
function(newDoc, oldDoc, userCtx, secObj) {
  var ddoc = this;

  secObj.admins = secObj.admins || {};
  secObj.admins.names = secObj.admins.names || [];
  secObj.admins.roles = secObj.admins.roles || [];

  var IS_DB_ADMIN = false;
  if(~ userCtx.roles.indexOf('_admin'))
    IS_DB_ADMIN = true;
  if(~ secObj.admins.names.indexOf(userCtx.name))
    IS_DB_ADMIN = true;
  for(var i = 0; i < userCtx.roles; i++)
    if(~ secObj.admins.roles.indexOf(userCtx.roles[i]))
      IS_DB_ADMIN = true;
  // check access.json's write_roles collection
  for(var i = 0; i < userCtx.roles.length; i++)
    if(~ ddoc.access.write_roles.indexOf(userCtx.roles[i]))
      IS_DB_ADMIN = true;

  if(ddoc.access && ddoc.access.read_only)
    if(IS_DB_ADMIN)
      log('Admin change on read-only db: ' + newDoc._id);
    else
      throw {'forbidden':'This database is read-only'};
}

Make perms write_roles actually work


var model = require('../models/index');

/* Returns a list of artists with the given genre (in the query string) */
exports.getArtistsByGenre = function(req, res) {
  return res.status(200).send('Success');
}

/* Gets all of the genres stored in the database */
exports.getGenres = function(req, res) {
  return res.status(200).send('Success');
}

var model = require('../models/index');
var _ = require('lodash');

/* Returns a list of artists with the given genre (in the query string) */
exports.getArtistsByGenre = function(req, res) {
  if (_.isEmpty(req.query.genre)) return res.status(400).send('No parameters given');
  else {
    model.Genre.findOne({ where: { genre: req.query.genre } })
    .then(function(genre) {
      if (_.isEmpty(genre)) return res.status(400).send('Genre not found');
      else {
        model.Artist.findAll({ where: { genre: genre.values.id }, limit: 20 })
        .then(function(artists) {
          if (_.isEmpty(artists)) return res.status(400).send('No artist with genre found');
          else {
            return res.status(200).send(artists);
          }
        })
        .catch(function(err) {
          return res.status(400).send(err);
        });
      }
    })
    .catch(function(err) {
      return res.status(400).send(err);
    });
  }
}

/* Gets all of the genres stored in the database */
exports.getGenres = function(req, res) {
  return res.status(200).send('Success');
}

Implement getting of artists by their genre


// @flow

export type UpdateType = {
	authors: string[],
	categories: string[],
	content: string,
	datePublished: ?string,
	excerpt: string,
	featuredImage: ?string,
	link: ?string,
	title: string,
}

// @flow

export type UpdateType = {
	authors: string[],
	categories: string[],
	content: string,
	datePublished: ?string,
	excerpt: string,
	featuredImage: ?string,
	link: string,
	title: string,
}

Mark covid update link type as non-optional


import { isNil } from 'substance'

export default function addTestAPI (tape) {
  const Test = tape.Test

  Test.prototype.nil =
  Test.prototype.isNil = function (value, msg, extra) {
    this._assert(isNil(value), {
      message: msg,
      operator: 'nil',
      expected: true,
      actual: value,
      extra: extra
    })
  }

  Test.prototype.notNil =
  Test.prototype.isNotNil = function (value, msg, extra) {
    this._assert(!isNil(value), {
      message: msg,
      operator: 'nil',
      expected: true,
      actual: value,
      extra: extra
    })
  }
}

import { isNil, platform } from 'substance'

export default function addTestAPI (tape) {
  const Test = tape.Test

  if (platform.inNodeJS) {
    const _run = Test.prototype.run
    Test.prototype.run = function () {
      try {
        _run.apply(this, arguments)
      } catch (err) {
        this.fail('Uncaught error: ' + String(err))
        this.end()
      }
    }
  }

  Test.prototype.nil =
  Test.prototype.isNil = function (value, msg, extra) {
    this._assert(isNil(value), {
      message: msg,
      operator: 'nil',
      expected: true,
      actual: value,
      extra: extra
    })
  }

  Test.prototype.notNil =
  Test.prototype.isNotNil = function (value, msg, extra) {
    this._assert(!isNil(value), {
      message: msg,
      operator: 'nil',
      expected: true,
      actual: value,
      extra: extra
    })
  }
}

Add a wrapper so that nodejs tests catch uncaught exceptions.


import {
  visit,
  remote,
  saveAndProcessPage,
  copyPage,
} from '../action_creators'
import { urlToPageKey } from './url'

export function mapStateToProps(
  state = { pages: {}, breezy: {} },
  ownProps
) {
  let pageKey = ownProps.pageKey
  let params = ownProps
  const csrfToken = state.breezy.csrfToken
  pageKey = urlToPageKey(pageKey)
  const { data, flash } = state.pages[pageKey] || {
    data: {},
    flash: {},
  }
  return { ...data, ...params, pageKey, csrfToken, flash }
}

export const mapDispatchToProps = {
  saveAndProcessPage,
  copyPage,
}

export const mapDispatchToPropsIncludingVisitAndRemote = {
  visit,
  remote,
  saveAndProcessPage,
  copyPage,
}

import {
  visit,
  remote,
  saveAndProcessPage,
  copyPage,
} from '../action_creators'
import { urlToPageKey } from './url'

export function mapStateToProps(
  state = { pages: {}, breezy: {} },
  ownProps
) {
  let pageKey = ownProps.pageKey
  let params = ownProps
  const csrfToken = state.breezy.csrfToken
  pageKey = urlToPageKey(pageKey)
  const { data, flash, fragments } = state.pages[pageKey] || {
    data: {},
    flash: {},
    fragments: [],
  }
  return { ...data, ...params, pageKey, csrfToken, flash, fragments }
}

export const mapDispatchToProps = {
  saveAndProcessPage,
  copyPage,
}

export const mapDispatchToPropsIncludingVisitAndRemote = {
  visit,
  remote,
  saveAndProcessPage,
  copyPage,
}

Add fragments to merged props


import('helma.webapp', 'webapp');
import('model');

var handleRequest = webapp.handleRequest;

// the main action is invoked for http://localhost:8080/
// this also shows simple skin rendering
function index_action(req, res) {
    if (req.params.save) {
        createBook(req, res);
    }
    if (req.params.remove) {
        removeBook(req, res);
    }
    var books = model.Book.all();
    res.render('skins/index.html', {
        title: 'Storage Demo',
        books: function(/*tag, skin, context*/) {
            var buffer = [];
            for (var i in books) {
                var book = books[i]
                buffer.push(book.getFullTitle(), getDeleteLink(book), "
\r\n");
            }
            return buffer.join(' ');
        }
    });
}

function createBook(req, res) {
    var author = new model.Author({name: req.params.author});
    var book = new model.Book({author: author, title: req.params.title});
    // author is saved transitively
    book.save();
    res.redirect('/');
}

function removeBook(req, res) {
    var book = model.Book.get(req.params.remove);
    // author is removed through cascading delete
    book.remove();
    res.redirect('/');
}

function getDeleteLink(book) {
    return 'delete';
}

if (__name__ == "__main__") {
    webapp.start();
}

import('helma.webapp', 'webapp');
import('model');

// the main action is invoked for http://localhost:8080/
// this also shows simple skin rendering
function index_action(req, res) {
    if (req.params.save) {
        createBook(req, res);
    }
    if (req.params.remove) {
        removeBook(req, res);
    }
    var books = model.Book.all();
    res.render('skins/index.html', {
        title: 'Storage Demo',
        books: function(/*tag, skin, context*/) {
            var buffer = [];
            for (var i in books) {
                var book = books[i]
                buffer.push(book.getFullTitle(), getDeleteLink(book), "
\r\n");
            }
            return buffer.join(' ');
        }
    });
}

function createBook(req, res) {
    var author = new model.Author({name: req.params.author});
    var book = new model.Book({author: author, title: req.params.title});
    // author is saved transitively
    book.save();
    res.redirect('/');
}

function removeBook(req, res) {
    var book = model.Book.get(req.params.remove);
    // author is removed through cascading delete
    book.remove();
    res.redirect('/');
}

function getDeleteLink(book) {
    return 'delete';
}

if (__name__ == "__main__") {
    webapp.start();
}

Remove obsolete import of handleRequest function.


// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

cur_frm.add_fetch("customer", "customer_name", "customer_name")
cur_frm.add_fetch("supplier", "supplier_name", "supplier_name")

cur_frm.add_fetch("item_code", "item_name", "item_name")
cur_frm.add_fetch("item_code", "description", "description")
cur_frm.add_fetch("item_code", "item_group", "item_group")
cur_frm.add_fetch("item_code", "brand", "brand")

cur_frm.cscript.onload = function() {
	cur_frm.set_query("item_code", function() {
		return erpnext.queries.item({"is_stock_item": "Yes", "has_serial_no": "Yes"})
	});
};

frappe.ui.form.on("Serial No", "refresh", function(frm) {
	frm.toggle_enable("item_code", frm.doc.__islocal);
});

// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

cur_frm.add_fetch("customer", "customer_name", "customer_name")
cur_frm.add_fetch("supplier", "supplier_name", "supplier_name")

cur_frm.add_fetch("item_code", "item_name", "item_name")
cur_frm.add_fetch("item_code", "description", "description")
cur_frm.add_fetch("item_code", "item_group", "item_group")
cur_frm.add_fetch("item_code", "brand", "brand")

cur_frm.cscript.onload = function() {
	cur_frm.set_query("item_code", function() {
		return erpnext.queries.item({"is_stock_item": "Yes", "has_serial_no": "Yes"})
	});
};

frappe.ui.form.on("Serial No", "refresh", function(frm) {
	frm.toggle_enable("item_code", frm.doc.__islocal);

	if(frm.doc.status == "Sales Returned" && frm.doc.warehouse)
		cur_frm.add_custom_button(__('Set Status as Available'), cur_frm.cscript.set_status_as_available);
});

cur_frm.cscript.set_status_as_available = function() {
	cur_frm.set_value("status", "Available");
	cur_frm.save()
}

Set status button in serial no


import { Store, toImmutable } from 'nuclear-js'

import actionTypes from '~/actions/actionTypes'
const { TOGGLE_LICENSE_MODAL, TOGGLE_ABOUT_MODAL } = actionTypes

export default Store({
  getInitialState() {
    return toImmutable({
      licenseModalOpened: false,
      aboutModalOpened: false
    })
  },

  initialize() {
    this.on(TOGGLE_LICENSE_MODAL, toggleLicenseModal)
    this.on(TOGGLE_ABOUT_MODAL, toggleAboutModal)
  }
})

function toggleLicenseModal(state) {
  return state.set('licenseModalOpened', !state.get('licenseModalOpened'))
}

function toggleAboutModal(state) {
  return state.set('aboutModalOpened', !state.get('aboutModalOpened'))
}

import { Store, toImmutable } from 'nuclear-js'

import actionTypes from '~/actions/actionTypes'
const {
  TOGGLE_LICENSE_MODAL,
  TOGGLE_ABOUT_MODAL,
  VIEW_MODE_CHANGED
} = actionTypes

export default Store({
  getInitialState() {
    return toImmutable({
      licenseModalOpened: false,
      aboutModalOpened: false,
      viewMode: -1
    })
  },

  initialize() {
    this.on(TOGGLE_LICENSE_MODAL, toggleLicenseModal)
    this.on(TOGGLE_ABOUT_MODAL, toggleAboutModal)
    this.on(VIEW_MODE_CHANGED, viewModeChanged)
  }
})

function toggleLicenseModal(state) {
  return state.set('licenseModalOpened', !state.get('licenseModalOpened'))
}

function toggleAboutModal(state) {
  return state.set('aboutModalOpened', !state.get('aboutModalOpened'))
}

function viewModeChanged(state, { mode }) {
  return state.set('viewMode', mode.toString())
}

Add view mode to UI store


/*
 * Copyright (c) 2012-2014 André Bargull
 * Alle Rechte vorbehalten / All Rights Reserved.  Use is subject to license terms.
 *
 * <https://github.com/anba/es6draft>
 */

const {
  assertSame
} = Assert;

// Invalid direct eval call and tail calls:
// - direct eval fallback and 'wrong' eval function have both tail calls enabled
// - chaining them should preserve the tail call property

const stackLimit = (function() {
  let limit = 0;
  try {
    (function f(){ f(limit++) })();
  } catch (e) {
  }
  return limit;
})();

function gauss(n) {
  return (n * n + n) / 2;
}

let callCount;
let realm = new Realm({
  directEval: {
    fallback(thisArgument, callee, ...args) {
      "use strict";
      callCount += 1;
      return callee(...args);
    }
  }
});
realm.eval(`
  function sum(n, acc) {
    "use strict";
    if (n === 0) return acc;
    return eval(n - 1, acc + n);
  }
  eval = sum;
`);

for (let v of [1, 10, 100, 1000, 10000, stackLimit * 10]) {
  callCount = 0;
  assertSame(gauss(v), realm.eval(`sum(${v}, 0)`));
  assertSame(v, callCount);
}

/*
 * Copyright (c) 2012-2014 André Bargull
 * Alle Rechte vorbehalten / All Rights Reserved.  Use is subject to license terms.
 *
 * <https://github.com/anba/es6draft>
 */

const {
  assertSame
} = Assert;

// Invalid direct eval call and tail calls:
// - direct eval fallback and 'wrong' eval function have both tail calls enabled
// - chaining them should preserve the tail call property

let realm = new Realm({
  directEval: {
    fallback(thisArgument, callee, ...args) {
      "use strict";
      return callee(...args);
    }
  }
});
realm.eval(`
  function returnCaller() {
    return returnCaller.caller;
  }

  function tailCall() {
    "use strict";
    return returnCaller();
  }

  function testFunction() {
    return eval("123");
  }

  eval = tailCall;
`);

assertSame(realm.global.testFunction, realm.eval(`testFunction()`));

Use the .caller property to test tail-calls instead of trying to cause stackoverflow errors


app.controller('NavController', ['$http', '$firebaseAuth', '$mdDialog', 'AuthFactory', function($http, $firebaseAuth, $mdDialog, AuthFactory) {
  console.log('NavController running');
  var auth = $firebaseAuth();
  var self = this;

  self.logInModal = function(ev) {
    $mdDialog.show({
        controller: 'LoginController as login',
        templateUrl: '../../views/login-modal.html',
        targetEvent: ev,
        clickOutsideToClose: true
      })
      .then(function(answer) {
        // logIn();
      });
  };

}]);

// $scope.showAdvanced = function(ev) {
//     $mdDialog.show({
//       controller: DialogController,
//       templateUrl: 'dialog1.tmpl.html',
//       parent: angular.element(document.body),
//       targetEvent: ev,
//       clickOutsideToClose:true,
//       fullscreen: $scope.customFullscreen // Only for -xs, -sm breakpoints.
//     })
//     .then(function(answer) {
//       $scope.status = 'You said the information was "' + answer + '".';
//     }, function() {
//       $scope.status = 'You cancelled the dialog.';
//     });
//   };

app.controller('NavController', ['$http', '$firebaseAuth', '$mdDialog', 'AuthFactory', 'BioFactory', function($http, $firebaseAuth, $mdDialog, AuthFactory, BioFactory) {
  console.log('NavController running');
  var auth = $firebaseAuth();
  var self = this;

  var userId = AuthFactory.userStatus.userId;

  self.logInModal = function(ev) {
    $mdDialog.show({
        controller: 'LoginController as login',
        templateUrl: '../../views/login-modal.html',
        targetEvent: ev,
        clickOutsideToClose: true
      })
      .then(function(answer) {
        // logIn();
      });
  };

  self.setMentorId = function(){
    BioFactory.setMentorId(AuthFactory.userStatus.userId);
  }

}]);

// $scope.showAdvanced = function(ev) {
//     $mdDialog.show({
//       controller: DialogController,
//       templateUrl: 'dialog1.tmpl.html',
//       parent: angular.element(document.body),
//       targetEvent: ev,
//       clickOutsideToClose:true,
//       fullscreen: $scope.customFullscreen // Only for -xs, -sm breakpoints.
//     })
//     .then(function(answer) {
//       $scope.status = 'You said the information was "' + answer + '".';
//     }, function() {
//       $scope.status = 'You cancelled the dialog.';
//     });
//   };

Add userId var and setMentorId function


'use strict';
const path = require('path');
const os = require('os');

exports.toNumber = function(x) { return (x = Number(x)) >= 0 ? x : false; };
exports.getSocketPath = function(channel)
{
    let pipePath = path.resolve(os.tmpdir(), `.fast.mq.${channel}`);

    // use windows named pipe
    if (process.platform === 'win32')
    {
        pipePath = path.replace(/^\//, '');
        pipePath = path.replace(/\//g, '-');
        pipePath = `\\\\.\\pipe\\${pipePath}`;
    }
    return pipePath;
};

const pid = (process && process.pid) ? process.pid : 0;
function uuid()
{
    var time = Date.now();
    var last = uuid.last || time;
    uuid.last = time > last ? (pid + time) : (pid + last + 1);
    return uuid.last;
}

exports.uuid = uuid;

'use strict';
const path = require('path');
const os = require('os');

exports.toNumber = function(x) { return (x = Number(x)) >= 0 ? x : false; };
exports.getSocketPath = function(channel)
{
    let pipePath = path.resolve(os.tmpdir(), `.fast.mq.${channel}`);

    // use windows named pipe
    if (process.platform === 'win32')
    {
        pipePath = pipePath.replace(/^\//, '');
        pipePath = pipePath.replace(/\//g, '-');
        pipePath = `\\\\.\\pipe\\${pipePath}`;
    }
    return pipePath;
};

const pid = (process && process.pid) ? process.pid : 0;
function uuid()
{
    var time = Date.now();
    var last = uuid.last || time;
    uuid.last = time > last ? (pid + time) : (pid + last + 1);
    return uuid.last;
}

exports.uuid = uuid;

Fix windows name pipeline issue


walk(document.body);

var rpl = "butt";
function loadRpl() {
  var rpl = localStorage["rpl"];
  return rpl;
}

function walk(node)
{
	// I stole this function from here:
	// http://is.gd/mwZp7E

	var child, next;

	switch ( node.nodeType )
	{
		case 1:  // Element
		case 9:  // Document
		case 11: // Document fragment
			child = node.firstChild;
			while ( child )
			{
				next = child.nextSibling;
				walk(child);
				child = next;
			}
			break;

		case 3: // Text node
			handleText(node);
			break;
	}
}

function handleText(textNode)
{
	var v = textNode.nodeValue;

  rpl = loadRpl();
	v = v.replace(/\bTrump\b/g, rpl);

	textNode.nodeValue = v;
}

walk(document.body);

var rpl = "butt";
function loadRpl() {
  var rpl = localStorage["rpl"];
  return rpl;
}

function walk(node)
{
	// I stole this function from here:
	// http://is.gd/mwZp7E

	var child, next;

	switch ( node.nodeType )
	{
		case 1:  // Element
		case 9:  // Document
		case 11: // Document fragment
			child = node.firstChild;
			while ( child )
			{
				next = child.nextSibling;
				walk(child);
				child = next;
			}
			break;

		case 3: // Text node
			handleText(node);
			break;
	}
}

function handleText(textNode)
{
	var v = textNode.nodeValue;

  rpl = loadRpl();
  // LocalStorage isn't working as I'd expect, so set a default.
  if ( rpl == undefined ) { rpl = "Butt"; }
	v = v.replace(/\bTrump\b/g, rpl);

	textNode.nodeValue = v;
}

Set a default for localstorage data, just in case.


import fetch from 'isomorphic-fetch'

export const REQUEST_BUS_STOPS = 'REQUEST_BUS_STOPS'
export const RECEIVE_BUS_STOPS = 'RECEIVE_BUS_STOPS'

function requestBusStops(meters, coors) {
  return {
    type: REQUEST_POSTS
  }
}

function receiveBusStops(received) {
  return {
    type: RECEIVE_POSTS
  }
}

import fetch from 'isomorphic-fetch'

//
//  action types
//

export const REQUEST_BUS_STOPS_AROUND_ME = 'REQUEST_BUS_STOPS_AROUND_ME'
export const RECEIVE_BUS_STOPS_AROUND_ME = 'RECEIVE_BUS_STOPS_AROUND_ME'

//
//  action creators
//

export function requestBusStopsAroundMe(meters, coors) {
  return {
    type: REQUEST_BUS_STOPS_AROUND_ME,
    meters,
    coors
  }
}

export function receiveBusStopsAroundMe(BusStopsAroundMe) {
  return {
    type: RECEIVE_BUS_STOPS_AROUND_ME,
    BusStopsAroundMe
  }
}
 5*

Add cations like redux strucure


/**
 * @module client/main
 */
'use strict';

require('./app');
require('angular');

/**
 * Each 'index' generated via grunt process dynamically includes all browserify common-js modules
 * in js bundle
 */
require('./controllers/index');
require('./services/index');

var io = require('./lib/socket.io');
var socket = io.connect('http://localhost:3000');
socket.on('data', function (data) {
  console.log('data received', data);
});

//require('router');

/**
 * Bundle of all templates to be attached to $templateCache generated by grunt process
 */
//var views = require('./build/views/viewBundle');

/**
 * DOM-ready event, start app
 */
angular.element(document).ready(function () {
  angular.bootstrap(document, ['app']);
});

/**
 * @module client/main
 */
'use strict';

require('./app');
require('angular');

/**
 * Each 'index' generated via grunt process dynamically includes all browserify common-js modules
 * in js bundle
 */
require('./controllers/index');
require('./services/index');

var io = require('./lib/socket.io');
var socket = io.connect('http://localhost:3000');
socket.on('data', function (data) {
  console.log('data received', data);
});

socket.on('postSequence', function (data) {
  console.log('postSequence: ', data);
});

//require('router');

/**
 * Bundle of all templates to be attached to $templateCache generated by grunt process
 */
//var views = require('./build/views/viewBundle');

/**
 * DOM-ready event, start app
 */
angular.element(document).ready(function () {
  angular.bootstrap(document, ['app']);
});

Add log logic in client module for postSequences event


(function() {
  var grid, projectItems;

  // setup grid
  {
    grid = $('.project-grid');
    grid.isotope({
      itemSelector: '.project-item',

      percentPosition: true,
      masonry: {
        columnWidth: '.project-grid-sizer'
      },

      sortBy: 'sortIndex',
      getSortData: {
        sortIndex: '[data-sort-index]',
      }
    });
  }

  // gray on hover
  {
    var restoreColorTimeout;
    projectItems = $('.project-item', grid);
    projectItems.on('mouseover touchstart', function(e) {
      clearTimeout(restoreColorTimeout);
      projectItems.addClass('gray');
      $(e.currentTarget).removeClass('gray');
      $(e.currentTarget).addClass('hover'); // force hover
    });
    projectItems.on('mouseoout touchend', function(e) {
      $(e.currentTarget).removeClass('hover'); // force unhover
      // debounce color restoration so we know that no for sure no other item has been moused over
      clearTimeout(restoreColorTimeout);
      restoreColorTimeout = setTimeout(function() {
        projectItems.removeClass('gray');
      }, 50);
    });
  }
})()

(function() {
  var grid, projectItems;

  // setup grid
  {
    grid = $('.project-grid');
    grid.isotope({
      itemSelector: '.project-item',

      percentPosition: true,
      masonry: {
        columnWidth: '.project-grid-sizer'
      },

      sortBy: 'sortIndex',
      getSortData: {
        sortIndex: '[data-sort-index]',
      }
    });
  }

  // gray on hover
  {
    var restoreColorTimeout;
    projectItems = $('.project-item', grid);
    projectItems.on('mouseover touchstart', function(e) {
      clearTimeout(restoreColorTimeout);
      projectItems.addClass('gray');
      $(e.currentTarget).removeClass('gray');
      $(e.currentTarget).addClass('hover'); // force hover
    });
    projectItems.on('mouseout touchend', function(e) {
      $(e.currentTarget).removeClass('hover'); // force unhover
      // debounce color restoration so we know that no for sure no other item has been moused over
      clearTimeout(restoreColorTimeout);
      restoreColorTimeout = setTimeout(function() {
        projectItems.removeClass('gray');
      }, 50);
    });
  }
})()

Fix typo in project grid event registration


'use strict';
angular.module('arethusa.core').service('notifier', function () {
  var self = this;
  this.messages = [];

  function Message(type, message, description) {
    this.type = type;
    this.message = message;
    this.description = description;
  }

  this.success = function (message) {
    self.messages.unshift({
      type: 'success',
      message: message
    });
  };
  this.error = function (message) {
    self.messages.unshift({
      type: 'error',
      message: message
    });
  };
  this.lastMessage = function () {
    return self.messages[0];
  };
  this.oldMessages = function () {
    return self.messages.slice(1);
  };
});

'use strict';
angular.module('arethusa.core').service('notifier', function () {
  var self = this;
  this.messages = [];

  function Message(type, message, description) {
    this.type = type;
    this.message = message;
    this.description = description;
  }

  this.success = function (message) {
    self.addMessage('success', message);
  };
  this.error = function (message) {
    self.addMessage('error', message);
  };

  this.lastMessage = function () {
    return self.messages[0];
  };
  this.oldMessages = function () {
    return self.messages.slice(1);
  };

  this.addMessage = function(type, message) {
    if (self.messages.length === 15) {
      self.messages.pop();
    }
    self.messages.unshift(new Message(type, message));
  };
  this.reset = function() {
    self.messages = [];
  };
});

Fix maximum length for messages


navigator.geolocation.getCurrentPosition(function(position) {
  makeMap({lat: position.coords.latitude, lng: position.coords.longitude});
}, function(err) {
  console.error(err);
});
var map;
var marker;
var destinationMarker;
var makeMap = function(currentLatLngObj) {
  map = new google.maps.Map(document.getElementById('map'), {
    center: currentLatLngObj,
    zoom: 13
  });
  marker = new google.maps.Marker({
    position: currentLatLngObj,
    map: map,
    animation: google.maps.Animation.DROP,
    icon: '/assets/bolt.png'
  });
  destinationMarker = new google.maps.Marker({
    position: randomCoordsAlongCircumference(currentLatLngObj, 1),
    map: map,
    animation: google.maps.Animation.DROP,
    icon: '/assets/finish-line.png' // change to finish line image
  });
};

var randomCoordsAlongCircumference = function(originObj, radius) {
  var randomTheta = Math.random() * 2 * Math.PI;
  return {
    lat: originObj.lat + (radius / 69 * Math.cos(randomTheta)),
    lng: originObj.lng + (radius / 69 * Math.sin(randomTheta))
  };
};

navigator.geolocation.getCurrentPosition(function (position) {
  var mapToMake = {
    lat: position.coords.latitude,
    lng: position.coords.longitude
  };
  makeMap(mapToMake);
}, function (err) {
  console.error(err);
});

var map;
var marker;
var destinationMarker;
var makeMap = function (currentLatLngObj) {
  map = new google.maps.Map(document.getElementById('map'), {
    center: currentLatLngObj,
    zoom: 13
  });
  marker = new google.maps.Marker({
    position: currentLatLngObj,
    map: map,
    animation: google.maps.Animation.DROP,
    icon: '/assets/bolt.png'
  });
  destinationMarker = new google.maps.Marker({
    position: randomCoordsAlongCircumference(currentLatLngObj, 1),
    map: map,
    animation: google.maps.Animation.DROP,
    icon: '/assets/finish-line.png' // change to finish line image
  });
};

var randomCoordsAlongCircumference = function (originObj, radius) {
  var randomTheta = Math.random() * 2 * Math.PI;
  return {
    lat: originObj.lat + (radius / 69 * Math.cos(randomTheta)),
    lng: originObj.lng + (radius / 69 * Math.sin(randomTheta))
  };
};

Fix and ungodly number of linter errors


import {createAction} from 'redux-actions';
import axios from 'axios';

export const FETCH_APP_REQUEST = 'FETCH_APP_REQUEST';
export const FETCH_APP_SUCCESS = 'FETCH_APP_SUCCESS';
export const FETCH_APP_FAILURE = 'FETCH_APP_FAILURE';

export const RESET_STORE_AT_KEY = 'RESET_STORE_AT_KEY';

const fetchIndexRequest = createAction(FETCH_APP_REQUEST);
const fetchIndexSuccess = createAction(FETCH_APP_SUCCESS);
const fetchIndexFailure = createAction(FETCH_APP_FAILURE);

export const fetchApp = () => async (dispatch) => {
  dispatch(fetchIndexRequest());

  let response;

  try {
    response = await axios.get('v1/index');
  } catch (err) {
    const reducedAction = (err instanceof Error) ? fetchIndexFailure(err) : fetchIndexFailure(err.response);

    return dispatch(reducedAction);
  }

  return dispatch(fetchIndexSuccess(response.data));
};

export const resetStoreAtKey = (key, initialState) => (dispatch) => {
  const resetStoreAtKeyAction = createAction(RESET_STORE_AT_KEY);

  return dispatch(resetStoreAtKeyAction({key, initialState}));
};

import {createAction} from 'redux-actions';
import axios from 'axios';

export const FETCH_APP_REQUEST = 'FETCH_APP_REQUEST';
export const FETCH_APP_SUCCESS = 'FETCH_APP_SUCCESS';
export const FETCH_APP_FAILURE = 'FETCH_APP_FAILURE';

export const RESET_STORE_AT_KEY = 'RESET_STORE_AT_KEY';

const fetchIndexRequest = createAction(FETCH_APP_REQUEST);
const fetchIndexSuccess = createAction(FETCH_APP_SUCCESS);
const fetchIndexFailure = createAction(FETCH_APP_FAILURE);

export const fetchApp = () => async (dispatch) => {
  dispatch(fetchIndexRequest());

  try {
    const {data} = await axios.get('v1/index');

    return dispatch(fetchIndexSuccess(data));
  } catch (err) {
    const reducedAction = (err instanceof Error) ? fetchIndexFailure(err) : fetchIndexFailure(err.response);

    return dispatch(reducedAction);
  }
};

export const resetStoreAtKey = (key, initialState) => (dispatch) => {
  const resetStoreAtKeyAction = createAction(RESET_STORE_AT_KEY);

  return dispatch(resetStoreAtKeyAction({key, initialState}));
};

Return dispatch in the try block.


import { declare } from "@babel/helper-plugin-utils";
import transformTypeScript from "@babel/plugin-transform-typescript";

export default declare(
  (api, { jsxPragma, allExtensions = false, isTSX = false }) => {
    api.assertVersion(7);

    if (typeof allExtensions !== "boolean") {
      throw new Error(".allExtensions must be a boolean, or undefined");
    }
    if (typeof isTSX !== "boolean") {
      throw new Error(".allExtensions must be a boolean, or undefined");
    }

    if (isTSX && !allExtensions) {
      throw new Error("isTSX:true requires allExtensions:true");
    }

    return {
      overrides: allExtensions
        ? [
            {
              plugins: [[transformTypeScript, { jsxPragma, isTSX }]],
            },
          ]
        : [
            {
              // Only set 'test' if explicitly requested, since it requires that
              // Babel is being called`
              test: /\.ts$/,
              plugins: [[transformTypeScript, { jsxPragma }]],
            },
            {
              // Only set 'test' if explicitly requested, since it requires that
              // Babel is being called`
              test: /\.tsx$/,
              plugins: [[transformTypeScript, { jsxPragma, isTSX: true }]],
            },
          ],
    };
  },
);

import { declare } from "@babel/helper-plugin-utils";
import transformTypeScript from "@babel/plugin-transform-typescript";

export default declare(
  (api, { jsxPragma, allExtensions = false, isTSX = false }) => {
    api.assertVersion(7);

    if (typeof allExtensions !== "boolean") {
      throw new Error(".allExtensions must be a boolean, or undefined");
    }
    if (typeof isTSX !== "boolean") {
      throw new Error(".isTSX must be a boolean, or undefined");
    }

    if (isTSX && !allExtensions) {
      throw new Error("isTSX:true requires allExtensions:true");
    }

    return {
      overrides: allExtensions
        ? [
            {
              plugins: [[transformTypeScript, { jsxPragma, isTSX }]],
            },
          ]
        : [
            {
              // Only set 'test' if explicitly requested, since it requires that
              // Babel is being called`
              test: /\.ts$/,
              plugins: [[transformTypeScript, { jsxPragma }]],
            },
            {
              // Only set 'test' if explicitly requested, since it requires that
              // Babel is being called`
              test: /\.tsx$/,
              plugins: [[transformTypeScript, { jsxPragma, isTSX: true }]],
            },
          ],
    };
  },
);

Fix typo in option validation.


// Copyright (C) 2006 Google Inc.
//
// 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.

/**
 * @fileoverview
 * Registers a language handler for Protocol Buffers as described at
 * http://code.google.com/p/protobuf/.
 *
 * Based on the lexical grammar at
 * http://research.microsoft.com/fsharp/manual/spec2.aspx#_Toc202383715
 *
 * @author mikesamuel@gmail.com
 */

PR['registerLangHandler'](PR['sourceDecorator']({
        keywords: (
            'bool bytes default double enum extend extensions false fixed32 '
            + 'fixed64 float group import int32 int64 max message option '
            + 'optional package repeated required returns rpc service '
            + 'sfixed32 sfixed64 sint32 sint64 string syntax to true uint32 '
            + 'uint64'),
        cStyleComments: true
      }), ['proto']);

// Copyright (C) 2006 Google Inc.
//
// 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.

/**
 * @fileoverview
 * Registers a language handler for Protocol Buffers as described at
 * http://code.google.com/p/protobuf/.
 *
 * Based on the lexical grammar at
 * http://research.microsoft.com/fsharp/manual/spec2.aspx#_Toc202383715
 *
 * @author mikesamuel@gmail.com
 */

PR['registerLangHandler'](PR['sourceDecorator']({
        'keywords': (
            'bytes,default,double,enum,extend,extensions,false,'
            + 'group,import,max,message,option,'
            + 'optional,package,repeated,required,returns,rpc,service,'
            + 'syntax,to,true'),
        'types': /^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\b/,
        'cStyleComments': true
      }), ['proto']);

Fix proto lang handler to work minified and to use the type style for types like uint32.


import Component from '@glimmer/component';
import { action } from '@ember/object';

export default class FormButtonComponent extends Component {
  @action
  handleClick() {
    if (!this.args.isActing && this.args.onClick) {
      return this.args.onClick();
    }
  }
}

import Component from '@glimmer/component';
import { action } from '@ember/object';

export default class FormButtonComponent extends Component {
  @action
  handleClick() {
    if (!this.args.isActing && this.args.onClick) {
      const ret = this.args.onClick();

      if (ret.finally) {
        this.isActing = true;
        ret.finally(() => (this.isActing = false));
      }
      return ret;
    }
  }
}

Fix simple button isActing state


function setup() {
  // put setup code here
}

function draw() {
  // put drawing code here
}

function setup() {
  createCanvas(640, 480);
}

function draw() {
  ellipse(50, 50, 80, 80);
}

/**
 * Boid class
 */
function Boid() {
  this.location = createVector();
  this.velocity = createVector();
  this.acceleration = createVector();
  this.mass = 0;
}

Create basic Boid class with properties


/* eslint-disable import/no-unresolved */

import React from 'react';
import ReactDOM from 'react-dom';

// Styling
import { FlexParent, FlexChild } from 'react-foundation-components/lib/flex';
import './splash.css';
import './logo.png';
import './splashFilters.jpg';

import 'react-foundation-components/lib/_typography.scss';

const App = () => {
  return (
    <FlexParent id="splashContainer" horizontalAlignment="middle" verticalAlignment="middle">
      <FlexChild>

      </FlexChild>
    </FlexParent>
  );
};

ReactDOM.render(<App />, document.getElementById('app'));

/* eslint-disable import/no-unresolved */

import React from 'react';
import ReactDOM from 'react-dom';

// Styling
import { FlexParent, FlexChild } from 'react-foundation-components/lib/flex';
import './splash.css';
import './logo.png';
import './splashFilters.jpg';

import 'react-foundation-components/lib/_typography.scss';

const App = () => {
  return (
    <FlexParent id="splashContainer" horizontalAlignment="center" verticalAlignment="middle">
      <FlexChild>

      </FlexChild>
    </FlexParent>
  );
};

ReactDOM.render(<App />, document.getElementById('app'));

Use proper value center (not middle) for `<FlexParent horizontalAlignment>` attribute


// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

// Support for Node 0.10
// See https://github.com/webpack/css-loader/issues/144
require('es6-promise').polyfill();

var childProcess = require('child_process');
var buildExtension = require('@jupyterlab/extension-builder/lib/builder').buildExtension;
var webpack = require('webpack');

console.log('Generating bundles...');

var notice = childProcess.execSync('git describe', { encoding: 'utf8' });

buildExtension({
  name: 'main',
  entry: './build/main',
  outputDir: './build',
  config: {
    output: {
      publicPath: 'lab/',
    },
    module: {
      noParse: [/xterm\.js/]   // Xterm ships a UMD module
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env': {
          'GIT_DESCRIPTION': JSON.stringify(notice.trim())
        }
      })
    ]
  }
});

module.exports = {
  entry: {
    loader: './build/loader'
  },
  output: {
    path: __dirname + '/build',
    filename: '[name].bundle.js',
    libraryTarget: 'this',
    library: 'jupyter'
  },
  node: {
    fs: 'empty'
  },
  debug: true,
  bail: true,
  devtool: 'source-map'
}

// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

// Support for Node 0.10
// See https://github.com/webpack/css-loader/issues/144
require('es6-promise').polyfill();

var childProcess = require('child_process');
var buildExtension = require('@jupyterlab/extension-builder/lib/builder').buildExtension;
var webpack = require('webpack');

console.log('Generating bundles...');

try {
  var notice = childProcess.execSync('git describe', { encoding: 'utf8' });
} catch {
  var notice = 'unknown';
}

buildExtension({
  name: 'main',
  entry: './build/main',
  outputDir: './build',
  config: {
    output: {
      publicPath: 'lab/',
    },
    module: {
      noParse: [/xterm\.js/]   // Xterm ships a UMD module
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env': {
          'GIT_DESCRIPTION': JSON.stringify(notice.trim())
        }
      })
    ]
  }
});

module.exports = {
  entry: {
    loader: './build/loader'
  },
  output: {
    path: __dirname + '/build',
    filename: '[name].bundle.js',
    libraryTarget: 'this',
    library: 'jupyter'
  },
  node: {
    fs: 'empty'
  },
  debug: true,
  bail: true,
  devtool: 'source-map'
}

Add a try guard around git description


import React from "react";
import DayPicker, {DateUtils} from "react-day-picker";
import "./MeetingDaysField.scss";

class MeetingDaysField extends React.Component {
  static propTypes = {
    days: React.PropTypes.array.isRequired,
    month: React.PropTypes.object.isRequired,
    onDayChange: React.PropTypes.func.isRequired,
    onMonthChange: React.PropTypes.func.isRequired
  };

  handleDayClick(e, day, {selected, disabled}){
    // We need to pass it upwards
    if(disabled){
      return;
    }

    this.props.onDayChange(selected, day);
  }

  isDaySelected(day){
    return this.props.days.findIndex((d) => DateUtils.isSameDay(d, day)) > -1;
  }

  render(){
    let { month, onMonthChange } = this.props;
    return (

        Wybierz dni

          <DayPicker initialMonth={month} firstDayOfWeek={1} selectedDays={this.isDaySelected.bind(this)}
                     onDayClick={this.handleDayClick.bind(this)} onMonthChange={onMonthChange} />

          {this.props.children}

    );
  }
}
export default MeetingDaysField;

import React from "react";
import DayPicker, {DateUtils} from "react-day-picker";
import moment from 'moment';
import "./MeetingDaysField.scss";

class MeetingDaysField extends React.Component {
  static propTypes = {
    days: React.PropTypes.array.isRequired,
    month: React.PropTypes.object.isRequired,
    onDayChange: React.PropTypes.func.isRequired,
    onMonthChange: React.PropTypes.func.isRequired
  };

  handleDayClick(e, day, {selected, disabled}){
    // We need to pass it upwards
    if(disabled){
      return;
    }

    this.props.onDayChange(selected, day);
  }

  isDaySelected(day){
    return this.props.days.findIndex((d) => DateUtils.isSameDay(d, day)) > -1;
  }

  isDayBeforeToday(day) {
    return moment(day).add(1, 'day').isBefore();
  }

  render(){
    let { month, onMonthChange } = this.props;
    return (

        Wybierz dni

          <DayPicker initialMonth={month} firstDayOfWeek={1} selectedDays={this.isDaySelected.bind(this)}
                     disabledDays={this.isDayBeforeToday.bind(this)} fromMonth={new Date()}
                     onDayClick={this.handleDayClick.bind(this)} onMonthChange={onMonthChange} />

          {this.props.children}

    );
  }
}
export default MeetingDaysField;

Disable days before today for selection