function supportsCodeConstraint(identifier, dataElementSpecs) {
  if (CODE.equals(identifier) || checkHasBaseType(identifier, new Identifier('shr.core', 'Coding'), dataElementSpecs)
      || checkHasBaseType(identifier, new Identifier('shr.core', 'CodeableConcept'), dataElementSpecs)) {
    return true;
  }
  const element = dataElementSpecs.findByIdentifier(identifier);
  if (element.value) {
    if (element.value instanceof IdentifiableValue) {
      return CODE.equals(element.value.identifier) || checkHasBaseType(element.value.identifier, new Identifier('shr.core', 'Coding'), dataElementSpecs)
          || checkHasBaseType(element.value.identifier, new Identifier('shr.core', 'CodeableConcept'), dataElementSpecs);
    } else if (element.value instanceof ChoiceValue) {
      for (const value of element.value.aggregateOptions) {
        if (value instanceof IdentifiableValue) {
          if (CODE.equals(value.identifier) || checkHasBaseType(value.identifier, new Identifier('shr.core', 'Coding'), dataElementSpecs)
              || checkHasBaseType(value.identifier, new Identifier('shr.core', 'CodeableConcept'), dataElementSpecs)) {
            return true;
          }
        }
      }
    }
  }
  return false;
}

function supportsCodeConstraint ( identifier , dataElementSpecs ) { if ( CODE . equals ( identifier ) || checkHasBaseType ( identifier , new Identifier ( 'shr.core' , 'Coding' ) , dataElementSpecs ) || checkHasBaseType ( identifier , new Identifier ( 'shr.core' , 'CodeableConcept' ) , dataElementSpecs ) ) { return true ; } const element = dataElementSpecs . findByIdentifier ( identifier ) ; if ( element . value ) { if ( element . value instanceof IdentifiableValue ) { return CODE . equals ( element . value . identifier ) || checkHasBaseType ( element . value . identifier , new Identifier ( 'shr.core' , 'Coding' ) , dataElementSpecs ) || checkHasBaseType ( element . value . identifier , new Identifier ( 'shr.core' , 'CodeableConcept' ) , dataElementSpecs ) ; } else if ( element . value instanceof ChoiceValue ) { for ( const value of element . value . aggregateOptions ) { if ( value instanceof IdentifiableValue ) { if ( CODE . equals ( value . identifier ) || checkHasBaseType ( value . identifier , new Identifier ( 'shr.core' , 'Coding' ) , dataElementSpecs ) || checkHasBaseType ( value . identifier , new Identifier ( 'shr.core' , 'CodeableConcept' ) , dataElementSpecs ) ) { return true ; } } } } } return false ; }

stealing from shr-expand
Determine if a type supports a code constraint.

@param {Identifier} identifier - The identifier of the type to check.
@param {DataElementSpecifications} dataElementSpecs - The available DataElement specs.
@return {boolean} Whether or not the given type supports a code constraint.

stealing from shr - expand Determine if a type supports a code constraint .


async function expire ({ payload, meta = {} }, { dispatch }) {
  const { service } = payload
  const { ident } = meta

  if (!service) {
    return createError(`Can't delete expired without a specified service`)
  }
  if (!payload.endpoint) {
    return createError(`Can't delete expired from service '${service}' without an endpoint`)
  }
  if (!payload.type) {
    return createError(`Can't delete expired from service '${service}' without one or more specified types`)
  }

  const response = await getExpired(payload, ident, dispatch)

  return deleteExpired(response, service, ident, dispatch)
}

async function expire ( { payload , meta = { } } , { dispatch } ) { const { service } = payload const { ident } = meta if ( ! service ) { return createError ( ` ` ) } if ( ! payload . endpoint ) { return createError ( ` ${ service } ` ) } if ( ! payload . type ) { return createError ( ` ${ service } ` ) } const response = await getExpired ( payload , ident , dispatch ) return deleteExpired ( response , service , ident , dispatch ) }

Action to delete expired items.

The given `endpoint` is used to retrieve expired items from the `service`, and
may use the paramters `timestamp` or `isodate`, which represents the current
time plus the microseconds in `msFromNow`, the former as microseconds since
January 1, 1970, the latter as an ISO formatted date and time string.

The items are mapped and typed, so the `type` param should be set to one
or more types expected from the `endpoint`, and may be a string or an array
of strings.
@param {Object} payload - Action payload (service, type, endpoint, and msFromNow)
@param {Object} resources - Dispatch and queue functions
@returns {Object} Response object


function transformRange(range, ops) {
  var rangeComps = range.split(':')
    , newRange
  var start = rangeComps[0]
  ops.forEach(op => start = transformRangeAnchor(start, op, /*isStart:*/true))
  var end = rangeComps[1]
  ops.forEach(op => end = transformRangeAnchor(end, op, /*isStart:*/false))
  if (start === end) return start
  return start+':'+end
}

function transformRange ( range , ops ) { var rangeComps = range . split ( ':' ) , newRange var start = rangeComps [ 0 ] ops . forEach ( op => start = transformRangeAnchor ( start , op , true ) ) var end = rangeComps [ 1 ] ops . forEach ( op => end = transformRangeAnchor ( end , op , false ) ) if ( start === end ) return start return start + ':' + end }

Transforms a range against an array of ops


function transformRangeAnchor(target, op, isStart) {
  var thisCell = parseCell(target)
  if (op instanceof InsertCol) {
    var otherCell = parseCell(op.newCol)
    if (otherCell[0] <= thisCell[0]) return column.fromInt(thisCell[0]+1)+thisCell[1]
  }
  else if (op instanceof DeleteCol) {
    var otherCell = parseCell(op.col)
    if (otherCell[0] < thisCell[0]) return column.fromInt(thisCell[0]-1)+thisCell[1]
    if (otherCell[0] === thisCell[0]) {
      // Spreadsheet selection is different from text selection:
      // While text selection ends in the first *not* selected char ( "foo| |bar" => 3,4)
      // ... spreadsheet selection ends in the last selected cell. Thus we need to
      // differentiate between start and end. Shame on those who didn't think about this!
      if (!isStart) return column.fromInt(thisCell[0]-1)+thisCell[1]     }
  }
  else if (op instanceof InsertRow) {
    var otherCell = parseCell(op.newRow)
    if (otherCell[1] <= thisCell[1]) return column.fromInt(thisCell[0])+(thisCell[1]+1)
  }
  else if (op instanceof DeleteRow) {
    var otherCell = parseCell(op.col)
    if (otherCell[1] < thisCell[1]) return column.fromInt(thisCell[0])+(thisCell[1]-1)
    if (otherCell[1] === thisCell[1]) {
      if (!isStart) return column.fromInt(thisCell[0])+(thisCell[1]-1)
    }
  }
  // If nothing has returned already then this anchor doesn't change
  return target
}

function transformRangeAnchor ( target , op , isStart ) { var thisCell = parseCell ( target ) if ( op instanceof InsertCol ) { var otherCell = parseCell ( op . newCol ) if ( otherCell [ 0 ] <= thisCell [ 0 ] ) return column . fromInt ( thisCell [ 0 ] + 1 ) + thisCell [ 1 ] } else if ( op instanceof DeleteCol ) { var otherCell = parseCell ( op . col ) if ( otherCell [ 0 ] < thisCell [ 0 ] ) return column . fromInt ( thisCell [ 0 ] - 1 ) + thisCell [ 1 ] if ( otherCell [ 0 ] === thisCell [ 0 ] ) { if ( ! isStart ) return column . fromInt ( thisCell [ 0 ] - 1 ) + thisCell [ 1 ] } } else if ( op instanceof InsertRow ) { var otherCell = parseCell ( op . newRow ) if ( otherCell [ 1 ] <= thisCell [ 1 ] ) return column . fromInt ( thisCell [ 0 ] ) + ( thisCell [ 1 ] + 1 ) } else if ( op instanceof DeleteRow ) { var otherCell = parseCell ( op . col ) if ( otherCell [ 1 ] < thisCell [ 1 ] ) return column . fromInt ( thisCell [ 0 ] ) + ( thisCell [ 1 ] - 1 ) if ( otherCell [ 1 ] === thisCell [ 1 ] ) { if ( ! isStart ) return column . fromInt ( thisCell [ 0 ] ) + ( thisCell [ 1 ] - 1 ) } } return target }

Transforms a range anchor, taking into account whether it's the start or end

Transforms a range anchor taking into account whether it s the start or end


function matchEndpoint (endpoints) {
  return ({ type, payload, meta }) => endpoints
    .find((endpoint) =>
      matchId(endpoint, { type, payload }) &&
      matchType(endpoint, { type, payload }) &&
      matchScope(endpoint, { type, payload }) &&
      matchAction(endpoint, { type, payload }) &&
      matchParams(endpoint, { type, payload }) &&
      matchFilters(endpoint, { type, payload, meta }))
}

function matchEndpoint ( endpoints ) { return ( { type , payload , meta } ) => endpoints . find ( ( endpoint ) => matchId ( endpoint , { type , payload } ) && matchType ( endpoint , { type , payload } ) && matchScope ( endpoint , { type , payload } ) && matchAction ( endpoint , { type , payload } ) && matchParams ( endpoint , { type , payload } ) && matchFilters ( endpoint , { type , payload , meta } ) ) }

Return the first matching endpoint from an array of endpoints that has
already been sortert with higher specificity first. Type should match before
scope, which should match before action, but the order here is taken care of
by the required sorting.

@param {Object[]} endpoints - Array of endpoint objects
@param {Object} action - Action object to match agains
@returns {Object} Matching endpoint

Return the first matching endpoint from an array of endpoints that has already been sortert with higher specificity first . Type should match before scope which should match before action but the order here is taken care of by the required sorting .


function createAction (type, payload = {}, meta) {
  if (!type) {
    return null
  }

  const action = { type, payload }
  if (meta) {
    action.meta = meta
  }
  return action
}

function createAction ( type , payload = { } , meta ) { if ( ! type ) { return null } const action = { type , payload } if ( meta ) { action . meta = meta } return action }

Create an action object.
@param {string} type - The action type
@param {Object} payload - The payload of the action
@param {Object} props - Other action properties
@returns {Object} An action object


function authorizeRequest ({ schemas }) {
  return ({ request }) => {
    const { access = {}, params = {}, action } = request

    const { ident = null } = access

    if (ident && ident.root) {
      return authItemsAndWrap(request, { status: 'granted', ident, scheme: 'root' }, schemas)
    }
    if (!params.type) {
      return authItemsAndWrap(request, { status: 'granted', ident, scheme: null }, schemas)
    }

    const requireAuth = !!request.auth
    const schema = schemas[params.type]
    const scheme = getScheme(schema, action)
    const status = (doAuth(scheme, ident, requireAuth)) ? 'granted' : 'refused'

    return authItemsAndWrap(request, { status, ident, scheme }, schemas)
  }
}

function authorizeRequest ( { schemas } ) { return ( { request } ) => { const { access = { } , params = { } , action } = request const { ident = null } = access if ( ident && ident . root ) { return authItemsAndWrap ( request , { status : 'granted' , ident , scheme : 'root' } , schemas ) } if ( ! params . type ) { return authItemsAndWrap ( request , { status : 'granted' , ident , scheme : null } , schemas ) } const requireAuth = ! ! request . auth const schema = schemas [ params . type ] const scheme = getScheme ( schema , action ) const status = ( doAuth ( scheme , ident , requireAuth ) ) ? 'granted' : 'refused' return authItemsAndWrap ( request , { status , ident , scheme } , schemas ) } }

Authorize the request according to the setting on the relevant schema.
Sets the access object with `status` property specifying whether access
is `granted` or `refused`, and returns the request.

The access object also includes the `ident` and the  `scheme`used for
authentication.

@param {Object} request - The request object to authorize
@param {Object} schemas - An object with all schemas that may be needed
@returns {Object} The request object with updated access object

Authorize the request according to the setting on the relevant schema . Sets the access object with status property specifying whether access is granted or refused and returns the request .


function requestFromAction (
  { type: action, payload, meta = {} },
  { endpoint, schemas = {} } = {}
) {
  const { data, ...params } = payload
  const { ident = null } = meta
  const typePlural = getPluralType(params.type, schemas)

  return {
    action,
    params,
    data,
    endpoint: (endpoint && endpoint.options) || null,
    access: { ident },
    meta: {
      typePlural
    }
  }
}

function requestFromAction ( { type : action , payload , meta = { } } , { endpoint , schemas = { } } = { } ) { const { data , ... params } = payload const { ident = null } = meta const typePlural = getPluralType ( params . type , schemas ) return { action , params , data , endpoint : ( endpoint && endpoint . options ) || null , access : { ident } , meta : { typePlural } } }

Complete missing props and allow only expected props on the request object.
@param {Object} request - The request object to complete
@returns {Object} The completed request object

Complete missing props and allow only expected props on the request object .


function getService (schemas, services) {
  return (type, service) => {
    if (!service && schemas[type]) {
      service = schemas[type].service
    }
    return services[service] || null
  }
}

function getService ( schemas , services ) { return ( type , service ) => { if ( ! service && schemas [ type ] ) { service = schemas [ type ] . service } return services [ service ] || null } }

Get service from type or service id.
@param {Object} schemas - The schemas
@param {Object} services - The services
@returns {function} Function to retrieve service from type and service id


async function sync ({ payload, meta = {} }, { dispatch }) {
  debug('Action: SYNC')
  const fromParams = await generateFromParams(payload, meta, dispatch)
  const toParams = generateToParams(payload, fromParams)

  const lastSyncedAt = new Date()

  const results = await Promise.all(
    fromParams.map(getFromService(dispatch, payload.type, meta))
  )

  if (results.some((result) => result.status !== 'ok')) {
    return (results.length === 1) ? results[0] : createError(makeErrorString(results))
  }

  const data = flatten(results.map((result) => result.data)).filter(Boolean)

  if (data.length === 0 && payload.syncNoData !== true) {
    return createError(`No items to update from service '${fromParams[0].service}'`, 'noaction')
  }

  return Promise.all([
    ...createSetMetas(fromParams, lastSyncedAt, meta.ident, dispatch),
    dispatch(action('SET', { data, ...toParams }, { ...meta, queue: true }))
  ])
    .then((responses) => {
      return { status: 'ok', data: responses }
    })
}

async
function
sync
(
{
payload
,
meta
=
{
}
}
,
{
dispatch
}
)
{
debug
(
'Action: SYNC'
)
const
fromParams
=
await
generateFromParams
(
payload
,
meta
,
dispatch
)
const
toParams
=
generateToParams
(
payload
,
fromParams
)
const
lastSyncedAt
=
new
Date
(
)
const
results
=
await
Promise
.
all
(
fromParams
.
map
(
getFromService
(
dispatch
,
payload
.
type
,
meta
)
)
)
if
(
results
.
some
(
(
result
)
=>
result
.
status
!==
'ok'
)
)
{
return
(
results
.
length
===
1
)
results
[
0
]
:
createError
(
makeErrorString
(
results
)
)
}
const
data
=
flatten
(
results
.
map
(
(
result
)
=>
result
.
data
)
)
.
filter
(
Boolean
)
if
(
data
.
length
===
0
&&
payload
.
syncNoData
!==
true
)
{
return
createError
(
`
${
fromParams
[
0
]
.
service
}
`
,
'noaction'
)
}
return
Promise
.
all
(
[
...
createSetMetas
(
fromParams
,
lastSyncedAt
,
meta
.
ident
,
dispatch
)
,
dispatch
(
action
(
'SET'
,
{
data
,
...
toParams
}
,
{
...
meta
,
queue
:
true
}
)
)
]
)
.
then
(
(
responses
)
=>
{
return
{
status
:
'ok'
,
data
:
responses
}
}
)
}

Action to sync from one service to another.

`retrieve` indicates which items to retrieve. The default is `all`, which
will retrieve all items from the `get` endpoint. Set `retrieve` to `updated`
to retrieve only items that are updated after the  `lastSyncedAt` date for
the `from` service. This is done by passing the `lastSyncedAt` date as a
parameter named `updatedAfter` to the `get` endpoint, and by actively
filter away any items received with `updatedAt` earlier than `lastSyncedAt`.

The `lastSyncedAt` metadata will be set on the `from` service when items
are retrieved and updated.

@param {Object} payload - Action payload (from, to, type, and retrieve)
@param {Object} resources - Dispatch function
@returns {Promise} Promise of the action result

Action to sync from one service to another .


function (gulp, cwd, config) {
  if (util.isNullOrUndefined(gulp)) {
    throw 'gulp must be defined';
  }

  /**
   * Configuration options that will be injected into every gulp task.
   *
   * @type {Object}
   */
  this._config = config || {},

  /**
   * Current working directory that path calculations should be relative to.
   *
   * @type {String}
   */
  this._cwd = cwd || __dirname;

  /**
   * Actual path of this file relative to the defined working directory.
   *
   * @type {String}
   */
  this._root = path.relative(this._cwd, __dirname);

  /**
   * Gulp instance. All tasks get injected the same gulp instances.
   *
   * @type {Gulp}
   */
  this._gulp = gulp;
}

function
(
gulp
,
cwd
,
config
)
{
if
(
util
.
isNullOrUndefined
(
gulp
)
)
{
throw
'gulp must be defined'
;
}
this
.
_config
=
config
||
{
}
,
this
.
_cwd
=
cwd
||
__dirname
;
this
.
_root
=
path
.
relative
(
this
.
_cwd
,
__dirname
)
;
this
.
_gulp
=
gulp
;
}

Task api that configures and loads gulp tasks.

@param {!Gulp} gulp
@param {String=} cwd
@param {Object=} config

Task api that configures and loads gulp tasks .


function(bg) {
    bg = bg ? bg : false

    return (...args) => {
      return this.output(args.join(' '), this.colors(bg))
    }
  }

function
(
bg
)
{
bg
=
bg
bg
:
false
return
(
...
args
)
=>
{
return
this
.
output
(
args
.
join
(
' '
)
,
this
.
colors
(
bg
)
)
}
}


function (browserify, name, source) {
  if (utility.isNullOrUndefined(browserify)) {
    throw 'browserify must be defined.';
  }

  if (!utility.isNonEmptyString(name)) {
    throw 'name must be defined.';
  }

  if (utility.isNullOrUndefined(source)) {
    throw 'source must be defined.';
  }

  this._browserify = browserify;
  this._name = name;
  this._source = source;
  this._hasModule = false;
  this._hasResolver = false;
}

function
(
browserify
,
name
,
source
)
{
if
(
utility
.
isNullOrUndefined
(
browserify
)
)
{
throw
'browserify must be defined.'
;
}
if
(
!
utility
.
isNonEmptyString
(
name
)
)
{
throw
'name must be defined.'
;
}
if
(
utility
.
isNullOrUndefined
(
source
)
)
{
throw
'source must be defined.'
;
}
this
.
_browserify
=
browserify
;
this
.
_name
=
name
;
this
.
_source
=
source
;
this
.
_hasModule
=
false
;
this
.
_hasResolver
=
false
;
}

Babel external helper module injector.

This object will configure browserify to accept a streaming source and then
resolve any relevant compile time bindings to the built module. The module
can later by referenced by name later down the browserify pipeline and modified
further.

@param {!Browserify} browserify
@param {!String} name
@param {!Readable} source


function mapToService () {
  return ({ request, requestMapper, mappings }) => {
    const data = mapData(request.data, request, mappings)
    return {
      ...request,
      data: applyEndpointMapper(data, request, requestMapper)
    }
  }
}

function mapToService ( ) { return ( { request , requestMapper , mappings } ) => { const data = mapData ( request . data , request , mappings ) return { ... request , data : applyEndpointMapper ( data , request , requestMapper ) } } }

Map the data coming _from_ the service. Everything is handled by the mappings,
but this method make sure that the right types are mapped.

@param {Object} data - The data to map
@param {Object} mappings - The mappings to map with
@returns {Object} Mapped data

Map the data coming _from_ the service . Everything is handled by the mappings but this method make sure that the right types are mapped .


async function processMessengerBody (body, context) {
    const allMessages = getAllMessages(body)
    if (!allMessages || !allMessages.length) return false

    context = context || {}

    for (let message of allMessages) {
      message = _.cloneDeep(message)
      const messageContext = Object.assign({}, context)
      try {
        for (let plugin of middleware) {
          await plugin(message, messageContext)
        }
      } catch (error) {
        const logError = (messageContext.log && messageContext.log.error instanceof Function)
          ? messageContext.log.error
          : console.error
        logError('Error running middleware', error)
      }
    }
    return true
  }

async
function
processMessengerBody
(
body
,
context
)
{
const
allMessages
=
getAllMessages
(
body
)
if
(
!
allMessages
||
!
allMessages
.
length
)
return
false
context
=
context
||
{
}
for
(
let
message
of
allMessages
)
{
message
=
_
.
cloneDeep
(
message
)
const
messageContext
=
Object
.
assign
(
{
}
,
context
)
try
{
for
(
let
plugin
of
middleware
)
{
await
plugin
(
message
,
messageContext
)
}
}
catch
(
error
)
{
const
logError
=
(
messageContext
.
log
&&
messageContext
.
log
.
error
instanceof
Function
)
messageContext
.
log
.
error
:
console
.
error
logError
(
'Error running middleware'
,
error
)
}
}
return
true
}

Process messages from Facebook Messenger.

@param  {object}   body               _parsed_ JSON HTTP message body.
@param  {function} beforeMiddlewareFn optional function to call before executing
any plugins.
@return {boolean}                     + `true` if the Message was processed
+ `false` if the body didn't contain
Messenger messages

Process messages from Facebook Messenger .


function create(prop) {
  if (typeof prop !== 'string') {
    throw new Error('expected the first argument to be a string.');
  }

  return function(app) {
    if (this.isRegistered('base-' + prop)) return;

    // map config
    var config = utils.mapper(app)
      // store/data
      .map('store', store(app.store))
      .map('data')

      // options
      .map('enable')
      .map('disable')
      .map('option')
      .alias('options', 'option')

      // get/set
      .map('set')
      .map('del')

    // Expose `prop` (config) on the instance
    app.define(prop, proxy(config));

    // Expose `process` on app[prop]
    app[prop].process = config.process;
  };

  function store(app) {
    if (!app) return {};
    var mapper = utils.mapper(app);
    app.define(prop, proxy(mapper));
    return mapper;
  }
}

Create a function for mapping `app` properties onto the
given `prop` namespace.

@param {String} `prop` The namespace to use
@param {Object} `argv`
@return {Object}
@api public

Create a function for mapping app properties onto the given prop namespace .


function ElementMatrix(top) {
  CommanalityMatrix.call(this, top);

  this.row(' ');
  this.collum(' ');
  this.classlist = top.root.classlist;
}

function
ElementMatrix
(
top
)
{
CommanalityMatrix
.
call
(
this
,
top
)
;
this
.
row
(
' '
)
;
this
.
collum
(
' '
)
;
this
.
classlist
=
top
.
root
.
classlist
;
}

Collects features and bind them to the node density


function publicS3URI(string) {
	return encodeURIComponent(string)
		.replace(/%20/img, '+')
		.replace(/%2F/img, '/')
    .replace(/\"/img, "%22")
    .replace(/\#/img, "%23")
    .replace(/\$/img, "%24")
    .replace(/\&/img, "%26")
    .replace(/\'/img, "%27")
		.replace(/\(/img, "%28")
    .replace(/\)/img, "%29")
    .replace(/\,/img, "%2C")
    .replace(/\:/img, "%3A")
    .replace(/\;/img, "%3B")
    .replace(/\=/img, "%3D")
    .replace(/\?/img, "%3F")
    .replace(/\@/img, "%40");
}

function publicS3URI ( string ) { return encodeURIComponent ( string ) . replace ( / %20 / img , '+' ) . replace ( / %2F / img , '/' ) . replace ( / \" / img , "%22" ) . replace ( / \# / img , "%23" ) . replace ( / \$ / img , "%24" ) . replace ( / \& / img , "%26" ) . replace ( / \' / img , "%27" ) . replace ( / \( / img , "%28" ) . replace ( / \) / img , "%29" ) . replace ( / \, / img , "%2C" ) . replace ( / \: / img , "%3A" ) . replace ( / \; / img , "%3B" ) . replace ( / \= / img , "%3D" ) . replace ( / \? / img , "%3F" ) . replace ( / \@ / img , "%40" ) ; }


function (done) {
        fs.writeFile(
          path.resolve(__dirname, '../../test/reallife/expected/' + item.key + '.json'),
          JSON.stringify({
            'title': item.title,
            'text': item.text
          }, null, '\t') + '\n',
          done
        );
      }

function ( done ) { fs . writeFile ( path . resolve ( __dirname , '../../test/reallife/expected/' + item . key + '.json' ) , JSON . stringify ( { 'title' : item . title , 'text' : item . text } , null , '\t' ) + \t , '\n' ) ; }


function (done) {
        fs.writeFile(
          path.resolve(__dirname, '../../test/reallife/source/' + item.key + '.html'),
          SOURCES[item.key],
          done
        );
      }

function ( done ) { fs . writeFile ( path . resolve ( __dirname , '../../test/reallife/source/' + item . key + '.html' ) , SOURCES [ item . key ] , done ) ; }


function (done) {
        datamap[item.index].labeled = true;

        fs.writeFile(
          path.resolve(__dirname, '../../test/reallife/datamap.json'),
          JSON.stringify(datamap, null, '\t') + '\n',
          done
        );
      }

function ( done ) { datamap [ item . index ] . labeled = true ; fs . writeFile ( path . resolve ( __dirname , '../../test/reallife/datamap.json' ) , JSON . stringify ( datamap , null , '\t' ) + \t , '\n' ) ; }


function Node(type, parent) {
  this.type = type;
  this.parent = parent;
  this.root = parent ? parent.root : this;
  this.identifyer = parent ? (++parent.root._counter) : 0;

  // The specific constructor will set another value if necessary
  this._textLength = 0;

  this.tags = 0;
  this.density = -1;

  this.children = [];

  this._text = '';
  this._textCompiled = false;
  this._noneStyleText = '';
  this._noneStyleTextCompiled = false;

  this.blocky = false;
  this.blockyChildren = false;

  this.inTree = true;
}

function Node ( type , parent ) { this . type = type ; this . parent = parent ; this . root = parent ? parent . root : this ; this . identifyer = parent ? ( ++ parent . root . _counter ) : 0 ; this . _textLength = 0 ; this . tags = 0 ; this . density = - 1 ; this . children = [ ] ; this . _text = '' ; this . _textCompiled = false ; this . _noneStyleText = '' ; this . _noneStyleTextCompiled = false ; this . blocky = false ; this . blockyChildren = false ; this . inTree = true ; }

Node General abstaction between all node types The rule is that this should contain the most obviouse implementation


function TextNode(parent, text) {
  Node.call(this, 'text', parent);

  // A text node has no children instead it has a text container
  this.children = null;
  this._text = text;
  this._noneStyleText = text;
}

function TextNode ( parent , text ) { Node . call ( this , 'text' , parent ) ; this . children = null ; this . _text = text ; this . _noneStyleText = text ; }

TextNode has a parent and a text containter


function ElementNode(parent, tagname, attributes) {
  Node.call(this, 'element', parent);

  // Since this is an element there will minimum one tag
  this.tags = (tagname === 'br' || tagname === 'wbr') ? 0 : 1;

  // Element nodes also has a tagname and an attribute collection
  this.tagname = tagname;
  this.attr = attributes;
  this.classes = attributes.hasOwnProperty('class') ?
    attributes['class'].trim().split(WHITE_SPACE) : [];

  // Add node to the classlist
  this.root.classlist.addNode(this);

  this._blockySelfCache = domHelpers.BLOCK_ELEMENTS.hasOwnProperty(tagname);
  this._countTagnames = {};
}

function ElementNode ( parent , tagname , attributes ) { Node . call ( this , 'element' , parent ) ; this . tags = ( tagname === 'br' || tagname === 'wbr' ) ? 0 : 1 ; this . tagname = tagname ; this . attr = attributes ; this . classes = attributes . hasOwnProperty ( 'class' ) ? attributes [ 'class' ] . trim ( ) . split ( WHITE_SPACE ) : [ ] ; this . root . classlist . addNode ( this ) ; this . _blockySelfCache = domHelpers . BLOCK_ELEMENTS . hasOwnProperty ( tagname ) ; this . _countTagnames = { } ; }

ElementNode has a parent, tagname and attributes

ElementNode has a parent tagname and attributes


function () {
            var r;

            // Recall as new if new isn't provided :)
            if( Util.isnt.instanceof( NewClass, this ) ) {
                return ClassUtil.construct( NewClass, arguments );
            }

            // call the constructor
            if ( Util.is.Function( this.initialize ) ) {
                r = this.initialize.apply(this, arguments);
            }

            // call all constructor hooks
            this.callInitHooks();

            return typeof r != 'undefined' ? r : this;
        }

function ( ) { var r ; if ( Util . isnt . instanceof ( NewClass , this ) ) { return ClassUtil . construct ( NewClass , arguments ) ; } if ( Util . is . Function ( this . initialize ) ) { r = this . initialize . apply ( this , arguments ) ; } this . callInitHooks ( ) ; return typeof r != 'undefined' ? r : this ; }


function distribute(filename, content){
    content = content;
    fs.appendFile(filename, content + "\n");
    log(rulecount + ': Append to ' + filename + ' -> ' + content);
  }

function distribute ( filename , content ) { content = content ; fs . appendFile ( filename , content + "\n" ) ; \n }

Distribute content to the cssfiles object


function detectTakeout(selectors){
    var properties = {
      takeout: false
    };

    options.takeout.forEach(function (takeout) {
      selectors.forEach(function (selector) {
        if (selector.indexOf(takeout.ruleprefix) === 0) {
          properties.takeout = true;
          properties.filename = takeout.filename;
        }
      });
    });

    return properties;
  }

function detectTakeout ( selectors ) { var properties = { takeout : false } ; options . takeout . forEach ( function ( takeout ) { selectors . forEach ( function ( selector ) { if ( selector . indexOf ( takeout . ruleprefix ) === 0 ) { properties . takeout = true ; properties . filename = takeout . filename ; } } ) ; } ) ; return properties ; }

Detect weather a selector should be extracted or not


function parseLineByLine(text) {
    var lines = text.trim().split("\n");
    var bookmarks = lines.splice(0, lines.length * 3 / 4);
    return {
        bookmarks: bookmarks,
        lines: lines
    };
}

function parseLineByLine ( text ) { var lines = text . trim ( ) . split ( "\n" ) ; \n var bookmarks = lines . splice ( 0 , lines . length * 3 / 4 ) ; }

create tuple that
@param text
@returns {{bookmarks: string[], lines: string[]}}


function CommonalityInterface(MatrixConstructor, top) {
  this.top = top;
  this.length = null;
  this.matrix = null;

  this.MatrixConstructor = MatrixConstructor;
}

function CommonalityInterface ( MatrixConstructor , top ) { this . top = top ; this . length = null ; this . matrix = null ; this . MatrixConstructor = MatrixConstructor ; }


function CommanalityMatrix(classlist) {
  // space will identify a text node and/or an element node without any classnames
  this.rowKeys = {};
  this.rowNames = [];

  this.collumKeys = {};
  this.collumNames = [];

  this.nodeMatrix = [];
  this.summaryMatrix = [];

  this.dim = [0, 0];

  this.bestIndex = [-1, -1];
  this._bestNodes = {};
}

function CommanalityMatrix ( classlist ) { this . rowKeys = { } ; this . rowNames = [ ] ; this . collumKeys = { } ; this . collumNames = [ ] ; this . nodeMatrix = [ ] ; this . summaryMatrix = [ ] ; this . dim = [ 0 , 0 ] ; this . bestIndex = [ - 1 , - 1 ] ; this . _bestNodes = { } ; }

Some abstact API for the commanality matrix


function arrayVector(size) {
  var vec = new Array(size);
  for (var i = 0; i < size; i++) vec[i] = [];
  return vec;
}

function arrayVector ( size ) { var vec = new Array ( size ) ; for ( var i = 0 ; i < size ; i ++ ) vec [ i ] = [ ] ; return vec ; }


function buildAttributeMatcher(match) {
  var keys = Object.keys(match);
  var jskey, i, l;

  var transform = '';
  var bool = '';

  transform = 'transform = {\n';
  for (i = 0, l = keys.length; i < l; i++) {
    jskey = JSON.stringify(keys[i]);

    transform += '  ' + jskey + ': attr.hasOwnProperty(' + jskey + ') ? attr[' + jskey + '].toLowerCase() : false';
    if (i !== l - 1) transform += ',';
    transform += '\n';
  }
  transform += '};\n';

  bool = 'return !!(';
  for (i = 0, l = keys.length; i < l; i++) {
    jskey = JSON.stringify(keys[i]);

    if (i > 0) bool += '    ||    ';
    bool += ' ( transform[' + jskey + ']';

    if (Array.isArray(match[keys[i]])) {
      bool += ' && ( ';

      for (var j = 0, s = match[keys[i]].length; j < s; j++) {
        if (j > 0) bool += ' || ';

        if (typeof match[keys[i]][j] === 'string') {
          bool += 'transform[' + jskey + '] === \'' + match[keys[i]][j].toLowerCase() + '\'';
        } else if (util.isRegExp(match[keys[i]][j])) {
          bool += 'match[' + jskey + '][' + j + '].test(transform[' + jskey + '])';
        }
      }

      bool += ' )';
    }

    bool += ' ) \n';
  }

  bool += '         );';

  var anonymous = new Function('attr', 'match', transform + '\n' + bool);
  return function (attr) {
    return anonymous(attr, match);
  };
}

function
buildAttributeMatcher
(
match
)
{
var
keys
=
Object
.
keys
(
match
)
;
var
jskey
,
i
,
l
;
var
transform
=
''
;
var
bool
=
''
;
transform
=
'transform = {\n'
;
\n
for
(
i
=
0
,
l
=
keys
.
length
;
i
<
l
;
i
++
)
{
jskey
=
JSON
.
stringify
(
keys
[
i
]
)
;
transform
+=
'  '
+
jskey
+
': attr.hasOwnProperty('
+
jskey
+
') ? attr['
+
jskey
+
'].toLowerCase() : false'
;
if
(
i
!==
l
1
)
transform
+=
','
;
transform
+=
'\n'
;
}
\n
transform
+=
'};\n'
;
\n
bool
=
'return !!('
;
for
(
i
=
0
,
l
=
keys
.
length
;
i
<
l
;
i
++
)
{
jskey
=
JSON
.
stringify
(
keys
[
i
]
)
;
if
(
i
>
0
)
bool
+=
'    ||    '
;
bool
+=
' ( transform['
+
jskey
+
']'
;
if
(
Array
.
isArray
(
match
[
keys
[
i
]
]
)
)
{
bool
+=
' && ( '
;
for
(
var
j
=
0
,
s
=
match
[
keys
[
i
]
]
.
length
;
j
<
s
;
j
++
)
{
if
(
j
>
0
)
bool
+=
' || '
;
if
(
typeof
match
[
keys
[
i
]
]
[
j
]
===
'string'
)
{
bool
+=
'transform['
+
jskey
+
'] === \''
+
\'
+
match
[
keys
[
i
]
]
[
j
]
.
toLowerCase
(
)
;
}
else
'\''
}
\'
}
if
(
util
.
isRegExp
(
match
[
keys
[
i
]
]
[
j
]
)
)
{
bool
+=
'match['
+
jskey
+
']['
+
j
+
'].test(transform['
+
jskey
+
'])'
;
}
}
}

Builds and attribute matching function, complexity is for uncomfirmed performace sake

Builds and attribute matching function complexity is for uncomfirmed performace sake


function containerOf(a, b) {
  while (b = b.parent) {
    if (a === b) return true;
  }
  return false;
}

function containerOf ( a , b ) { while ( b = b . parent ) { if ( a === b ) return true ; } return false ; }

Checks if container `a` is a container of `b`

Checks if container a is a container of b


function commonParent(a, b) {
  if (a === b) {
    return a;
  } else if (containerOf(a, b)) {
    return a;
  } else if (containerOf(b, a)) {
    return b;
  } else {
    // This will happen at some point, since the root is a container of
    // everything
    while (b = b.parent) {
      if (containerOf(b, a)) return b;
    }
  }
}

function commonParent ( a , b ) { if ( a === b ) { return a ; } else if ( containerOf ( a , b ) ) { return a ; } else if ( containerOf ( b , a ) ) { return b ; } else { while ( b = b . parent ) { if ( containerOf ( b , a ) ) return b ; } } }


function styleParser(style) {
  style = style || '';

  var tokens = style.trim().split(/\s*(?:;|:)\s*/);
  var output = {};
  for (var i = 1, l = tokens.length; i < l; i += 2) {
    output[tokens[i - 1]] = tokens[i];
  }
  return output;
}

function styleParser ( style ) { style = style || '' ; var tokens = style . trim ( ) . split ( / \s*(?:;|:)\s* / ) ; var output = { } ; for ( var i = 1 , l = tokens . length ; i < l ; i += 2 ) { output [ tokens [ i - 1 ] ] = tokens [ i ] ; } return output ; }


function treeDistance(a, b) {
  if (a === b) return 0;
  var parent = commonParent(a, b);

  var aParent = a;
  var aCount = 0;

  var bParent = b;
  var bCount = 0;

  if (parent !== a) {
    while (parent !== aParent.parent) {
      aCount += 1;
      aParent = aParent.parent;
    }
  } else {
    bCount += 1;
  }

  if (parent !== b) {
    while (parent !== bParent.parent) {
      bCount += 1;
      bParent = bParent.parent;
    }
  } else {
    aCount += 1;
  }

  var abCount = 0;
  if (parent !== a && parent !== b) {
    abCount = Math.abs(
      parent.children.indexOf(aParent) - parent.children.indexOf(bParent)
    );
  }

  return aCount + bCount + abCount;
}

function treeDistance ( a , b ) { if ( a === b ) return 0 ; var parent = commonParent ( a , b ) ; var aParent = a ; var aCount = 0 ; var bParent = b ; var bCount = 0 ; if ( parent !== a ) { while ( parent !== aParent . parent ) { aCount += 1 ; aParent = aParent . parent ; } } else { bCount += 1 ; } if ( parent !== b ) { while ( parent !== bParent . parent ) { bCount += 1 ; bParent = bParent . parent ; } } else { aCount += 1 ; } var abCount = 0 ; if ( parent !== a && parent !== b ) { abCount = Math . abs ( parent . children . indexOf ( aParent ) - parent . children . indexOf ( bParent ) ) ; } return aCount + bCount + abCount ; }

Calculate the tree distance between a and b


function Lexer(file, options) {
  this.options = utils.extend({}, options);
  this.file = file;
  this.regex = new RegexCache();
  this.names = [];
  this.ast = {
    tags: {},
    type: 'root',
    name: 'root',
    nodes: []
  };

  this.unknown = {tags: [], blocks: []};
  this.known = {
    tags: ['extends', 'layout'],
    blocks: ['block']
  };

  this.delimiters = {
    variable: ['{{', '}}'],
    block: ['{%', '%}'],
    es6: ['${', '}'],
  };

  this.tokens = [this.ast];
  this.errors = [];
  this.stack = [];
  this.stash = [];
  this.lexers = {};
  this.fns = [];
}

function Lexer ( file , options ) { this . options = utils . extend ( { } , options ) ; this . file = file ; this . regex = new RegexCache ( ) ; this . names = [ ] ; this . ast = { tags : { } , type : 'root' , name : 'root' , nodes : [ ] } ; this . unknown = { tags : [ ] , blocks : [ ] } ; this . known = { tags : [ 'extends' , 'layout' ] , blocks : [ 'block' ] } ; this . delimiters = { variable : [ '{{' , '}}' ] , block : [ '{%' , '%}' ] , es6 : [ '${' , '}' ] , } ; this . tokens = [ this . ast ] ; this . errors = [ ] ; this . stack = [ ] ; this . stash = [ ] ; this . lexers = { } ; this . fns = [ ] ; }

Create a new `Lexer` for the given `file` and `options`.
@param {object} `file`
@param {object} `options`

Create a new Lexer for the given file and options .


function() {
    if (this.isInitialized) return;

    this.isInitialized = true;
    var lexer = this;
    this.lineno = 1;
    this.column = 1;
    this.lexed = '';

    this.file = utils.normalize(this.file);
    this.file.orig = this.file.contents;
    this.input = this.file.contents.toString();
    this.file.ast = this.ast;
    this.file.ast.variables = {};
    this.file.ast.blocks = {};

    this.input = this.input.split('{% body %}')
      .join('{% block "body" %}{% endblock %}');

    if (this.file.extends) {
      this.prependNode(this.file, 'extends');
    }

    /**
     * Tags
     */
    this.captureTag('extends');
    this.captureTag('layout');

    /**
     * Block tags
     */
    this.captureBlock('block');

    /**
     * Captures
     */

    this.capture('text', utils.negateDelims(this.delimiters));
    this.capture('newline', /^\n+/);
    this.capture('es6', /^\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/);
    this.capture('variable', /^\{{2,}([^\\}]*(?:\\.[^\\}]*)*)\}{2,}/);
    this.capture('escape', /^\\(.)/);
    this.capture('space', /^[ \t]+/);

    /**
     * Custom helpers
     */
    var helpers = this.options.helpers || {};
    if (utils.isObject(helpers)) {
      helpers = Object.keys(helpers);
    }

    helpers.forEach(function(key) {
      lexer.known.blocks.push(key);
      lexer.captureBlock(key);
    });

    /**
     * Add other names to return un-rendered
     */

    var matches = this.input.match(/\{%\s*([^%}]+)/g);
    var names = utils.getNames(matches);

    names.tags.forEach(function(key) {
      if (!utils.isRegistered(lexer, key)) {
        lexer.unknown.tags.push(key);
        lexer.captureTag(key);
      }
    });

    names.blocks.forEach(function(key) {
      if (!utils.isRegistered(lexer, key)) {
        lexer.unknown.blocks.push(key);
        lexer.captureBlock(key);
      }
    });
  }

function
(
)
{
if
(
this
.
isInitialized
)
return
;
this
.
isInitialized
=
true
;
var
lexer
=
this
;
this
.
lineno
=
1
;
this
.
column
=
1
;
this
.
lexed
=
''
;
this
.
file
=
utils
.
normalize
(
this
.
file
)
;
this
.
file
.
orig
=
this
.
file
.
contents
;
this
.
input
=
this
.
file
.
contents
.
toString
(
)
;
this
.
file
.
ast
=
this
.
ast
;
this
.
file
.
ast
.
variables
=
{
}
;
this
.
file
.
ast
.
blocks
=
{
}
;
this
.
input
=
this
.
input
.
split
(
'{% body %}'
)
.
join
(
'{% block "body" %}{% endblock %}'
)
;
if
(
this
.
file
.
extends
)
{
this
.
prependNode
(
this
.
file
,
'extends'
)
;
}
this
.
captureTag
(
'extends'
)
;
this
.
captureTag
(
'layout'
)
;
this
.
captureBlock
(
'block'
)
;
this
.
capture
(
'text'
,
utils
.
negateDelims
(
this
.
delimiters
)
)
;
this
.
capture
(
'newline'
,
/
^\n+
/
)
;
this
.
capture
(
'es6'
,
/
^\$\{([^\\}]*(?:\\.[^\\}]*)*)\}
/
)
;
this
.
capture
(
'variable'
,
/
^\{{2,}([^\\}]*(?:\\.[^\\}]*)*)\}{2,}
/
)
;
this
.
capture
(
'escape'
,
/
^\\(.)
/
)
;
this
.
capture
(
'space'
,
/
^[ \t]+
/
)
;
var
helpers
=
this
.
options
.
helpers
||
{
}
;
if
(
utils
.
isObject
(
helpers
)
)
{
helpers
=
Object
.
keys
(
helpers
)
;
}
helpers
.
forEach
(
function
(
key
)
{
lexer
.
known
.
blocks
.
push
(
key
)
;
lexer
.
captureBlock
(
key
)
;
}
)
;
var
matches
=
this
.
input
.
match
(
/
\{%\s*([^%}]+)
/
g
)
;
var
names
=
utils
.
getNames
(
matches
)
;
names
.
tags
.
forEach
(
function
(
key
)
{
if
(
!
utils
.
isRegistered
(
lexer
,
key
)
)
{
lexer
.
unknown
.
tags
.
push
(
key
)
;
lexer
.
captureTag
(
key
)
;
}
}
)
;
names
.
blocks
.
forEach
(
function
(
key
)
{
if
(
!
utils
.
isRegistered
(
lexer
,
key
)
)
{
lexer
.
unknown
.
blocks
.
push
(
key
)
;
lexer
.
captureBlock
(
key
)
;
}
}
)
;
}


function(msg) {
    var message = this.file.relative
      + ' line:' + this.lineno
      + ' column:' + this.column
      + ': ' + msg;

    var err = new Error(message);
    err.reason = msg;
    err.line = this.lineno;
    err.column = this.column;
    err.source = this.input;
    err.path = this.file.path;

    if (this.options.silent) {
      this.errors.push(err);
    } else {
      throw err;
    }
  }

function
(
msg
)
{
var
message
=
this
.
file
.
relative
+
' line:'
+
this
.
lineno
+
' column:'
+
this
.
column
+
': '
+
msg
;
var
err
=
new
Error
(
message
)
;
err
.
reason
=
msg
;
err
.
line
=
this
.
lineno
;
err
.
column
=
this
.
column
;
err
.
source
=
this
.
input
;
err
.
path
=
this
.
file
.
path
;
if
(
this
.
options
.
silent
)
{
this
.
errors
.
push
(
err
)
;
}
else
{
throw
err
;
}
}

Set an error message with the current line number and column.
@param {String} `msg` Message to use in the Error.

Set an error message with the current line number and column .


function(type) {
    var cached = this.regex.createVariable(type);
    var file = this.file;
    var lexer = this;

    var fn = this.lexers[type] = function() {
      var pos = lexer.position();
      var m = lexer.match(cached.strict);
      if (!m) return;

      var parent = this.prev();
      var node = pos({
        type: type,
        known: utils.has(lexer.known.tags, type),
        val: m[0].trim()
      });

      parent.known = node.known;
      var nodes = parent.nodes;

      Object.defineProperty(file.ast.variables, type, {
        configurable: true,
        set: function(val) {
          nodes = val;
        },
        get: function() {
          return nodes;
        }
      });

      Object.defineProperty(parent, 'nodes', {
        configurable: true,
        set: function(val) {
          nodes = val;
        },
        get: function() {
          return nodes;
        }
      });

      utils.define(node, 'parent', parent);
      parent.nodes.push(node);
    };

    this.addLexer(fn);
    return this;
  }

function ( type ) { var cached = this . regex . createVariable ( type ) ; var file = this . file ; var lexer = this ; var fn = this . lexers [ type ] = function ( ) { var pos = lexer . position ( ) ; var m = lexer . match ( cached . strict ) ; if ( ! m ) return ; var parent = this . prev ( ) ; var node = pos ( { type : type , known : utils . has ( lexer . known . tags , type ) , val : m [ 0 ] . trim ( ) } ) ; parent . known = node . known ; var nodes = parent . nodes ; Object . defineProperty ( file . ast . variables , type , { configurable : true , set : function ( val ) { nodes = val ; } , get : function ( ) { return nodes ; } } ) ; Object . defineProperty ( parent , 'nodes' , { configurable : true , set : function ( val ) { nodes = val ; } , get : function ( ) { return nodes ; } } ) ; utils . define ( node , 'parent' , parent ) ; parent . nodes . push ( node ) ; } ; this . addLexer ( fn ) ; return this ; }

Create a lexer for the given variable `type`.
@param {String} `type`
@return {Function}

Create a lexer for the given variable type .


function(type) {
    this.ast.tags[type] = null;
    this.names.push(type);

    var cached = this.regex.createTag(type);
    var file = this.file;
    var lexer = this;

    var fn = this.lexers[type] = function() {
      var pos = lexer.position();
      var m = lexer.match(cached.strict);
      if (!m) return;

      var name = utils.getName(m[1]);
      if (this.options.strict) {
        var isKnown = utils.has(lexer.known.tags, type);
        if (isKnown && file.hasOwnProperty(type) && !file.hasOwnProperty('isParsed')) {
          throw new Error(`only one "${type}" tag may be defined per template`);
        }
      }

      file[type] = name;
      lexer.ast.tags[type] = name;
      lexer.createNode(type, name, m, pos);
    };

    this.addLexer(fn);
    return this;
  }

function ( type ) { this . ast . tags [ type ] = null ; this . names . push ( type ) ; var cached = this . regex . createTag ( type ) ; var file = this . file ; var lexer = this ; var fn = this . lexers [ type ] = function ( ) { var pos = lexer . position ( ) ; var m = lexer . match ( cached . strict ) ; if ( ! m ) return ; var name = utils . getName ( m [ 1 ] ) ; if ( this . options . strict ) { var isKnown = utils . has ( lexer . known . tags , type ) ; if ( isKnown && file . hasOwnProperty ( type ) && ! file . hasOwnProperty ( 'isParsed' ) ) { throw new Error ( ` ${ type } ` ) ; } } file [ type ] = name ; lexer . ast . tags [ type ] = name ; lexer . createNode ( type , name , m , pos ) ; } ; this . addLexer ( fn ) ; return this ; }

Create a tag lexer for the given `type`.
@param {String} `type`
@return {Function}


function(type, name, m, pos) {
    var parent = this.prev();
    var val = m[1];
    var tok = { type: 'args', val: val };

    var node = pos({
      type: type,
      name: name,
      known: utils.has(this.known.tags, type),
      val: val.trim(),
      nodes: [tok]
    });

    utils.define(node, 'parent', parent);
    utils.define(tok, 'parent', node);
    parent.nodes.push(node);
  }

function ( type , name , m , pos ) { var parent = this . prev ( ) ; var val = m [ 1 ] ; var tok = { type : 'args' , val : val } ; var node = pos ( { type : type , name : name , known : utils . has ( this . known . tags , type ) , val : val . trim ( ) , nodes : [ tok ] } ) ; utils . define ( node , 'parent' , parent ) ; utils . define ( tok , 'parent' , node ) ; parent . nodes . push ( node ) ; }

Push AST node `type` onto `parent.nodes`
@param {String} `type`
@param {String} `name`
@param {String} `val`
@param {Function} `pos`


function(type) {
    this.names.push(type);
    var cached = this.regex.createOpen(type);
    var file = this.file;
    var lexer = this;

    return function() {
      var pos = lexer.position();
      var m = lexer.match(cached.strict);
      if (!m) return;

      var name = utils.getName(m[1]);
      var action = utils.getAction(m[1]);
      var val = m[0];

      if (!name && lexer.options[type] && lexer.options[type].args === 'required') {
        throw new Error(`no arguments defined on "${type}": ${m[0]}`);
      }

      if (!name) name = 'unnamed';
      var node = pos({
        type: `${type}.open`,
        known: utils.has(lexer.known.blocks, type),
        name: name,
        val: val.trim()
      });

      var parent = lexer.prev();
      if (parent && parent.name && parent.name !== 'root') {
        name = parent.name + '.' + name;
      }

      var block = {
        type: type,
        name: name,
        known: node.known,
        action: action,
        nodes: [node]
      };

      utils.define(node, 'parent', block);
      utils.define(block, 'parent', parent);
      block.rawArgs = m[1];
      block.args = utils.parseArgs(m[1]);

      Object.defineProperty(file.ast.blocks[type], name, {
        configurable: true,
        enumerable: true,
        set: function(val) {
          block = val;
        },
        get: function() {
          return block;
        }
      });

      parent.nodes.push(block);
      lexer.tokens.push(block);
      return block;
    };
  }

function ( type ) { this . names . push ( type ) ; var cached = this . regex . createOpen ( type ) ; var file = this . file ; var lexer = this ; return function ( ) { var pos = lexer . position ( ) ; var m = lexer . match ( cached . strict ) ; if ( ! m ) return ; var name = utils . getName ( m [ 1 ] ) ; var action = utils . getAction ( m [ 1 ] ) ; var val = m [ 0 ] ; if ( ! name && lexer . options [ type ] && lexer . options [ type ] . args === 'required' ) { throw new Error ( ` ${ type } ${ m [ 0 ] } ` ) ; } if ( ! name ) name = 'unnamed' ; var node = pos ( { type : ` ${ type } ` , known : utils . has ( lexer . known . blocks , type ) , name : name , val : val . trim ( ) } ) ; var parent = lexer . prev ( ) ; if ( parent && parent . name && parent . name !== 'root' ) { name = parent . name + '.' + name ; } var block = { type : type , name : name , known : node . known , action : action , nodes : [ node ] } ; utils . define ( node , 'parent' , block ) ; utils . define ( block , 'parent' , parent ) ; block . rawArgs = m [ 1 ] ; block . args = utils . parseArgs ( m [ 1 ] ) ; Object . defineProperty ( file . ast . blocks [ type ] , name , { configurable : true , enumerable : true , set : function ( val ) { block = val ; } , get : function ( ) { return block ; } } ) ; parent . nodes . push ( block ) ; lexer . tokens . push ( block ) ; return block ; } ; }

Create an opening tag lexer for block `name`.
@param {String} `name`
@return {Function}

Create an opening tag lexer for block name .


function(type) {
    var cached = this.regex.createClose(type);
    var file = this.file;
    var lexer = this;

    return function() {
      var pos = lexer.position();
      var m = lexer.match(cached.strict);
      if (!m) return;

      var block = lexer.tokens.pop();
      if (typeof block === 'undefined' || block.type !== type) {
        throw new Error(`missing opening ${type}`);
      }

      if (block.name === 'body') {
        lexer.ast.isLayout = true;
        file.ast.isLayout = true;
      }

      var nodes = block.nodes;
      Object.defineProperty(file.ast.blocks, block.name, {
        configurable: true,
        set: function(val) {
          nodes = val;
        },
        get: function() {
          return nodes;
        }
      });

      Object.defineProperty(block, 'nodes', {
        configurable: true,
        set: function(val) {
          nodes = val;
        },
        get: function() {
          return nodes;
        }
      });

      var tok = pos({
        known: block.known,
        type: `${type}.close`,
        val: m[0].trim()
      });

      utils.define(block, 'position', tok.position);
      utils.define(tok, 'parent', block);
      block.nodes.push(tok);
      return block;
    };
  }

function ( type ) { var cached = this . regex . createClose ( type ) ; var file = this . file ; var lexer = this ; return function ( ) { var pos = lexer . position ( ) ; var m = lexer . match ( cached . strict ) ; if ( ! m ) return ; var block = lexer . tokens . pop ( ) ; if ( typeof block === 'undefined' || block . type !== type ) { throw new Error ( ` ${ type } ` ) ; } if ( block . name === 'body' ) { lexer . ast . isLayout = true ; file . ast . isLayout = true ; } var nodes = block . nodes ; Object . defineProperty ( file . ast . blocks , block . name , { configurable : true , set : function ( val ) { nodes = val ; } , get : function ( ) { return nodes ; } } ) ; Object . defineProperty ( block , 'nodes' , { configurable : true , set : function ( val ) { nodes = val ; } , get : function ( ) { return nodes ; } } ) ; var tok = pos ( { known : block . known , type : ` ${ type } ` , val : m [ 0 ] . trim ( ) } ) ; utils . define ( block , 'position' , tok . position ) ; utils . define ( tok , 'parent' , block ) ; block . nodes . push ( tok ) ; return block ; } ; }

Create a closing tag lexer for block `name`.
@param {String} `name`
@return {Function}

Create a closing tag lexer for block name .


function(type) {
    this.file.ast.blocks[type] = this.file.ast.blocks[type] || {};
    this.addLexer(this.captureOpen(type));
    this.addLexer(this.captureClose(type));
    return this;
  }

function ( type ) { this . file . ast . blocks [ type ] = this . file . ast . blocks [ type ] || { } ; this . addLexer ( this . captureOpen ( type ) ) ; this . addLexer ( this . captureClose ( type ) ) ; return this ; }

Create a block lexer with opening and closing tags for the given `name`.
@param {String} `name`
@return {Function}

Create a block lexer with opening and closing tags for the given name .


function(file, prop) {
    return this.createNode(prop, file[prop], `{% ${prop} "${file[prop]}" %}`, this.position());
  }

function ( file , prop ) { return this . createNode ( prop , file [ prop ] , ` ${ prop } ${ file [ prop ] } ` , this . position ( ) ) ; }


function(str, len) {
    var lines = str.match(/\n/g);
    if (lines) this.lineno += lines.length;
    var i = str.lastIndexOf('\n');
    this.column = ~i ? len - i : this.column + len;
    this.lexed += str;
    this.consume(str, len);
  }

function ( str , len ) { var lines = str . match ( / \n / g ) ; if ( lines ) this . lineno += lines . length ; var i = str . lastIndexOf ( '\n' ) ; \n this . column = ~ i ? len - i : this . column + len ; this . lexed += str ; }

Update lineno and column based on `str`.


function() {
    var len = this.fns.length;
    var idx = -1;
    while (++idx < len) {
      this.fns[idx].call(this);
      if (!this.input) {
        break;
      }
    }
  }

function ( ) { var len = this . fns . length ; var idx = - 1 ; while ( ++ idx < len ) { this . fns [ idx ] . call ( this ) ; if ( ! this . input ) { break ; } } }

Run lexers to advance the curson position


function() {
    while (this.input) {
      var prev = this.input;
      this.advance();
      if (this.input && prev === this.input) {
        throw new Error(`no lexers registered for: "${this.input.substr(0, 10)}"`);
      }
    }
  }

function ( ) { while ( this . input ) { var prev = this . input ; this . advance ( ) ; if ( this . input && prev === this . input ) { throw new Error ( ` ${ this . input . substr ( 0 , 10 ) } ` ) ; } } }


function(file) {
    debug('lexing <%s>', this.file.path);
    if (file) this.file = file;
    this.init();
    while (this.input) this.next();
    return this.ast;
  }

function
(
file
)
{
debug
(
'lexing <%s>'
,
this
.
file
.
path
)
;
if
(
file
)
this
.
file
=
file
;
this
.
init
(
)
;
while
(
this
.
input
)
this
.
next
(
)
;
return
this
.
ast
;
}

Tokenize the given string.
@return {Array}


function notifyHook(e) {

    message_count++;

    var message;

    if (!options.enabled) {
      return;
    }

    if (!e) {
      return;
    }

    if (e && e.length === 1) {
      e = e[0];
    }

    if (/Task .* failed\./.test(e.message)) {
      message = e.message;
    } else if (e.message && e.stack) {
      message = exception(e);
    } else {
      message = e + '';
    }

    if (message_count > 0 && message === 'Aborted due to warnings.') {
      // skip unhelpful message because there was probably another one that was more helpful
      return;
    }

    // shorten message by removing full path
    // TODO - make a global replace
    message = message.replace(cwd, '').replace('\x07', '');

    return notify({
      title:    options.title + (grunt.task.current.nameArgs ? ' ' + grunt.task.current.nameArgs : ''),
      message:  message
    });
  }

function
notifyHook
(
e
)
{
message_count
++
;
var
message
;
if
(
!
options
.
enabled
)
{
return
;
}
if
(
!
e
)
{
return
;
}
if
(
e
&&
e
.
length
===
1
)
{
e
=
e
[
0
]
;
}
if
(
/
Task .* failed\.
/
.
test
(
e
.
message
)
)
{
message
=
e
.
message
;
}
else
if
(
e
.
message
&&
e
.
stack
)
{
message
=
exception
(
e
)
;
}
else
{
message
=
e
+
''
;
}
if
(
message_count
>
0
&&
message
===
'Aborted due to warnings.'
)
{
return
;
}
message
=
message
.
replace
(
cwd
,
''
)
.
replace
(
'\x07'
,
\x07
)
;
''
}

Hook for showing the automatic message
@param e Exception or message
@returns {*}


function() {
    if (this._initialized && this._isPaused) {
      return false;
    }

    this._isPaused = true;
    raf.cancel(this._requestID);

    this._pauseTime = now();
    this._onPause();

    return true;
  }

function ( ) { if ( this . _initialized && this . _isPaused ) { return false ; } this . _isPaused = true ; raf . cancel ( this . _requestID ) ; this . _pauseTime = now ( ) ; this . _onPause ( ) ; return true ; }


function() {
    if (this._initialized && !this._isPaused) {
      return false;
    }

    var pauseDuration;

    this._isPaused = false;
    this._prevTime = now();

    pauseDuration = this._prevTime - this._pauseTime;
    this._onResume(pauseDuration);

    this._requestID = raf.request(this._tick);

    return true;
  }

function ( ) { if ( this . _initialized && ! this . _isPaused ) { return false ; } var pauseDuration ; this . _isPaused = false ; this . _prevTime = now ( ) ; pauseDuration = this . _prevTime - this . _pauseTime ; this . _onResume ( pauseDuration ) ; this . _requestID = raf . request ( this . _tick ) ; return true ; }


function mktmpdir(prefixSuffix, tmpdir, callback, onend) {
  if ('function' == typeof prefixSuffix) {
    onend = tmpdir;
    callback = prefixSuffix;
    tmpdir = null;
    prefixSuffix = null;
  } else if ('function' == typeof tmpdir) {
    onend = callback;
    callback = tmpdir;
    tmpdir = null;
  }

  prefixSuffix = prefixSuffix || 'd';
  onend = onend || function() {};

  tmpname.create(prefixSuffix, tmpdir, function(err, path, next) {
    if (err) return callback(err);

    fs.mkdir(path, 0700, next);
  }, function(err, path) {
    if (err) return callback(err);

    callback(null, path, function(err) {
      if (!path) return onend(err);

      rimraf(path, function(_err) {
        onend(err || _err, path);
      });
    });
  });
}

function mktmpdir ( prefixSuffix , tmpdir , callback , onend ) { if ( 'function' == typeof prefixSuffix ) { onend = tmpdir ; callback = prefixSuffix ; tmpdir = null ; prefixSuffix = null ; } else if ( 'function' == typeof tmpdir ) { onend = callback ; callback = tmpdir ; tmpdir = null ; } prefixSuffix = prefixSuffix || 'd' ; onend = onend || function ( ) { } ; tmpname . create ( prefixSuffix , tmpdir , function ( err , path , next ) { if ( err ) return callback ( err ) ; fs . mkdir ( path , 0700 , next ) ; } , function ( err , path ) { if ( err ) return callback ( err ) ; callback ( null , path , function ( err ) { if ( ! path ) return onend ( err ) ; rimraf ( path , function ( _err ) { onend ( err || _err , path ) ; } ) ; } ) ; } ) ; }

Creates a temporary directory.

The directory is created with 0700 permission.
Application should not change the permission to make the temporary directory accessible from other users.

The prefix and suffix of the name of the directory is specified by
the optional first argument, prefixSuffix.
- If it is not specified or null, "d" is used as the prefix and no suffix is used.
- If it is a string, it is used as the prefix and no suffix is used.
- If it is an array, first element is used as the prefix and second element is used as a suffix.

mktmpdir(function(err, dir) { dir is ".../d..." });
mktmpdir('foo', function(err, dir) { dir is ".../foo..." });
mktmpdir(['foo', 'bar'], function(err, dir) { dir is ".../foo...bar" });

The directory is created under os.tmpdir() or
the optional second argument tmpdir if non-null value is given.

mktmpdir(function(err, dir) { dir is os.tmpdir() + "/d..." });
mktmpdir(null, '/var/tmp', function(err, dir) { dir is "/var/tmp/d..." });

If a callback is invoked,
the path of the directory and its contents are removed.

mktmpdir(function(err, dir, done) {
if (err) throw err;
// use the directory...
fs.open(dir + '/foo', 'w', function(err, fd) {
done(err);
});
}, function(err) {
// the directory has been removed.
});

If a callback is not invoked, mktmpdir doesn't remove the directory.

mktmpdir(function(err, dir) {
if (err) throw err;
// use the directory...
fs.open(dir + '/foo', 'w', function(err, fd) {
// remove the directory.
exec('rm -rf ' + dir);
});
});

@param {String|Array} prefix, or an array including prefix and suffix.
@param {String} base tmpdir
@param {Function} callback
@param {Function} onend
@api public


function copyString(buffer, length, offsetBegin, offsetEnd) {
  if (length > 2048) {
    return buffer.toString('utf-8', offsetBegin, offsetEnd);
  }

  var string = '';
  while(offsetBegin < offsetEnd) {
    string += String.fromCharCode(buffer[offsetBegin++]);
  }
  return string;
}

function copyString ( buffer , length , offsetBegin , offsetEnd ) { if ( length > 2048 ) { return buffer . toString ( 'utf-8' , offsetBegin , offsetEnd ) ; } var string = '' ; while ( offsetBegin < offsetEnd ) { string += String . fromCharCode ( buffer [ offsetBegin ++ ] ) ; } return string ; }


function parseSimpleString(parser) {
  var offset = parser.offset;
  var length = parser.buffer.length;
  var string = '';

  while (offset < length) {
    var c1 = parser.buffer[offset++];
    if (c1 === 13) {
      var c2 = parser.buffer[offset++];
      if (c2 === 10) {
        parser.offset = offset;
        return string;
      }
      string += String.fromCharCode(c1) + String.fromCharCode(c2);
      continue;
    }
    string += String.fromCharCode(c1);
  }
  return undefined;
}

function parseSimpleString ( parser ) { var offset = parser . offset ; var length = parser . buffer . length ; var string = '' ; while ( offset < length ) { var c1 = parser . buffer [ offset ++ ] ; if ( c1 === 13 ) { var c2 = parser . buffer [ offset ++ ] ; if ( c2 === 10 ) { parser . offset = offset ; return string ; } string += String . fromCharCode ( c1 ) + String . fromCharCode ( c2 ) ; continue ; } string += String . fromCharCode ( c1 ) ; } return undefined ; }


function getBaseConfig(isProd) {
  // get library details from JSON config
  const libraryEntryPoint = path.join('src', LIBRARY_DESC.entry);

  // generate webpack base config
  return {
    entry: [
      // "babel-polyfill",
      path.join(__dirname, libraryEntryPoint),
    ],
    output: {
      devtoolLineToLine: true,
      pathinfo: true,
    },
    module: {
      preLoaders: [
        {
          test: /\.js$/,
          exclude: /(node_modules|bower_components)/,
          loader: "eslint-loader",
        },
      ],
      loaders: [
        {
          exclude: /(node_modules|bower_components)/,
          loader: "babel-loader",
          plugins: [
            "transform-runtime",
          ],
          query: {
            presets: [
              "es2015",
              "stage-0",
              "stage-1",
              "stage-2",
            ],
            cacheDirectory: false,
          },
          test: /\.js$/,
        },
      ],
    },
    eslint: {
      configFile: './.eslintrc',
    },
    resolve: {
      root: path.resolve('./src'),
      extensions: ['', '.js'],
    },
    devtool: isProd ? "source-map"/* null*/ : "source-map"/* '#eval-source-map'*/,
    debug: !isProd,
    plugins: isProd ? [
      new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"production"' } }),
      new UglifyJsPlugin({
        compress: { warnings: true },
        minimize: true,
        sourceMap: true,
      }),
      // Prod plugins here
    ] : [
      new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"development"' } }),
      new UglifyJsPlugin({
        compress: { warnings: true },
        minimize: true,
        sourceMap: true,
      }),
      // Dev plugins here
    ],
  };
}

function getBaseConfig ( isProd ) { const libraryEntryPoint = path . join ( 'src' , LIBRARY_DESC . entry ) ; return { entry : [ path . join ( __dirname , libraryEntryPoint ) , ] , output : { devtoolLineToLine : true , pathinfo : true , } , module : { preLoaders : [ { test : / \.js$ / , exclude : / (node_modules|bower_components) / , loader : "eslint-loader" , } , ] , loaders : [ { exclude : / (node_modules|bower_components) / , loader : "babel-loader" , plugins : [ "transform-runtime" , ] , query : { presets : [ "es2015" , "stage-0" , "stage-1" , "stage-2" , ] , cacheDirectory : false , } , test : / \.js$ / , } , ] , } , eslint : { configFile : './.eslintrc' , } , resolve : { root : path . resolve ( './src' ) , extensions : [ '' , '.js' ] , } , devtool : isProd ? "source-map" : "source-map" , debug : ! isProd , plugins : isProd ? [ new webpack . DefinePlugin ( { 'process.env' : { NODE_ENV : '"production"' } } ) , new UglifyJsPlugin ( { compress : { warnings : true } , minimize : true , sourceMap : true , } ) , ] : [ new webpack . DefinePlugin ( { 'process.env' : { NODE_ENV : '"development"' } } ) , new UglifyJsPlugin ( { compress : { warnings : true } , minimize : true , sourceMap : true , } ) , ] , } ; }

Build base config
@param  {Boolean} isProd [description]
@return {[type]}         [description]


function postNotification(options, cb) {

  options.title = removeColor(options.title);
  options.message = removeColor(options.message);

  if (!options.message) {
    return cb && cb(!options.message && 'Message is required');
  }

  if (!notifyPlatform) {
    notifyPlatform = choosePlatform();
  }

  function resetPreviousTimer(newMessage) {
    previousMessage = newMessage;
    clearTimeout(previousMessageTimer);
    previousMessageTimer = setTimeout(function(){previousMessage = false;}, previousMessageTimeoutMS);
  }

  if (options.message === previousMessage) {
    resetPreviousTimer(options.message);
    if (typeof cb === 'function') {
            cb(err);
          }
    return;
  }

  resetPreviousTimer(options.message);

  options.debug = debug(notifyPlatform.name); //for debug logging

  return notifyPlatform.notify(options, function(err){
      if (err) {
        options.debug({
          return_code: err
        });
      }
      if (typeof cb === 'function') {
        cb(err);
      }
    });
}

function
postNotification
(
options
,
cb
)
{
options
.
title
=
removeColor
(
options
.
title
)
;
options
.
message
=
removeColor
(
options
.
message
)
;
if
(
!
options
.
message
)
{
return
cb
&&
cb
(
!
options
.
message
&&
'Message is required'
)
;
}
if
(
!
notifyPlatform
)
{
notifyPlatform
=
choosePlatform
(
)
;
}
function
resetPreviousTimer
(
newMessage
)
{
previousMessage
=
newMessage
;
clearTimeout
(
previousMessageTimer
)
;
previousMessageTimer
=
setTimeout
(
function
(
)
{
previousMessage
=
false
;
}
,
previousMessageTimeoutMS
)
;
}
if
(
options
.
message
===
previousMessage
)
{
resetPreviousTimer
(
options
.
message
)
;
if
(
typeof
cb
===
'function'
)
{
cb
(
err
)
;
}
return
;
}
resetPreviousTimer
(
options
.
message
)
;
options
.
debug
=
debug
(
notifyPlatform
.
name
)
;
return
notifyPlatform
.
notify
(
options
,
function
(
err
)
{
if
(
err
)
{
options
.
debug
(
{
return_code
:
err
}
)
;
}
if
(
typeof
cb
===
'function'
)
{
cb
(
err
)
;
}
}
)
;
}

Public function to notify
@param options - options.message is the only required value. title is recommended. subtitle is going overboard.
@param [cb] - optional callback. function(err, stdout, stderr)


function generateUsername(base) {
    base = base.toLowerCase();
    var entries = [];
    var finalName;
    return userDB.allDocs({startkey: base, endkey: base + '\uffff', include_docs: false})
      .then(function(results){
        if(results.rows.length === 0) {
          return BPromise.resolve(base);
        }
        for(var i=0; i<results.rows.length; i++) {
          entries.push(results.rows[i].id);
        }
        if(entries.indexOf(base) === -1) {
          return BPromise.resolve(base);
        }
        var num = 0;
        while(!finalName) {
          num++;
          if(entries.indexOf(base+num) === -1) {
            finalName = base + num;
          }
        }
        return BPromise.resolve(finalName);
      });
  }

function generateUsername ( base ) { base = base . toLowerCase ( ) ; var entries = [ ] ; var finalName ; return userDB . allDocs ( { startkey : base , endkey : base + '\uffff' , \uffff } ) . include_docs : false then ; }

Adds numbers to a base name until it finds a unique database key


function linkSuccess(req, res, next) {
    var provider = getProvider(req.path);
    var result = {
      error: null,
      session: null,
      link: provider
    };
    var template;
    if(config.getItem('testMode.oauthTest')) {
      template = fs.readFileSync(path.join(__dirname, '../templates/oauth/auth-callback-test.ejs'), 'utf8');
    } else {
      template = fs.readFileSync(path.join(__dirname, '../templates/oauth/auth-callback.ejs'), 'utf8');
    }
    var html = ejs.render(template, result);
    res.status(200).send(html);
  }

Called after an account has been succesfully linked


function linkTokenSuccess(req, res, next) {
    var provider = getProviderToken(req.path);
    res.status(200).json({
      ok: true,
      success: util.capitalizeFirstLetter(provider) + ' successfully linked',
      provider: provider
    });
  }

function
linkTokenSuccess
(
req
,
res
,
next
)
{
var
provider
=
getProviderToken
(
req
.
path
)
;
res
.
status
(
200
)
.
json
(
{
ok
:
true
,
success
:
util
.
capitalizeFirstLetter
(
provider
)
+
' successfully linked'
,
provider
:
provider
}
)
;
}

Called after an account has been succesfully linked using access_token provider


function oauthErrorHandler(err,req,res,next) {
    var template;
    if(config.getItem('testMode.oauthTest')) {
      template = fs.readFileSync(path.join(__dirname, '../templates/oauth/auth-callback-test.ejs'), 'utf8');
    } else {
      template = fs.readFileSync(path.join(__dirname, '../templates/oauth/auth-callback.ejs'), 'utf8');
    }
    var html = ejs.render(template, {error: err.message, session: null, link: null});
    console.error(err);
    if(err.stack) {
      console.error(err.stack);
    }
    res.status(400).send(html);
  }


function tokenAuthErrorHandler(err,req,res,next) {
    var status;
    if(req.user && req.user._id) {
      status = 403;
    } else {
      status = 401;
    }
    console.error(err);
    if(err.stack) {
      console.error(err.stack);
      delete err.stack;
    }
    res.status(status).json(err);
  }

function tokenAuthErrorHandler ( err , req , res , next ) { var status ; if ( req . user && req . user . _id ) { status = 403 ; } else { status = 401 ; } console . error ( err ) ; if ( err . stack ) { console . error ( err . stack ) ; delete err . stack ; } res . status ( status ) . json ( err ) ; }

Handles errors if authentication from access_token provider fails


function registerProvider(provider, configFunction) {
    provider = provider.toLowerCase();
    var configRef = 'providers.' + provider;
    if (config.getItem(configRef + '.credentials')) {
      var credentials = config.getItem(configRef + '.credentials');
      credentials.passReqToCallback = true;
      var options = config.getItem(configRef + '.options') || {};
      configFunction.call(null, credentials, passport, authHandler);
      router.get('/' + provider, passportCallback(provider, options, 'login'));
      router.get('/' + provider + '/callback', passportCallback(provider, options, 'login'), initSession, oauthErrorHandler);
      if(!config.getItem('security.disableLinkAccounts')) {
        router.get('/link/' + provider, passport.authenticate('bearer', {session: false}), passportCallback(provider, options, 'link'));
        router.get('/link/' + provider + '/callback', passport.authenticate('bearer', {session: false}),
          passportCallback(provider, options, 'link'), linkSuccess, oauthErrorHandler);
      }
      console.log(provider + ' loaded.');
    }
  }

function
registerProvider
(
provider
,
configFunction
)
{
provider
=
provider
.
toLowerCase
(
)
;
var
configRef
=
'providers.'
+
provider
;
if
(
config
.
getItem
(
configRef
+
'.credentials'
)
)
{
var
credentials
=
config
.
getItem
(
configRef
+
'.credentials'
)
;
credentials
.
passReqToCallback
=
true
;
var
options
=
config
.
getItem
(
configRef
+
'.options'
)
||
{
}
;
configFunction
.
call
(
,
credentials
,
passport
,
authHandler
)
;
router
.
get
(
'/'
+
provider
,
passportCallback
(
provider
,
options
,
'login'
)
)
;
router
.
get
(
'/'
+
provider
+
'/callback'
,
passportCallback
(
provider
,
options
,
'login'
)
,
initSession
,
oauthErrorHandler
)
;
if
(
!
config
.
getItem
(
'security.disableLinkAccounts'
)
)
{
router
.
get
(
'/link/'
+
provider
,
passport
.
authenticate
(
'bearer'
,
{
session
:
false
}
)
,
passportCallback
(
provider
,
options
,
'link'
)
)
;
router
.
get
(
'/link/'
+
provider
+
'/callback'
,
passport
.
authenticate
(
'bearer'
,
{
session
:
false
}
)
,
passportCallback
(
provider
,
options
,
'link'
)
,
linkSuccess
,
oauthErrorHandler
)
;
}
console
.
log
(
provider
+
' loaded.'
)
;
}
}

Framework to register OAuth providers with passport


function registerOAuth2 (providerName, Strategy) {
    registerProvider(providerName, function (credentials, passport, authHandler) {
      passport.use(new Strategy(credentials,
        function (req, accessToken, refreshToken, profile, done) {
          authHandler(req, providerName, {accessToken: accessToken, refreshToken: refreshToken}, profile)
            .asCallback(done);
        }
      ));
    });
  }

function registerOAuth2 ( providerName , Strategy ) { registerProvider ( providerName , function ( credentials , passport , authHandler ) { passport . use ( new Strategy ( credentials , function ( req , accessToken , refreshToken , profile , done ) { authHandler ( req , providerName , { accessToken : accessToken , refreshToken : refreshToken } , profile ) . asCallback ( done ) ; } ) ) ; } ) ; }

A shortcut to register OAuth2 providers that follow the exact accessToken, refreshToken pattern.

A shortcut to register OAuth2 providers that follow the exact accessToken refreshToken pattern .


function registerTokenProvider (providerName, Strategy) {
    providerName = providerName.toLowerCase();
    var configRef = 'providers.' + providerName;
    if (config.getItem(configRef + '.credentials')) {
      var credentials = config.getItem(configRef + '.credentials');
      credentials.passReqToCallback = true;
      var options = config.getItem(configRef + '.options') || {};
      // Configure the Passport Strategy
      passport.use(providerName + '-token', new Strategy(credentials,
        function (req, accessToken, refreshToken, profile, done) {
          authHandler(req, providerName, {accessToken: accessToken, refreshToken: refreshToken}, profile)
            .asCallback(done);
        }));
      router.post('/' + providerName + '/token', passportTokenCallback(providerName, options), initTokenSession, tokenAuthErrorHandler);
      if(!config.getItem('security.disableLinkAccounts')) {
        router.post('/link/' + providerName + '/token', passport.authenticate('bearer', {session: false}),
          passportTokenCallback(providerName, options), linkTokenSuccess, tokenAuthErrorHandler);
      }
      console.log(providerName + '-token loaded.');
    }
  }

function
registerTokenProvider
(
providerName
,
Strategy
)
{
providerName
=
providerName
.
toLowerCase
(
)
;
var
configRef
=
'providers.'
+
providerName
;
if
(
config
.
getItem
(
configRef
+
'.credentials'
)
)
{
var
credentials
=
config
.
getItem
(
configRef
+
'.credentials'
)
;
credentials
.
passReqToCallback
=
true
;
var
options
=
config
.
getItem
(
configRef
+
'.options'
)
||
{
}
;
passport
.
use
(
providerName
+
'-token'
,
new
Strategy
(
credentials
,
function
(
req
,
accessToken
,
refreshToken
,
profile
,
done
)
{
authHandler
(
req
,
providerName
,
{
accessToken
:
accessToken
,
refreshToken
:
refreshToken
}
,
profile
)
.
asCallback
(
done
)
;
}
)
)
;
router
.
post
(
'/'
+
providerName
+
'/token'
,
passportTokenCallback
(
providerName
,
options
)
,
initTokenSession
,
tokenAuthErrorHandler
)
;
if
(
!
config
.
getItem
(
'security.disableLinkAccounts'
)
)
{
router
.
post
(
'/link/'
+
providerName
+
'/token'
,
passport
.
authenticate
(
'bearer'
,
{
session
:
false
}
)
,
passportTokenCallback
(
providerName
,
options
)
,
linkTokenSuccess
,
tokenAuthErrorHandler
)
;
}
console
.
log
(
providerName
+
'-token loaded.'
)
;
}
}

Registers a provider that accepts an access_token directly from the client, skipping the popup window and callback This is for supporting Cordova, native IOS and Android apps, as well as other devices

Registers a provider that accepts an access_token directly from the client skipping the popup window and callback This is for supporting Cordova native IOS and Android apps as well as other devices


function authHandler(req, provider, auth, profile) {
    if(req.user && req.user._id && req.user.key) {
      return user.linkSocial(req.user._id, provider, auth, profile, req);
    } else {
      return user.socialAuth(provider, auth, profile, req);
    }
  }

function authHandler ( req , provider , auth , profile ) { if ( req . user && req . user . _id && req . user . key ) { return user . linkSocial ( req . user . _id , provider , auth , profile , req ) ; } else { return user . socialAuth ( provider , auth , profile , req ) ; } }

This is called after a user has successfully authenticated with a provider If a user is authenticated with a bearer token we will link an account, otherwise log in auth is an object containing 'access_token' and optionally 'refresh_token'

This is called after a user has successfully authenticated with a provider If a user is authenticated with a bearer token we will link an account otherwise log in auth is an object containing access_token and optionally refresh_token


function passportCallback(provider, options, operation) {
    return function(req, res, next) {
      var theOptions = extend({}, options);
      if(provider === 'linkedin') {
        theOptions.state = true;
      }
      var accessToken = req.query.bearer_token || req.query.state;
      if(accessToken && (stateRequired.indexOf(provider) > -1 || config.getItem('providers.' + provider + '.stateRequired') === true)) {
        theOptions.state = accessToken;
      }
      theOptions.callbackURL = getLinkCallbackURLs(provider, req, operation, accessToken);
      theOptions.session = false;
      passport.authenticate(provider, theOptions)(req, res, next);
    };
  }

function passportCallback ( provider , options , operation ) { return function ( req , res , next ) { var theOptions = extend ( { } , options ) ; if ( provider === 'linkedin' ) { theOptions . state = true ; } var accessToken = req . query . bearer_token || req . query . state ; if ( accessToken && ( stateRequired . indexOf ( provider ) > - 1 || config . getItem ( 'providers.' + provider + '.stateRequired' ) === true ) ) { theOptions . state = accessToken ; } theOptions . callbackURL = getLinkCallbackURLs ( provider , req , operation , accessToken ) ; theOptions . session = false ; passport . authenticate ( provider , theOptions ) ( req , res , next ) ; } ; }

Configures the passport.authenticate for the given provider, passing in options Operation is 'login' or 'link'

Configures the passport . authenticate for the given provider passing in options Operation is login or link


function passportTokenCallback(provider, options) {
    return function(req, res, next) {
      var theOptions = extend({}, options);
      theOptions.session = false;
      passport.authenticate(provider + '-token', theOptions)(req, res, next);
    };
  }

function passportTokenCallback ( provider , options ) { return function ( req , res , next ) { var theOptions = extend ( { } , options ) ; theOptions . session = false ; passport . authenticate ( provider + '-token' , theOptions ) ( req , res , next ) ; } ; }

Configures the passport.authenticate for the given access_token provider, passing in options

Configures the passport . authenticate for the given access_token provider passing in options


function getProvider(pathname) {
    var items = pathname.split('/');
    var index = items.indexOf('callback');
    if(index > 0) {
      return items[index-1];
    }
  }

function getProvider ( pathname ) { var items = pathname . split ( '/' ) ; var index = items . indexOf ( 'callback' ) ; if ( index > 0 ) { return items [ index - 1 ] ; } }

Gets the provider name from a callback path


function getProviderToken(pathname) {
    var items = pathname.split('/');
    var index = items.indexOf('token');
    if(index > 0) {
      return items[index-1];
    }
  }

function getProviderToken ( pathname ) { var items = pathname . split ( '/' ) ; var index = items . indexOf ( 'token' ) ; if ( index > 0 ) { return items [ index - 1 ] ; } }

Gets the provider name from a callback path for access_token strategy


function requireRole(requiredRole) {
    return function(req, res, next) {
      if(!req.user) {
        return next(superloginError);
      }
      var roles = req.user.roles;
      if(!roles || !roles.length || roles.indexOf(requiredRole) === -1) {
        res.status(forbiddenError.status);
        res.json(forbiddenError);
      } else {
        next();
      }
    };
  }

function requireRole ( requiredRole ) { return function ( req , res , next ) { if ( ! req . user ) { return next ( superloginError ) ; } var roles = req . user . roles ; if ( ! roles || ! roles . length || roles . indexOf ( requiredRole ) === - 1 ) { res . status ( forbiddenError . status ) ; res . json ( forbiddenError ) ; } else { next ( ) ; } } ; }

Requires that the user have the specified role


function() {
    var foundLayer = null;
    $.each(projectedTiles, function (layerName, layer) {
      if (map.hasLayer(layer)) {
        foundLayer = layer;
      }
    });
    return foundLayer;
  }

function ( ) { var foundLayer = null ; $ . each ( projectedTiles , function ( layerName , layer ) { if ( map . hasLayer ( layer ) ) { foundLayer = layer ; } } ) ; return foundLayer ; }


function (crs, options) {
    switch(crs) {
      case "EPSG:3857":
      return L.CRS.EPSG3857;
      case "EPSG:3395":
      return L.CRS.EPSG3395;
      case "EPSG:4326":
      return L.CRS.EPSG4326;
      default:
        return this._defineMapCRS(crs, options);
    }
  }

function ( crs , options ) { switch ( crs ) { case "EPSG:3857" : return L . CRS . EPSG3857 ; case "EPSG:3395" : return L . CRS . EPSG3395 ; case "EPSG:4326" : return L . CRS . EPSG4326 ; default : return this . _defineMapCRS ( crs , options ) ; } }

Use default CRS classes for common codes, fallback to custom for all other codes.

Use default CRS classes for common codes fallback to custom for all other codes .


function (group) {
    var map = this;

    if (group.eachLayer) {
      group.eachLayer(function (layer) {
        map._updateAllLayers(layer);
      });
    } else {
      if (group.redraw) {
        group.redraw();
      } else if (group.update) {
        group.update();
      } else {
        console.log("Don't know how to update", group);
      }
    }
  }

function
(
group
)
{
var
map
=
this
;
if
(
group
.
eachLayer
)
{
group
.
eachLayer
(
function
(
layer
)
{
map
.
_updateAllLayers
(
layer
)
;
}
)
;
}
else
{
if
(
group
.
redraw
)
{
group
.
redraw
(
)
;
}
else
if
(
group
.
update
)
{
group
.
update
(
)
;
}
else
{
console
.
log
(
"Don't know how to update"
,
group
)
;
}
}
}

This recurses through all the map's layers to update layer positions after their positions moved.

This recurses through all the map s layers to update layer positions after their positions moved .


function (layersArray) {
    var fg = this._featureGroup,
      npg = this._nonPointGroup,
      chunked = this.options.chunkedLoading,
      chunkInterval = this.options.chunkInterval,
      chunkProgress = this.options.chunkProgress,
      newMarkers, i, l, m;

    if (this._map) {
      var offset = 0,
        started = (new Date()).getTime();
      var process = L.bind(function () {
        var start = (new Date()).getTime();
        for (; offset < layersArray.length; offset++) {
          if (chunked && offset % 200 === 0) {
            // every couple hundred markers, instrument the time elapsed since processing started:
            var elapsed = (new Date()).getTime() - start;
            if (elapsed > chunkInterval) {
              break; // been working too hard, time to take a break :-)
            }
          }

          m = layersArray[offset];

          //Not point data, can't be clustered
          if (!m.getLatLng) {
            npg.addLayer(m);
            continue;
          }

          if (this.hasLayer(m)) {
            continue;
          }

          this._addLayer(m, this._maxZoom);

          //If we just made a cluster of size 2 then we need to remove the other marker from the map (if it is) or we never will
          if (m.__parent) {
            if (m.__parent.getChildCount() === 2) {
              var markers = m.__parent.getAllChildMarkers(),
                otherMarker = markers[0] === m ? markers[1] : markers[0];
              fg.removeLayer(otherMarker);
            }
          }
        }

        if (chunkProgress) {
          // report progress and time elapsed:
          chunkProgress(offset, layersArray.length, (new Date()).getTime() - started);
        }

        if (offset === layersArray.length) {
          //Update the icons of all those visible clusters that were affected
          this._featureGroup.eachLayer(function (c) {
            if (c instanceof L.MarkerCluster && c._iconNeedsUpdate) {
              c._updateIcon();
            }
          });

          this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);
        } else {
          setTimeout(process, this.options.chunkDelay);
        }
      }, this);

      process();
    } else {
      newMarkers = [];
      for (i = 0, l = layersArray.length; i < l; i++) {
        m = layersArray[i];

        //Not point data, can't be clustered
        if (!m.getLatLng) {
          npg.addLayer(m);
          continue;
        }

        if (this.hasLayer(m)) {
          continue;
        }

        newMarkers.push(m);
      }
      this._needsClustering = this._needsClustering.concat(newMarkers);
    }
    return this;
  }

function ( layersArray ) { var fg = this . _featureGroup , npg = this . _nonPointGroup , chunked = this . options . chunkedLoading , chunkInterval = this . options . chunkInterval , chunkProgress = this . options . chunkProgress , newMarkers , i , l , m ; if ( this . _map ) { var offset = 0 , started = ( new Date ( ) ) . getTime ( ) ; var process = L . bind ( function ( ) { var start = ( new Date ( ) ) . getTime ( ) ; for ( ; offset < layersArray . length ; offset ++ ) { if ( chunked && offset % 200 === 0 ) { var elapsed = ( new Date ( ) ) . getTime ( ) - start ; if ( elapsed > chunkInterval ) { break ; } } m = layersArray [ offset ] ; if ( ! m . getLatLng ) { npg . addLayer ( m ) ; continue ; } if ( this . hasLayer ( m ) ) { continue ; } this . _addLayer ( m , this . _maxZoom ) ; if ( m . __parent ) { if ( m . __parent . getChildCount ( ) === 2 ) { var markers = m . __parent . getAllChildMarkers ( ) , otherMarker = markers [ 0 ] === m ? markers [ 1 ] : markers [ 0 ] ; fg . removeLayer ( otherMarker ) ; } } } if ( chunkProgress ) { chunkProgress ( offset , layersArray . length , ( new Date ( ) ) . getTime ( ) - started ) ; } if ( offset === layersArray . length ) { this . _featureGroup . eachLayer ( function ( c ) { if ( c instanceof L . MarkerCluster && c . _iconNeedsUpdate ) { c . _updateIcon ( ) ; } } ) ; this . _topClusterLevel . _recursivelyAddChildrenToMap ( null , this . _zoom , this . _currentShownBounds ) ; } else { setTimeout ( process , this . options . chunkDelay ) ; } } , this ) ; process ( ) ; } else { newMarkers = [ ] ; for ( i = 0 , l = layersArray . length ; i < l ; i ++ ) { m = layersArray [ i ] ; if ( ! m . getLatLng ) { npg . addLayer ( m ) ; continue ; } if ( this . hasLayer ( m ) ) { continue ; } newMarkers . push ( m ) ; } this . _needsClustering = this . _needsClustering . concat ( newMarkers ) ; } return this ; }

Takes an array of markers and adds them in bulk


function (layersArray) {
    var i, l, m,
      fg = this._featureGroup,
      npg = this._nonPointGroup;

    if (!this._map) {
      for (i = 0, l = layersArray.length; i < l; i++) {
        m = layersArray[i];
        this._arraySplice(this._needsClustering, m);
        npg.removeLayer(m);
      }
      return this;
    }

    for (i = 0, l = layersArray.length; i < l; i++) {
      m = layersArray[i];

      if (!m.__parent) {
        npg.removeLayer(m);
        continue;
      }

      this._removeLayer(m, true, true);

      if (fg.hasLayer(m)) {
        fg.removeLayer(m);
        if (m.setOpacity) {
          m.setOpacity(1);
        }
      }
    }

    //Fix up the clusters and markers on the map
    this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);

    fg.eachLayer(function (c) {
      if (c instanceof L.MarkerCluster) {
        c._updateIcon();
      }
    });

    return this;
  }

function ( layersArray ) { var i , l , m , fg = this . _featureGroup , npg = this . _nonPointGroup ; if ( ! this . _map ) { for ( i = 0 , l = layersArray . length ; i < l ; i ++ ) { m = layersArray [ i ] ; this . _arraySplice ( this . _needsClustering , m ) ; npg . removeLayer ( m ) ; } return this ; } for ( i = 0 , l = layersArray . length ; i < l ; i ++ ) { m = layersArray [ i ] ; if ( ! m . __parent ) { npg . removeLayer ( m ) ; continue ; } this . _removeLayer ( m , true , true ) ; if ( fg . hasLayer ( m ) ) { fg . removeLayer ( m ) ; if ( m . setOpacity ) { m . setOpacity ( 1 ) ; } } } this . _topClusterLevel . _recursivelyAddChildrenToMap ( null , this . _zoom , this . _currentShownBounds ) ; fg . eachLayer ( function ( c ) { if ( c instanceof L . MarkerCluster ) { c . _updateIcon ( ) ; } } ) ; return this ; }

Takes an array of markers and removes them in bulk


function () {
    var bounds = new L.LatLngBounds();

    if (this._topClusterLevel) {
      bounds.extend(this._topClusterLevel._bounds);
    }

    for (var i = this._needsClustering.length - 1; i >= 0; i--) {
      bounds.extend(this._needsClustering[i].getLatLng());
    }

    bounds.extend(this._nonPointGroup.getBounds());

    return bounds;
  }

function ( ) { var bounds = new L . LatLngBounds ( ) ; if ( this . _topClusterLevel ) { bounds . extend ( this . _topClusterLevel . _bounds ) ; } for ( var i = this . _needsClustering . length - 1 ; i >= 0 ; i -- ) { bounds . extend ( this . _needsClustering [ i ] . getLatLng ( ) ) ; } bounds . extend ( this . _nonPointGroup . getBounds ( ) ) ; return bounds ; }

Override FeatureGroup.getBounds as it doesn't work

Override FeatureGroup . getBounds as it doesn t work


function (method, context) {
    var markers = this._needsClustering.slice(),
      i;

    if (this._topClusterLevel) {
      this._topClusterLevel.getAllChildMarkers(markers);
    }

    for (i = markers.length - 1; i >= 0; i--) {
      method.call(context, markers[i]);
    }

    this._nonPointGroup.eachLayer(method, context);
  }

function ( method , context ) { var markers = this . _needsClustering . slice ( ) , i ; if ( this . _topClusterLevel ) { this . _topClusterLevel . getAllChildMarkers ( markers ) ; } for ( i = markers . length - 1 ; i >= 0 ; i -- ) { method . call ( context , markers [ i ] ) ; } this . _nonPointGroup . eachLayer ( method , context ) ; }


function (layer) {
    if (!layer) {
      return false;
    }

    var i, anArray = this._needsClustering;

    for (i = anArray.length - 1; i >= 0; i--) {
      if (anArray[i] === layer) {
        return true;
      }
    }

    anArray = this._needsRemoving;
    for (i = anArray.length - 1; i >= 0; i--) {
      if (anArray[i] === layer) {
        return false;
      }
    }

    return !!(layer.__parent && layer.__parent._group === this) || this._nonPointGroup.hasLayer(layer);
  }

function ( layer ) { if ( ! layer ) { return false ; } var i , anArray = this . _needsClustering ; for ( i = anArray . length - 1 ; i >= 0 ; i -- ) { if ( anArray [ i ] === layer ) { return true ; } } anArray = this . _needsRemoving ; for ( i = anArray . length - 1 ; i >= 0 ; i -- ) { if ( anArray [ i ] === layer ) { return false ; } } return ! ! ( layer . __parent && layer . __parent . _group === this ) || this . _nonPointGroup . hasLayer ( layer ) ; }

Returns true if the given layer is in this MarkerClusterGroup


function (map) {
    this._map = map;
    var i, l, layer;

    if (!isFinite(this._map.getMaxZoom())) {
      throw "Map has no maxZoom specified";
    }

    this._featureGroup.onAdd(map);
    this._nonPointGroup.onAdd(map);

    if (!this._gridClusters) {
      this._generateInitialClusters();
    }

    for (i = 0, l = this._needsRemoving.length; i < l; i++) {
      layer = this._needsRemoving[i];
      this._removeLayer(layer, true);
    }
    this._needsRemoving = [];

    //Remember the current zoom level and bounds
    this._zoom = this._map.getZoom();
    this._currentShownBounds = this._getExpandedVisibleBounds();

    this._map.on('zoomend', this._zoomEnd, this);
    this._map.on('moveend', this._moveEnd, this);

    if (this._spiderfierOnAdd) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely
      this._spiderfierOnAdd();
    }

    this._bindEvents();

    //Actually add our markers to the map:
    l = this._needsClustering;
    this._needsClustering = [];
    this.addLayers(l);
  }

function
(
map
)
{
this
.
_map
=
map
;
var
i
,
l
,
layer
;
if
(
!
isFinite
(
this
.
_map
.
getMaxZoom
(
)
)
)
{
throw
"Map has no maxZoom specified"
;
}
this
.
_featureGroup
.
onAdd
(
map
)
;
this
.
_nonPointGroup
.
onAdd
(
map
)
;
if
(
!
this
.
_gridClusters
)
{
this
.
_generateInitialClusters
(
)
;
}
for
(
i
=
0
,
l
=
this
.
_needsRemoving
.
length
;
i
<
l
;
i
++
)
{
layer
=
this
.
_needsRemoving
[
i
]
;
this
.
_removeLayer
(
layer
,
true
)
;
}
this
.
_needsRemoving
=
[
]
;
this
.
_zoom
=
this
.
_map
.
getZoom
(
)
;
this
.
_currentShownBounds
=
this
.
_getExpandedVisibleBounds
(
)
;
this
.
_map
.
on
(
'zoomend'
,
this
.
_zoomEnd
,
this
)
;
this
.
_map
.
on
(
'moveend'
,
this
.
_moveEnd
,
this
)
;
if
(
this
.
_spiderfierOnAdd
)
{
this
.
_spiderfierOnAdd
(
)
;
}
this
.
_bindEvents
(
)
;
l
=
this
.
_needsClustering
;
this
.
_needsClustering
=
[
]
;
this
.
addLayers
(
l
)
;
}


function (map) {
    map.off('zoomend', this._zoomEnd, this);
    map.off('moveend', this._moveEnd, this);

    this._unbindEvents();

    //In case we are in a cluster animation
    this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', '');

    if (this._spiderfierOnRemove) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely
      this._spiderfierOnRemove();
    }

    //Clean up all the layers we added to the map
    this._hideCoverage();
    this._featureGroup.onRemove(map);
    this._nonPointGroup.onRemove(map);

    this._featureGroup.clearLayers();

    this._map = null;
  }

function
(
map
)
{
map
.
off
(
'zoomend'
,
this
.
_zoomEnd
,
this
)
;
map
.
off
(
'moveend'
,
this
.
_moveEnd
,
this
)
;
this
.
_unbindEvents
(
)
;
this
.
_map
.
_mapPane
.
className
=
this
.
_map
.
_mapPane
.
className
.
replace
(
' leaflet-cluster-anim'
,
''
)
;
if
(
this
.
_spiderfierOnRemove
)
{
this
.
_spiderfierOnRemove
(
)
;
}
this
.
_hideCoverage
(
)
;
this
.
_featureGroup
.
onRemove
(
map
)
;
this
.
_nonPointGroup
.
onRemove
(
map
)
;
this
.
_featureGroup
.
clearLayers
(
)
;
this
.
_map
=
;
}


function (anArray, obj) {
    for (var i = anArray.length - 1; i >= 0; i--) {
      if (anArray[i] === obj) {
        anArray.splice(i, 1);
        return true;
      }
    }
  }

function ( anArray , obj ) { for ( var i = anArray . length - 1 ; i >= 0 ; i -- ) { if ( anArray [ i ] === obj ) { anArray . splice ( i , 1 ) ; return true ; } } }

Remove the given object from the given array


function (layer, newCluster) {
    if (newCluster === layer) {
      this._featureGroup.addLayer(layer);
    } else if (newCluster._childCount === 2) {
      newCluster._addToMap();

      var markers = newCluster.getAllChildMarkers();
      this._featureGroup.removeLayer(markers[0]);
      this._featureGroup.removeLayer(markers[1]);
    } else {
      newCluster._updateIcon();
    }
  }

function ( layer , newCluster ) { if ( newCluster === layer ) { this . _featureGroup . addLayer ( layer ) ; } else if ( newCluster . _childCount === 2 ) { newCluster . _addToMap ( ) ; var markers = newCluster . getAllChildMarkers ( ) ; this . _featureGroup . removeLayer ( markers [ 0 ] ) ; this . _featureGroup . removeLayer ( markers [ 1 ] ) ; } else { newCluster . _updateIcon ( ) ; } }


function (storageArray) {
    storageArray = storageArray || [];

    for (var i = this._childClusters.length - 1; i >= 0; i--) {
      this._childClusters[i].getAllChildMarkers(storageArray);
    }

    for (var j = this._markers.length - 1; j >= 0; j--) {
      storageArray.push(this._markers[j]);
    }

    return storageArray;
  }

function ( storageArray ) { storageArray = storageArray || [ ] ; for ( var i = this . _childClusters . length - 1 ; i >= 0 ; i -- ) { this . _childClusters [ i ] . getAllChildMarkers ( storageArray ) ; } for ( var j = this . _markers . length - 1 ; j >= 0 ; j -- ) { storageArray . push ( this . _markers [ j ] ) ; } return storageArray ; }

Recursively retrieve all child markers of this cluster