Input: Use this to add an equation clause for the value which is either an object or an array [CODESPLIT] function _handleMultiValuedParameters ( knexBuilder , attrName , parameter ) { if ( parameter instanceof Set ) { knexBuilder = knexBuilder . whereIn ( attrName , Array . from ( parameter ) ) ; } else if ( Array . isArray ( parameter ) ) { knexBuilder = knexBuilder . whereIn ( attrName , parameter ) ; } else { knexBuilder = knexBuilder . where ( attrName , parameter ) ; } return knexBuilder ; }


Input: Clean db [CODESPLIT] function cleanDb ( knex , tableNames , logger , verboseLog = false ) { validate . notNil ( tableNames ) ; return tableCleaner . cleanTables ( knex , tableNames , verboseLog ) . then ( ( ) => { if ( logger ) { logger . info ( 'Tables cleaned successfully: ' , tableNames . join ( ', ' ) ) ; } } ) . catch ( err => { if ( logger ) { logger . error ( 'Error cleaning tables' , err ) ; } throw err ; } ) ; }


Input:
Get Knex instance without validating the connection [CODESPLIT] function getKnexInstance ( config , registry = _registry , logger = console ) { validate . notNil ( config , 'Config is null or undefined' ) ; validate . notNil ( config . client , 'DB client is null or undefined' ) ; const { host , database , user } = config . connection ; const connectionTimeout = config . acquireConnectionTimeout ; logger . info ( ` ${ user } ${ host } ${ database } ` ) ; logger . info ( ` ${ connectionTimeout } ` ) ; const knex = module . exports . _initKnexInstance ( config ) ; module . exports . registerKnexInstance ( knex , registry ) ; // unfortunately, we can't check heartbeat here and fail-fast, as this initialization is synchronous
 return knex ; }


Input: Attempts to close all registered knex instances [CODESPLIT] function closeAllInstances ( registry = _registry ) { const promises = [ ] ; const errors = [ ] ; while ( registry . length > 0 ) { const knex = registry . pop ( ) ; const destructionPromise = knex . destroy ( ) . catch ( e => { errors . push ( { knex , cause : e } ) ; } ) ; promises . push ( destructionPromise ) ; } return Promise . all ( promises ) . then ( ( ) => { return errors ; } ) ; }


Input: Remark plugin for custom tags : <x - foo data - value = 42 / > [CODESPLIT] function remarkCustomTags ( customTags ) { return ast => visit ( ast , 'html' , node => { if ( node . value . startsWith ( '<x-' ) ) { // Parse tag’s HTML const dom = parse5 . parseFragment ( unescapeMarkdown ( node . value ) ) ; const tagNode = dom . childNodes [ 0 ] ; if ( ! tagNode ) { throw new Error ( 'Cannot parse custom tag:' , node . value ) ; } let { tagName , attrs } = tagNode ; const childNode = tagNode . childNodes [ 0 ] ; attrs . push ( { name : 'children' , value : childNode ? childNode . value . trim ( ) : null , } ) ; tagName = tagName . replace ( / ^x- / , '' ) ; // Check tag function const tagFunction = customTags [ tagName ] ; if ( ! tagFunction || ! _ . isFunction ( tagFunction ) ) { throw new Error ( ` ${ tagName } ` ) ; } // Unzip attributes attrs = attrs . reduce ( ( attrsObj , attr ) => { attrsObj [ attr . name ] = attr . value ; return attrsObj ; } , { } ) ; // Render let result ; try { result = tagFunction ( attrs ) || '' ; } catch ( exception ) { result = errorInlineHtml ( ` ${ tagName } ${ exception . message } ` , { block : true } ) ; } node . value = result . toString ( ) . trim ( ) ; } } ) ; }


Input: Remark plugin for Highlight . js . [CODESPLIT] function remarkHljs ( { aliases } ) { return ast => visit ( ast , 'code' , node => { if ( ! node . data ) { node . data = { } ; } const lang = node . lang ; const highlighted = lang ? low . highlight ( aliases [ lang ] || lang , node . value ) . value : low . highlightAuto ( node . value ) . value ; node . data . hChildren = highlighted ; node . data . hProperties = { className : [ 'hljs' , lang && ` ${ lang } ` ] , } ; } ) ; }


Input: Render Markdow using given processor . [CODESPLIT] function render ( processor , source ) { try { return processor . processSync ( source ) . contents ; } catch ( exception ) { const error = ` ${ exception . message } ` ; console . error ( error ) ; return errorInlineHtml ( error ) . toString ( ) ; } }


Input: / * function parseWithDox ( content ) { const dox = require ( dox ) [CODESPLIT] function readTemplate ( doc ) { return fs . readFileAsync ( flags . template , "utf8" ) . then ( template => ( { doc , template } ) ) ; }


Input: Appends an arrow head marker to the defs element to be used later . [CODESPLIT] function createColorArrow ( defElement , color ) { defElement . append ( "marker" ) . attr ( "id" , "arrow-" + color ) . attr ( "viewBox" , "0 -5 10 10" ) . attr ( "refX" , 8 ) . attr ( "markerWidth" , 6 ) . attr ( "markerHeight" , 6 ) . attr ( "fill" , color ) . attr ( "orient" , "auto" ) . append ( "path" ) . attr ( "d" , "M0,-5L10,0L0,5" ) . attr ( "class" , "arrowHead" ) ; }


Input: The main entry point of this module takes a CSS property / value pair and validates it . It will return either true if valid or a message object if either invalid or unknown . [CODESPLIT] function cssValues ( property , value ) { if ( typeof value === 'string' ) { value = valueParser ( value ) ; } var first = value . nodes [ 0 ] ; if ( value . nodes . length === 1 && ( isKeyword ( first , cssGlobals ) || isVariable ( first ) ) ) { return true ; } if ( validators [ property ] ) { var result = validators [ property ] ( value ) ; if ( result . type ) { return result ; } if ( ! ! result === false ) { return invalidMessage ( '"' + value + '" is not a valid value for "' + property + '".' ) ; } return true ; } // Pass through unknown properties return unknownMessage ( '"' + property + '" is not a recognised property.' ) ; }


Input: Test that the nodes from postcss - value - parser are a certain length . This uses strict equality by default but you can supply an alternate operator . [CODESPLIT] function valueParserNodesLength ( length , operator = '===' ) { return t . binaryExpression ( operator , valueParserASTNodesLength , t . numericLiteral ( length ) ) ; }


Input: Add colors to selenium log messages . ** Note ** : Naive but fun . [CODESPLIT] function ( data ) { data = ( data || "" ) . toString ( ) . trim ( ) ; _ . any ( SEL_LOG_COLORS , function ( val , key ) { if ( data . indexOf ( key ) > NOT_FOUND ) { data = data . split ( key ) . join ( key [ val ] ) ; return true ; } } ) ; return data ; }


Input: / * This is a temporary function to be removed once generation of all functions has been achieved . [CODESPLIT] function known ( parsed ) { return parsed . every ( node => { return node . type === 'keyword' || node . type === 'string' || node . type === 'group' && ! node . order && ! node . min && node . values . every ( n => n . type === 'keyword' ) || ( node . type === 'data' && validators [ dataValidator ( node . value ) ] ) ; // eslint-disable-line } ) ; }


Input: / * Decrypt encrypted data block of keyword index ( attrs . Encrypted = 2 ) . [CODESPLIT] function decrypt ( buf , key ) { key = ripemd128 . ripemd128 ( key ) ; var byte , keylen = key . length , prev = 0x36 , i = 0 , len = buf . length ; for ( ; i < len ; i ++ ) { byte = buf [ i ] ; byte = ( ( byte >> 4 ) | ( byte << 4 ) ) ; // & 0xFF;  <-- it's already a byte byte = byte ^ prev ^ ( i & 0xFF ) ^ key [ i % keylen ] ; prev = buf [ i ] ; buf [ i ] = byte ; } return buf ; }


Input: For sliceThen ( .. ) . exec ( proc .. ) mark what proc function returns is multiple values to be passed to further Promise#spread ( .. ) call . [CODESPLIT] function spreadus ( ) { var args = Array . prototype . slice . apply ( arguments ) ; args . _spreadus_ = true ; return args ; }


Input:
var fd = null ; var fdFileName = null ; [CODESPLIT] function sliceThen ( file , offset , len ) { var p = new Promise ( function ( _resolve ) { fs . open ( file , 'r' , function ( err , fd ) { if ( err ) { throw err ; } var res = new Buffer ( len ) ; fs . read ( fd , res , 0 , len , offset , function ( err , bytesRead , buffer ) { if ( err ) { throw err ; } _resolve ( buffer ) ; } ) ; } ) ; } ) ; /**
     * Call proc with specified arguments prepending with sliced file/blob data (ArrayBuffer) been read.
     * @param the first argument is a function to be executed
     * @param other optional arguments are passed to the function following auto supplied input ArrayBuffer
     * @return a promise object which can be chained with further process through spread() method
     */ p . exec = function ( proc /*, args... */ ) { var args = Array . prototype . slice . call ( arguments , 1 ) ; return p . then ( function ( data ) { args . unshift ( data ) ; var ret = proc . apply ( null , args ) ; return resolve ( ret !== UNDEFINED && ret . _spreadus_ ? ret : [ ret ] ) ; } ) ; } ; return p ; }


Input: Harvest any resolved promises if all failed then return reasons . [CODESPLIT] function harvest ( outcomes ) { return Promise . settle ( outcomes ) . then ( function ( results ) { if ( results . length === 0 ) { return reject ( "** NOT FOUND **" ) ; } var solved = [ ] , failed = [ ] ; for ( var i = 0 ; i < results . length ; i ++ ) { if ( results [ i ] . isResolved ( ) ) { solved . push ( results [ i ] . value ( ) ) ; } else { failed . push ( results [ i ] . reason ( ) ) ; } } return solved . length ? solved : failed ; } ) ; }


Input: / * Create a Record Block Table object to load record block info from record section in mdx / mdd file . Retrived data is stored in an Uint32Array which contains N pairs of ( offset_comp offset_decomp ) value where N is number of record blocks . [CODESPLIT] function createRecordBlockTable ( ) { var pos = 0 , // current position arr ; // backed Uint32Array return { // Allocate required ArrayBuffer for storing record block table, where len is number of record blocks. alloc : function ( len ) { arr = new Uint32Array ( len * 2 ) ; } , // Store offset pair value (compressed & decompressed) for a record block // NOTE: offset_comp is absolute offset counted from start of mdx/mdd file. put : function ( offset_comp , offset_decomp ) { arr [ pos ++ ] = offset_comp ; arr [ pos ++ ] = offset_decomp ; } , // Given offset of a keyword after decompression, return a record block info containing it, else undefined if not found. find : function ( keyAt ) { var hi = ( arr . length >> 1 ) - 1 , lo = 0 , i = ( lo + hi ) >> 1 , val = arr [ ( i << 1 ) + 1 ] ; if ( keyAt > arr [ ( hi << 1 ) + 1 ] || keyAt < 0 ) { return ; } while ( true ) { if ( hi - lo <= 1 ) { if ( i < hi ) { return { block_no : i , comp_offset : arr [ i <<= 1 ] , comp_size : arr [ i + 2 ] - arr [ i ] , decomp_offset : arr [ i + 1 ] , decomp_size : arr [ i + 3 ] - arr [ i + 1 ] } ; } else { return ; } } ( keyAt < val ) ? hi = i : lo = i ; i = ( lo + hi ) >> 1 ; val = arr [ ( i << 1 ) + 1 ] ; } } , } ; }


Input: Given offset of a keyword after decompression return a record block info containing it else undefined if not found . [CODESPLIT] function ( keyAt ) { var hi = ( arr . length >> 1 ) - 1 , lo = 0 , i = ( lo + hi ) >> 1 , val = arr [ ( i << 1 ) + 1 ] ; if ( keyAt > arr [ ( hi << 1 ) + 1 ] || keyAt < 0 ) { return ; } while ( true ) { if ( hi - lo <= 1 ) { if ( i < hi ) { return { block_no : i , comp_offset : arr [ i <<= 1 ] , comp_size : arr [ i + 2 ] - arr [ i ] , decomp_offset : arr [ i + 1 ] , decomp_size : arr [ i + 3 ] - arr [ i + 1 ] } ; } else { return ; } } ( keyAt < val ) ? hi = i : lo = i ; i = ( lo + hi ) >> 1 ; val = arr [ ( i << 1 ) + 1 ] ; } }


Input:
Parse a MDict dictionary / resource file ( mdx / mdd ) . [CODESPLIT] function parse_mdict ( file , ext ) { var KEY_INDEX , // keyword index array RECORD_BLOCK_TABLE = createRecordBlockTable ( ) ; // record block table var attrs = { } , // storing dictionary attributes _v2 , // true if enginge version > 2 _bpu , // bytes per unit when converting text size to byte length for text data _tail , // need to skip extra tail bytes after decoding text _decoder , // text decorder _decryptors = [ false , false ] , // [keyword_header_decryptor, keyword_index_decryptor], only keyword_index_decryptor is supported _searchTextLen , // search NUL to get text length _readShort = function ( scanner ) { return scanner . readUint8 ( ) ; } , // read a "short" number representing kewword text size, 8-bit for version < 2, 16-bit for version >= 2 _readNum = function ( scanner ) { return scanner . readInt ( ) ; } , // Read a number representing offset or data block size, 16-bit for version < 2, 32-bit for version >= 2 _checksum_v2 = function ( ) { } , // Version >= 2.0 only checksum _adaptKey = function ( key ) { return key ; } , // adapt key by converting to lower case or stripping punctuations according to dictionary attributes (KeyCaseSensitive, StripKey) _slice = sliceThen . bind ( null , file ) ; // bind sliceThen() with file argument           /**
     * Config scanner according to dictionary attributes.
     */ function config ( ) { attrs . Encoding = attrs . Encoding || 'UTF-16' ; _searchTextLen = ( attrs . Encoding === 'UTF-16' ) ? function ( dv , offset ) { offset = offset ; var mark = offset ; while ( dv . getUint16 ( offset ++ ) ) { /* scan for NUL */ } ; return offset - mark ; } : function ( dv , offset ) { offset = offset ; var mark = offset ; while ( dv . getUint8 ( offset ++ ) ) { /* scan for NUL */ } return offset - mark - 1 ; } ; _decoder = new TextDecoder ( attrs . Encoding || 'UTF-16LE' ) ; _bpu = ( attrs . Encoding === 'UTF-16' ) ? 2 : 1 ; if ( parseInt ( attrs . GeneratedByEngineVersion , 10 ) >= 2.0 ) { _v2 = true ; _tail = _bpu ; // HUGE dictionary file (>4G) is not supported, take only lower 32-bit _readNum = function ( scanner ) { return scanner . forward ( 4 ) , scanner . readInt ( ) ; } ; _readShort = function ( scanner ) { return scanner . readUint16 ( ) ; } ; _checksum_v2 = function ( scanner ) { return scanner . checksum ( ) ; } ; } else { _tail = 0 ; } // keyword index decrypted? if ( attrs . Encrypted & 0x02 ) { _decryptors [ 1 ] = decrypt ; } var regexp = common . REGEXP_STRIPKEY [ ext ] ; if ( isTrue ( attrs . KeyCaseSensitive ) ) { _adaptKey = isTrue ( attrs . StripKey ) ? function ( key ) { return key . replace ( regexp , '$1' ) ; } : function ( key ) { return key ; } ; } else { _adaptKey = isTrue ( attrs . StripKey || ( _v2 ? '' : 'yes' ) ) ? function ( key ) { return key . toLowerCase ( ) . replace ( regexp , '$1' ) ; } : function ( key ) { return key . toLowerCase ( ) ; } ; } } // Read data in current offset from target data ArrayBuffer function Scanner ( buf , len ) { var offset = 0 , dv = new DataView ( buf ) ; var methods = { // target data size in bytes size : function ( ) { return len || buf . byteLength ; } , // update offset to new position forward : function ( len ) { return offset += len ; } , // return current offset offset : function ( ) { return offset ; } , // MDict file format uses big endian to store number // 32-bit unsigned int readInt : function ( ) { return conseq ( dv . getUint32 ( offset , false ) , this . forward ( 4 ) ) ; } , readUint16 : function ( ) { return conseq ( dv . getUint16 ( offset , false ) , this . forward ( 2 ) ) ; } , readUint8 : function ( ) { return conseq ( dv . getUint8 ( offset , false ) , this . forward ( 1 ) ) ; } , // Read a "short" number representing keyword text size, 8-bit for version < 2, 16-bit for version >= 2 readShort : function ( ) { return _readShort ( this ) ; } , // Read a number representing offset or data block size, 16-bit for version < 2, 32-bit for version >= 2 readNum : function ( ) { return _readNum ( this ) ; } , readUTF16 : function ( len ) { return conseq ( UTF_16LE . decode ( newUint8Array ( buf , offset , len ) ) , this . forward ( len ) ) ; } , // Read data to an Uint8Array and decode it to text with specified encoding. // Text length in bytes is determined by searching terminated NUL. // NOTE: After decoding the text, it is need to forward extra "tail" bytes according to specified encoding.  readText : function ( ) { var len = _searchTextLen ( dv , offset ) ; return conseq ( _decoder . decode ( newUint8Array ( buf , offset , len ) ) , this . forward ( len + _bpu ) ) ; } , // Read data to an Uint8Array and decode it to text with specified encoding. // @param len length in basic unit, need to multiply byte per unit to get length in bytes // NOTE: After decoding the text, it is need to forward extra "tail" bytes according to specified encoding.  readTextSized : function ( len ) { len *= _bpu ; var read = conseq ( _decoder . decode ( newUint8Array ( buf , offset , len ) ) , this . forward ( len + _tail ) ) ; return read ; } , // Skip checksum, just ignore it anyway. checksum : function ( ) { this . forward ( 4 ) ; } , // Version >= 2.0 only checksum_v2 : function ( ) { return _checksum_v2 ( this ) ; } , // Read data block of keyword index, key block or record content. // These data block are maybe in compressed (gzip or lzo) format, while keyword index maybe be encrypted. // @see https://github.com/zhansliu/writemdict/blob/master/fileformat.md#compression (with typo mistake) readBlock : function ( len , expectedBufSize , decryptor ) { var comp_type = dv . getUint8 ( offset , false ) ; // compression type, 0 = non, 1 = lzo, 2 = gzip if ( comp_type === 0 ) { if ( _v2 ) { this . forward ( 8 ) ; // for version >= 2, skip comp_type (4 bytes with tailing \x00) and checksum (4 bytes) } return this ; } else { // skip comp_type (4 bytes with tailing \x00) and checksum (4 bytes) offset += 8 ; len -= 8 ; var tmp = new Uint8Array ( len ) ; buf . copy ( tmp , 0 , offset , offset + len ) ; if ( decryptor ) { var passkey = new Uint8Array ( 8 ) ; var q = new Buffer ( 4 ) ; buf . copy ( passkey , 0 , offset - 4 , offset ) ; // var q = new Buffer(4); passkey . set ( [ 0x95 , 0x36 , 0x00 , 0x00 ] , 4 ) ; // key part 2: fixed data tmp = decryptor ( tmp , passkey ) ; } tmp = comp_type === 2 ? pako . inflate ( tmp ) : lzo . decompress ( tmp , expectedBufSize , 1308672 ) ; this . forward ( len ) ; var d = new Buffer ( tmp ) ; return Scanner ( d , tmp . length ) ; } } , // Read raw data as Uint8Array from current offset with specified length in bytes readRaw : function ( len ) { return conseq ( newUint8Array ( buf , offset , len ) , this . forward ( len === UNDEFINED ? buf . length - offset : len ) ) ; } , } ; return Object . create ( methods ) ; } /**
     * Read the first 4 bytes of mdx/mdd file to get length of header_str.
     * @see https://github.com/zhansliu/writemdict/blob/master/fileformat.md#file-structure
     * @param input sliced file (start = 0, length = 4)
     * @return length of header_str
     */ function read_file_head ( input ) { return Scanner ( input ) . readInt ( ) ; } /**
     * Read header section, parse dictionary attributes and config scanner according to engine version attribute.
     * @see https://github.com/zhansliu/writemdict/blob/master/fileformat.md#header-section
     * @param input sliced file (start = 4, length = len + 48), header string + header section (max length 48)
     * @param len lenghth of header_str
     * @return [remained length of header section (header_str and checksum, = len + 4), original input]
     */ function read_header_sect ( input , len ) { var scanner = Scanner ( input ) , header_str = scanner . readUTF16 ( len ) . replace ( / \0$ / , '' ) ; // need to remove tailing NUL // parse dictionary attributes var doc = new DOMParser ( ) . parseFromString ( header_str , 'text/xml' ) ; var elem = doc . getElementsByTagName ( 'Dictionary' ) [ 0 ] ; if ( ! elem ) { elem = doc . getElementsByTagName ( 'Library_Data' ) [ 0 ] ; } // console.log(doc.getElementsByTagName('Dictionary')[0].attributes); // var xml = parseXml(header_str).querySelector('Dictionary, Library_Data').attributes; for ( var i = 0 , item ; i < elem . attributes . length ; i ++ ) { item = elem . attributes [ i ] ; attrs [ item . nodeName ] = item . nodeValue ; } attrs . Encrypted = parseInt ( attrs . Encrypted , 10 ) || 0 ; config ( ) ; return spreadus ( len + 4 , input ) ; } /**
     * Read keyword summary at the begining of keyword section.
     * @see https://github.com/zhansliu/writemdict/blob/master/fileformat.md#keyword-section
     * @param input sliced file, same as input passed to read_header_sect()
     * @param offset start position of keyword section in sliced file, equals to length of header string plus checksum.\
     * @return keyword_sect object
     */ function read_keyword_summary ( input , offset ) { var scanner = Scanner ( input ) ; scanner . forward ( offset ) ; return { num_blocks : scanner . readNum ( ) , num_entries : scanner . readNum ( ) , key_index_decomp_len : _v2 && scanner . readNum ( ) , // Ver >= 2.0 only key_index_comp_len : scanner . readNum ( ) , key_blocks_len : scanner . readNum ( ) , chksum : scanner . checksum_v2 ( ) , // extra field len : scanner . offset ( ) - offset , // actual length of keyword section, varying with engine version attribute } ; } /**
     * Read keyword index part of keyword section.
     * @see https://github.com/zhansliu/writemdict/blob/master/fileformat.md#keyword-header-encryption
     * @see https://github.com/zhansliu/writemdict/blob/master/fileformat.md#keyword-index
     * @param input sliced file, remained part of keyword section after keyword summary which can also be used to read following key blocks.
     * @param keyword_summary
     * @return [keyword_summary, array of keyword index]
     */ function read_keyword_index ( input , keyword_summary ) { var scanner = Scanner ( input ) . readBlock ( keyword_summary . key_index_comp_len , keyword_summary . key_index_decomp_len , _decryptors [ 1 ] ) , keyword_index = Array ( keyword_summary . num_blocks ) , offset = 0 ; for ( var i = 0 , size ; i < keyword_summary . num_blocks ; i ++ ) { keyword_index [ i ] = { num_entries : conseq ( scanner . readNum ( ) , size = scanner . readShort ( ) ) , // UNUSED, can be ignored         //          first_size:  size = scanner.readShort(), first_word : conseq ( scanner . readTextSized ( size ) , size = scanner . readShort ( ) ) , // UNUSED, can be ignored //          last_size:   size = scanner.readShort(), last_word : scanner . readTextSized ( size ) , comp_size : size = scanner . readNum ( ) , decomp_size : scanner . readNum ( ) , // extra fields offset : offset , // offset of the first byte for the target key block in mdx/mdd file index : i // index of this key index, used to search previous/next block } ; offset += size ; } return spreadus ( keyword_summary , keyword_index ) ; } /**
     * Read keyword entries inside a keyword block and fill KEY_TABLE.
     * @param scanner scanner object to read key entries, which starts at begining of target key block
     * @param kdx corresponding keyword index object
     * NOTE: no need to read keyword block anymore, for debug only.
     */ function read_key_block ( scanner , kdx ) { var scanner = scanner . readBlock ( kdx . comp_size , kdx . decomp_size ) ; for ( var i = 0 ; i < kdx . num_entries ; i ++ ) { //        scanner.readNum(); scanner.readText(); var kk = [ scanner . readNum ( ) , scanner . readText ( ) ] ; } } /**
     * Delay to scan key table, for debug onyl.
     * @param slicedKeyBlock a promise object which will resolve to an ArrayBuffer containing keyword blocks
     *                       sliced from mdx/mdd file.
     * @param num_entries number of keyword entries
     * @param keyword_index array of keyword index
     * @param delay time to delay for scanning key table
     */ function willScanKeyTable ( slicedKeyBlock , num_entries , keyword_index , delay ) { slicedKeyBlock . delay ( delay ) . then ( function ( input ) { var scanner = Scanner ( input ) ; for ( var i = 0 , size = keyword_index . length ; i < size ; i ++ ) { // common.log('z',keyword_index[i]); read_key_block ( scanner , keyword_index [ i ] ) ; } } ) ; } /**
     * Read record summary at the begining of record section.
     * @see https://github.com/zhansliu/writemdict/blob/master/fileformat.md#record-section
     * @param input sliced file, start = begining of record section, length = 32 (max length of record summary)
     * @param pos begining of record section
     * @returj record summary object
     */ function read_record_summary ( input , pos ) { var scanner = Scanner ( input ) , record_summary = { num_blocks : scanner . readNum ( ) , num_entries : scanner . readNum ( ) , index_len : scanner . readNum ( ) , blocks_len : scanner . readNum ( ) , // extra field len : scanner . offset ( ) , // actual length of record section (excluding record block index), varying with engine version attribute } ; // start position of record block from head of mdx/mdd file record_summary . block_pos = pos + record_summary . index_len + record_summary . len ; return record_summary ; } /**
     * Read record block index part in record section, and fill RECORD_BLOCK_TABLE
     * @see https://github.com/zhansliu/writemdict/blob/master/fileformat.md#record-section
     * @param input sliced file, start = begining of record block index, length = record_summary.index_len
     * @param record_summary record summary object
     */ function read_record_block ( input , record_summary ) { var scanner = Scanner ( input ) , size = record_summary . num_blocks , record_index = Array ( size ) , p0 = record_summary . block_pos , p1 = 0 ; RECORD_BLOCK_TABLE . alloc ( size + 1 ) ; for ( var i = 0 , rdx ; i < size ; i ++ ) { record_index [ i ] = rdx = { comp_size : scanner . readNum ( ) , decomp_size : scanner . readNum ( ) } ; RECORD_BLOCK_TABLE . put ( p0 , p1 ) ; p0 += rdx . comp_size ; p1 += rdx . decomp_size ; } RECORD_BLOCK_TABLE . put ( p0 , p1 ) ; } /**
     * Read definition in text for given keyinfo object.
     * @param input record block sliced from the file
     * @param block record block index
     * @param keyinfo a object with property of record's offset and optional size for the given keyword
     * @return definition in text
     */ function read_definition ( input , block , keyinfo ) { var scanner = Scanner ( input ) . readBlock ( block . comp_size , block . decomp_size ) ; scanner . forward ( keyinfo . offset - block . decomp_offset ) ; return scanner . readText ( ) ; } /**
     * Following link to find actual definition of keyword.
     * @param definition maybe starts with "@@@LINK=" which links to another keyword
     * @param lookup search function
     * @return resolved actual definition
     */ function followLink ( definition , lookup ) { return ( definition . substring ( 0 , 8 ) !== '@@@LINK=' ) ? definition : lookup ( definition . substring ( 8 ) ) ; } /**
     * Read content in ArrayBuffer for give keyinfo object
     * @param input record block sliced from the file
     * @param block record block index
     * @param keyinfo a object with property of record's offset and optional size for the given keyword
     * @return an ArrayBuffer containing resource of image/audio/css/font etc.
     */ function read_object ( input , block , keyinfo ) { if ( input . byteLength > 0 ) { var scanner = Scanner ( input ) . readBlock ( block . comp_size , block . decomp_size ) ; scanner . forward ( keyinfo . offset - block . decomp_offset ) ; return scanner . readRaw ( keyinfo . size ) ; } else { throw '* OUT OF FILE RANGE * ' + keyinfo + ' @offset=' + block . comp_offset ; } } /**
     * Find word definition for given keyinfo object.
     * @param keyinfo a object with property of record's offset and optional size for the given keyword
     * @return a promise object which will resolve to definition in text. Link to other keyword is followed to get actual definition.
     */ function findWord ( keyinfo ) { var block = RECORD_BLOCK_TABLE . find ( keyinfo . offset ) ; return _slice ( block . comp_offset , block . comp_size ) . exec ( read_definition , block , keyinfo ) . spread ( function ( definition ) { return resolve ( followLink ( definition , LOOKUP . mdx ) ) ; } ) ; } /**
     * Find resource (image, sound etc.) for given keyinfo object.
     * @param keyinfo a object with property of record's offset and optional size for the given keyword
     * @return a promise object which will resolve to an ArrayBuffer containing resource of image/audio/css/font etc.
     * TODO: Follow link, maybe it's too expensive and a rarely used feature?
     */ function findResource ( keyinfo ) { var block = RECORD_BLOCK_TABLE . find ( keyinfo . offset ) ; return _slice ( block . comp_offset , block . comp_size ) . exec ( read_object , block , keyinfo ) . spread ( function ( blob ) { return resolve ( blob ) ; } ) ; } //------------------------------------------------------------------------------------------------ // Implementation for look-up //------------------------------------------------------------------------------------------------ var slicedKeyBlock , _cached_keys , // cache latest keys  _trail , // store latest visited record block & position when search for candidate keys mutual_ticket = 0 ; // a oneway increased ticket used to cancel unfinished pattern match /**
      * Reduce the key index array to an element which contains or is the nearest one matching a given phrase.
      */ function reduce ( arr , phrase ) { var len = arr . length ; if ( len > 1 ) { len = len >> 1 ; return phrase > _adaptKey ( arr [ len - 1 ] . last_word ) ? reduce ( arr . slice ( len ) , phrase ) : reduce ( arr . slice ( 0 , len ) , phrase ) ; } else { return arr [ 0 ] ; } } /**
      * Reduce the array to index of an element which contains or is the nearest one matching a given phrase.
      */ function shrink ( arr , phrase ) { var len = arr . length , sub ; if ( len > 1 ) { len = len >> 1 ; var key = _adaptKey ( arr [ len ] ) ; if ( phrase < key ) { sub = arr . slice ( 0 , len ) ; sub . pos = arr . pos ; } else { sub = arr . slice ( len ) ; sub . pos = ( arr . pos || 0 ) + len ; } return shrink ( sub , phrase ) ; } else { return ( arr . pos || 0 ) + ( phrase <= _adaptKey ( arr [ 0 ] ) ? 0 : 1 ) ; } } /**
     * Load keys for a keyword index object from mdx/mdd file.
     * @param kdx keyword index object
     */ function loadKeys ( kdx ) { if ( _cached_keys && _cached_keys . pilot === kdx . first_word ) { return resolve ( _cached_keys . list ) ; } else { return slicedKeyBlock . then ( function ( input ) { var scanner = Scanner ( input ) , list = Array ( kdx . num_entries ) ; scanner . forward ( kdx . offset ) ; scanner = scanner . readBlock ( kdx . comp_size , kdx . decomp_size ) ; for ( var i = 0 ; i < kdx . num_entries ; i ++ ) { var offset = scanner . readNum ( ) ; list [ i ] = new Object ( scanner . readText ( ) ) ; list [ i ] . offset = offset ; if ( i > 0 ) { list [ i - 1 ] . size = offset - list [ i - 1 ] . offset ; } } _cached_keys = { list : list , pilot : kdx . first_word } ; return list ; } ) ; } } /**
     * Search for the first keyword match given phrase.
     */ function seekVanguard ( phrase ) { phrase = _adaptKey ( phrase ) ; var kdx = reduce ( KEY_INDEX , phrase ) ; // look back for the first record block containing keyword for the specified phrase if ( phrase <= _adaptKey ( kdx . last_word ) ) { var index = kdx . index - 1 , prev ; while ( prev = KEY_INDEX [ index ] ) { if ( _adaptKey ( prev . last_word ) !== _adaptKey ( kdx . last_word ) ) { break ; } kdx = prev ; index -- ; } } return loadKeys ( kdx ) . then ( function ( list ) { var idx = shrink ( list , phrase ) ; // look back for the first matched keyword position while ( idx > 0 ) { if ( _adaptKey ( list [ -- idx ] ) !== _adaptKey ( phrase ) ) { idx ++ ; break ; } } return [ kdx , Math . min ( idx , list . length - 1 ) , list ] ; } ) ; } // TODO: have to restrict max count to improve response /**
     * Append more to word list according to a filter or expected size.
     */ function appendMore ( word , list , nextKdx , expectedSize , filter , ticket ) { if ( ticket !== mutual_ticket ) { throw 'force terminated' ; } if ( filter ) { if ( _trail . count < expectedSize && nextKdx && nextKdx . first_word . substr ( 0 , word . length ) === word ) { return loadKeys ( nextKdx ) . delay ( 30 ) . then ( function ( more ) { _trail . offset = 0 ; _trail . block = nextKdx . index ; Array . prototype . push . apply ( list , more . filter ( filter , _trail ) ) ; return appendMore ( word , list , KEY_INDEX [ nextKdx . index + 1 ] , expectedSize , filter , ticket ) ; } ) ; } else { if ( list . length === 0 ) { _trail . exhausted = true ; } return resolve ( list ) ; } } else { var shortage = expectedSize - list . length ; if ( shortage > 0 && nextKdx ) { _trail . block = nextKdx . index ; return loadKeys ( nextKdx ) . then ( function ( more ) { _trail . offset = 0 ; _trail . pos = Math . min ( shortage , more . length ) ; Array . prototype . push . apply ( list , more . slice ( 0 , shortage ) ) ; return appendMore ( word , list , KEY_INDEX [ nextKdx . index + 1 ] , expectedSize , filter , ticket ) ; } ) ; } else { if ( _trail . pos > expectedSize ) { _trail . pos = expectedSize ; } list = list . slice ( 0 , expectedSize ) ; _trail . count = list . length ; _trail . total += _trail . count ; return resolve ( list ) ; } } } function followUp ( ) { var kdx = KEY_INDEX [ _trail . block ] ; return loadKeys ( kdx ) . then ( function ( list ) { return [ kdx , Math . min ( _trail . offset + _trail . pos , list . length - 1 ) , list ] ; } ) ; } function matchKeys ( phrase , expectedSize , follow ) { expectedSize = Math . max ( expectedSize || 0 , 10 ) ; var str = phrase . trim ( ) . toLowerCase ( ) , m = / ([^?*]+)[?*]+ / . exec ( str ) , word ; if ( m ) { word = m [ 1 ] ; var wildcard = new RegExp ( '^' + str . replace ( / ([\.\\\+\[\^\]\$\(\)]) / g , '\\$1' ) . replace ( / \*+ / g , '.*' ) . replace ( / \? / g , '.' ) + '$' ) , tester = phrase [ phrase . length - 1 ] === ' ' ? function ( s ) { return wildcard . test ( s ) ; } : function ( s ) { return wildcard . test ( s ) && ! /   / . test ( s ) ; } , filter = function ( s , i ) { if ( _trail . count < expectedSize && tester ( s ) ) { _trail . count ++ ; _trail . total ++ ; _trail . pos = i + 1 ; return true ; } return false ; } ; } else { word = phrase . trim ( ) ; } if ( _trail && _trail . phrase !== phrase ) { follow = false ; } if ( follow && _trail && _trail . exhausted ) { return resolve ( [ ] ) ; } var startFrom = follow && _trail ? followUp ( ) : seekVanguard ( word ) ; return startFrom . spread ( function ( kdx , idx , list ) { list = list . slice ( idx ) ; _trail = { phrase : phrase , block : kdx . index , offset : idx , pos : list . length , count : 0 , total : follow ? _trail && _trail . total || 0 : 0 } ; if ( filter ) { list = list . filter ( filter , _trail ) ; } return appendMore ( word , list , KEY_INDEX [ kdx . index + 1 ] , expectedSize , filter , ++ mutual_ticket ) . then ( function ( result ) { if ( _trail . block === KEY_INDEX . length - 1 ) { if ( _trail . offset + _trail . pos >= KEY_INDEX [ _trail . block ] . num_entries ) { _trail . exhausted = true ; // console.log('EXHAUSTED!!!!'); } } // console.log('trail: ', _trail);           return result ; } ) ; } ) ; } ; /**
     * Match the first element in list with given offset.
     */ function matchOffset ( list , offset ) { return list . some ( function ( el ) { return el . offset === offset ? list = [ el ] : false ; } ) ? list : [ ] ; } // Lookup functions var LOOKUP = { /**
       * @param query
       *          String
       *          {phrase: .., max: .., follow: true} object
       */ mdx : function ( query ) { if ( typeof query === 'string' || query instanceof String ) { _trail = null ; var word = query . trim ( ) . toLowerCase ( ) , offset = query . offset ; return seekVanguard ( word ) . spread ( function ( kdx , idx , list ) { list = list . slice ( idx ) ; if ( offset !== UNDEFINED ) { list = matchOffset ( list , offset ) ; } else { list = list . filter ( function ( el ) { return el . toLowerCase ( ) === word ; } ) ; } return harvest ( list . map ( findWord ) ) ; } ) ; } else { return matchKeys ( query . phrase , query . max , query . follow ) ; } } , // TODO: chain multiple mdd file mdd : function ( phrase ) { var word = phrase . trim ( ) . toLowerCase ( ) ; word = '\\' + word . replace ( / (^[/\\])|([/]$) / , '' ) ; word = word . replace ( / \/ / g , '\\' ) ; return seekVanguard ( word ) . spread ( function ( kdx , idx , list ) { return list . slice ( idx ) . filter ( function ( one ) { return one . toLowerCase ( ) === word ; } ) ; } ) . then ( function ( candidates ) { if ( candidates . length === 0 ) { throw '*RESOURCE NOT FOUND* ' + phrase ; } else { return findResource ( candidates [ 0 ] ) ; } } ) ; } } ; // ------------------------------------------ // start to load mdx/mdd file // ------------------------------------------ var pos = 0 ; // read first 4 bytes to get header length return _slice ( pos , 4 ) . exec ( read_file_head ) . then ( function ( len ) { len = parseInt ( len , 10 ) ; pos += 4 ; // start of header string in header section return _slice ( pos , len + 48 ) . exec ( read_header_sect , len ) ; } ) . then ( function ( ret ) { var header_remain_len = ret [ 0 ] ; var input = ret [ 1 ] ; pos += header_remain_len ; // start of keyword section return read_keyword_summary ( input , header_remain_len ) ; } ) . then ( function ( keyword_summary ) { pos += keyword_summary . len ; // start of key index in keyword section return _slice ( pos , keyword_summary . key_index_comp_len ) . exec ( read_keyword_index , keyword_summary ) ; } ) . then ( function ( data ) { var keyword_summary = data [ 0 ] ; var keyword_index = data [ 1 ] ; // console.log(data[1]); // console.log(data); pos += keyword_summary . key_index_comp_len ; // start of keyword block in keyword section slicedKeyBlock = _slice ( pos , keyword_summary . key_blocks_len ) ; // Now it's fast enough to look up word without key table, which scans keyword from the specified key blocks in an effcient way. // No need to scan the whole key table in ahead. // willScanKeyTable(slicedKeyBlock, keyword_summary.num_entries, keyword_index, 00); dasd; //  pos += keyword_summary . key_blocks_len ; // start of record section KEY_INDEX = keyword_index ; } ) . then ( function ( ) { return _slice ( pos , 32 ) . exec ( read_record_summary , pos ) ; } ) . spread ( function ( record_summary ) { pos += record_summary . len ; // start of record blocks in record section return _slice ( pos , record_summary . index_len ) . exec ( read_record_block , record_summary ) ; } ) . spread ( function ( ) { // resolve and return lookup() function according to file extension (mdx/mdd) LOOKUP [ ext ] . description = attrs . Description ; return resolve ( LOOKUP [ ext ] ) ; } ) ; }


Input: bind sliceThen () with file argument Config scanner according to dictionary attributes . [CODESPLIT] function config ( ) { attrs . Encoding = attrs . Encoding || 'UTF-16' ; _searchTextLen = ( attrs . Encoding === 'UTF-16' ) ? function ( dv , offset ) { offset = offset ; var mark = offset ; while ( dv . getUint16 ( offset ++ ) ) { /* scan for NUL */ } ; return offset - mark ; } : function ( dv , offset ) { offset = offset ; var mark = offset ; while ( dv . getUint8 ( offset ++ ) ) { /* scan for NUL */ } return offset - mark - 1 ; } ; _decoder = new TextDecoder ( attrs . Encoding || 'UTF-16LE' ) ; _bpu = ( attrs . Encoding === 'UTF-16' ) ? 2 : 1 ; if ( parseInt ( attrs . GeneratedByEngineVersion , 10 ) >= 2.0 ) { _v2 = true ; _tail = _bpu ; // HUGE dictionary file (>4G) is not supported, take only lower 32-bit _readNum = function ( scanner ) { return scanner . forward ( 4 ) , scanner . readInt ( ) ; } ; _readShort = function ( scanner ) { return scanner . readUint16 ( ) ; } ; _checksum_v2 = function ( scanner ) { return scanner . checksum ( ) ; } ; } else { _tail = 0 ; } // keyword index decrypted? if ( attrs . Encrypted & 0x02 ) { _decryptors [ 1 ] = decrypt ; } var regexp = common . REGEXP_STRIPKEY [ ext ] ; if ( isTrue ( attrs . KeyCaseSensitive ) ) { _adaptKey = isTrue ( attrs . StripKey ) ? function ( key ) { return key . replace ( regexp , '$1' ) ; } : function ( key ) { return key ; } ; } else { _adaptKey = isTrue ( attrs . StripKey || ( _v2 ? '' : 'yes' ) ) ? function ( key ) { return key . toLowerCase ( ) . replace ( regexp , '$1' ) ; } : function ( key ) { return key . toLowerCase ( ) ; } ; } }


Input: Read data in current offset from target data ArrayBuffer [CODESPLIT] function Scanner ( buf , len ) { var offset = 0 , dv = new DataView ( buf ) ; var methods = { // target data size in bytes size : function ( ) { return len || buf . byteLength ; } , // update offset to new position forward : function ( len ) { return offset += len ; } , // return current offset offset : function ( ) { return offset ; } , // MDict file format uses big endian to store number // 32-bit unsigned int readInt : function ( ) { return conseq ( dv . getUint32 ( offset , false ) , this . forward ( 4 ) ) ; } , readUint16 : function ( ) { return conseq ( dv . getUint16 ( offset , false ) , this . forward ( 2 ) ) ; } , readUint8 : function ( ) { return conseq ( dv . getUint8 ( offset , false ) , this . forward ( 1 ) ) ; } , // Read a "short" number representing keyword text size, 8-bit for version < 2, 16-bit for version >= 2 readShort : function ( ) { return _readShort ( this ) ; } , // Read a number representing offset or data block size, 16-bit for version < 2, 32-bit for version >= 2 readNum : function ( ) { return _readNum ( this ) ; } , readUTF16 : function ( len ) { return conseq ( UTF_16LE . decode ( newUint8Array ( buf , offset , len ) ) , this . forward ( len ) ) ; } , // Read data to an Uint8Array and decode it to text with specified encoding. // Text length in bytes is determined by searching terminated NUL. // NOTE: After decoding the text, it is need to forward extra "tail" bytes according to specified encoding.  readText : function ( ) { var len = _searchTextLen ( dv , offset ) ; return conseq ( _decoder . decode ( newUint8Array ( buf , offset , len ) ) , this . forward ( len + _bpu ) ) ; } , // Read data to an Uint8Array and decode it to text with specified encoding. // @param len length in basic unit, need to multiply byte per unit to get length in bytes // NOTE: After decoding the text, it is need to forward extra "tail" bytes according to specified encoding.  readTextSized : function ( len ) { len *= _bpu ; var read = conseq ( _decoder . decode ( newUint8Array ( buf , offset , len ) ) , this . forward ( len + _tail ) ) ; return read ; } , // Skip checksum, just ignore it anyway. checksum : function ( ) { this . forward ( 4 ) ; } , // Version >= 2.0 only checksum_v2 : function ( ) { return _checksum_v2 ( this ) ; } , // Read data block of keyword index, key block or record content. // These data block are maybe in compressed (gzip or lzo) format, while keyword index maybe be encrypted. // @see https://github.com/zhansliu/writemdict/blob/master/fileformat.md#compression (with typo mistake) readBlock : function ( len , expectedBufSize , decryptor ) { var comp_type = dv . getUint8 ( offset , false ) ; // compression type, 0 = non, 1 = lzo, 2 = gzip if ( comp_type === 0 ) { if ( _v2 ) { this . forward ( 8 ) ; // for version >= 2, skip comp_type (4 bytes with tailing \x00) and checksum (4 bytes) } return this ; } else { // skip comp_type (4 bytes with tailing \x00) and checksum (4 bytes) offset += 8 ; len -= 8 ; var tmp = new Uint8Array ( len ) ; buf . copy ( tmp , 0 , offset , offset + len ) ; if ( decryptor ) { var passkey = new Uint8Array ( 8 ) ; var q = new Buffer ( 4 ) ; buf . copy ( passkey , 0 , offset - 4 , offset ) ; // var q = new Buffer(4); passkey . set ( [ 0x95 , 0x36 , 0x00 , 0x00 ] , 4 ) ; // key part 2: fixed data tmp = decryptor ( tmp , passkey ) ; } tmp = comp_type === 2 ? pako . inflate ( tmp ) : lzo . decompress ( tmp , expectedBufSize , 1308672 ) ; this . forward ( len ) ; var d = new Buffer ( tmp ) ; return Scanner ( d , tmp . length ) ; } } , // Read raw data as Uint8Array from current offset with specified length in bytes readRaw : function ( len ) { return conseq ( newUint8Array ( buf , offset , len ) , this . forward ( len === UNDEFINED ? buf . length - offset : len ) ) ; } , } ; return Object . create ( methods ) ; }


Input: Read data to an Uint8Array and decode it to text with specified encoding . Text length in bytes is determined by searching terminated NUL . NOTE : After decoding the text it is need to forward extra tail bytes according to specified encoding . [CODESPLIT] function ( ) { var len = _searchTextLen ( dv , offset ) ; return conseq ( _decoder . decode ( newUint8Array ( buf , offset , len ) ) , this . forward ( len + _bpu ) ) ; }


Input: Read data to an Uint8Array and decode it to text with specified encoding . [CODESPLIT] function ( len ) { len *= _bpu ; var read = conseq ( _decoder . decode ( newUint8Array ( buf , offset , len ) ) , this . forward ( len + _tail ) ) ; return read ; }


Input: Read data block of keyword index key block or record content . These data block are maybe in compressed ( gzip or lzo ) format while keyword index maybe be encrypted . [CODESPLIT] function ( len , expectedBufSize , decryptor ) { var comp_type = dv . getUint8 ( offset , false ) ; // compression type, 0 = non, 1 = lzo, 2 = gzip if ( comp_type === 0 ) { if ( _v2 ) { this . forward ( 8 ) ; // for version >= 2, skip comp_type (4 bytes with tailing \x00) and checksum (4 bytes) } return this ; } else { // skip comp_type (4 bytes with tailing \x00) and checksum (4 bytes) offset += 8 ; len -= 8 ; var tmp = new Uint8Array ( len ) ; buf . copy ( tmp , 0 , offset , offset + len ) ; if ( decryptor ) { var passkey = new Uint8Array ( 8 ) ; var q = new Buffer ( 4 ) ; buf . copy ( passkey , 0 , offset - 4 , offset ) ; // var q = new Buffer(4); passkey . set ( [ 0x95 , 0x36 , 0x00 , 0x00 ] , 4 ) ; // key part 2: fixed data tmp = decryptor ( tmp , passkey ) ; } tmp = comp_type === 2 ? pako . inflate ( tmp ) : lzo . decompress ( tmp , expectedBufSize , 1308672 ) ; this . forward ( len ) ; var d = new Buffer ( tmp ) ; return Scanner ( d , tmp . length ) ; } }


Input: Read raw data as Uint8Array from current offset with specified length in bytes [CODESPLIT] function ( len ) { return conseq ( newUint8Array ( buf , offset , len ) , this . forward ( len === UNDEFINED ? buf . length - offset : len ) ) ; }


Input: Read header section parse dictionary attributes and config scanner according to engine version attribute . [CODESPLIT] function read_header_sect ( input , len ) { var scanner = Scanner ( input ) , header_str = scanner . readUTF16 ( len ) . replace ( / \0$ / , '' ) ; // need to remove tailing NUL // parse dictionary attributes var doc = new DOMParser ( ) . parseFromString ( header_str , 'text/xml' ) ; var elem = doc . getElementsByTagName ( 'Dictionary' ) [ 0 ] ; if ( ! elem ) { elem = doc . getElementsByTagName ( 'Library_Data' ) [ 0 ] ; } // console.log(doc.getElementsByTagName('Dictionary')[0].attributes); // var xml = parseXml(header_str).querySelector('Dictionary, Library_Data').attributes; for ( var i = 0 , item ; i < elem . attributes . length ; i ++ ) { item = elem . attributes [ i ] ; attrs [ item . nodeName ] = item . nodeValue ; } attrs . Encrypted = parseInt ( attrs . Encrypted , 10 ) || 0 ; config ( ) ; return spreadus ( len + 4 , input ) ; }


Input: Read keyword summary at the begining of keyword section . [CODESPLIT] function read_keyword_summary ( input , offset ) { var scanner = Scanner ( input ) ; scanner . forward ( offset ) ; return { num_blocks : scanner . readNum ( ) , num_entries : scanner . readNum ( ) , key_index_decomp_len : _v2 && scanner . readNum ( ) , // Ver >= 2.0 only key_index_comp_len : scanner . readNum ( ) , key_blocks_len : scanner . readNum ( ) , chksum : scanner . checksum_v2 ( ) , // extra field len : scanner . offset ( ) - offset , // actual length of keyword section, varying with engine version attribute } ; }


Input: Read keyword index part of keyword section . [CODESPLIT] function read_keyword_index ( input , keyword_summary ) { var scanner = Scanner ( input ) . readBlock ( keyword_summary . key_index_comp_len , keyword_summary . key_index_decomp_len , _decryptors [ 1 ] ) , keyword_index = Array ( keyword_summary . num_blocks ) , offset = 0 ; for ( var i = 0 , size ; i < keyword_summary . num_blocks ; i ++ ) { keyword_index [ i ] = { num_entries : conseq ( scanner . readNum ( ) , size = scanner . readShort ( ) ) , // UNUSED, can be ignored         //          first_size:  size = scanner.readShort(), first_word : conseq ( scanner . readTextSized ( size ) , size = scanner . readShort ( ) ) , // UNUSED, can be ignored //          last_size:   size = scanner.readShort(), last_word : scanner . readTextSized ( size ) , comp_size : size = scanner . readNum ( ) , decomp_size : scanner . readNum ( ) , // extra fields offset : offset , // offset of the first byte for the target key block in mdx/mdd file index : i // index of this key index, used to search previous/next block } ; offset += size ; } return spreadus ( keyword_summary , keyword_index ) ; }


Input: Read keyword entries inside a keyword block and fill KEY_TABLE . [CODESPLIT] function read_key_block ( scanner , kdx ) { var scanner = scanner . readBlock ( kdx . comp_size , kdx . decomp_size ) ; for ( var i = 0 ; i < kdx . num_entries ; i ++ ) { //        scanner.readNum(); scanner.readText(); var kk = [ scanner . readNum ( ) , scanner . readText ( ) ] ; } }


Input: Delay to scan key table for debug onyl . [CODESPLIT] function willScanKeyTable ( slicedKeyBlock , num_entries , keyword_index , delay ) { slicedKeyBlock . delay ( delay ) . then ( function ( input ) { var scanner = Scanner ( input ) ; for ( var i = 0 , size = keyword_index . length ; i < size ; i ++ ) { // common.log('z',keyword_index[i]); read_key_block ( scanner , keyword_index [ i ] ) ; } } ) ; }


Input: Read record summary at the begining of record section . [CODESPLIT] function read_record_summary ( input , pos ) { var scanner = Scanner ( input ) , record_summary = { num_blocks : scanner . readNum ( ) , num_entries : scanner . readNum ( ) , index_len : scanner . readNum ( ) , blocks_len : scanner . readNum ( ) , // extra field len : scanner . offset ( ) , // actual length of record section (excluding record block index), varying with engine version attribute } ; // start position of record block from head of mdx/mdd file record_summary . block_pos = pos + record_summary . index_len + record_summary . len ; return record_summary ; }


Input: Read record block index part in record section and fill RECORD_BLOCK_TABLE [CODESPLIT] function read_record_block ( input , record_summary ) { var scanner = Scanner ( input ) , size = record_summary . num_blocks , record_index = Array ( size ) , p0 = record_summary . block_pos , p1 = 0 ; RECORD_BLOCK_TABLE . alloc ( size + 1 ) ; for ( var i = 0 , rdx ; i < size ; i ++ ) { record_index [ i ] = rdx = { comp_size : scanner . readNum ( ) , decomp_size : scanner . readNum ( ) } ; RECORD_BLOCK_TABLE . put ( p0 , p1 ) ; p0 += rdx . comp_size ; p1 += rdx . decomp_size ; } RECORD_BLOCK_TABLE . put ( p0 , p1 ) ; }


Input: Read definition in text for given keyinfo object . [CODESPLIT] function read_definition ( input , block , keyinfo ) { var scanner = Scanner ( input ) . readBlock ( block . comp_size , block . decomp_size ) ; scanner . forward ( keyinfo . offset - block . decomp_offset ) ; return scanner . readText ( ) ; }


Input: Read content in ArrayBuffer for give keyinfo object [CODESPLIT] function read_object ( input , block , keyinfo ) { if ( input . byteLength > 0 ) { var scanner = Scanner ( input ) . readBlock ( block . comp_size , block . decomp_size ) ; scanner . forward ( keyinfo . offset - block . decomp_offset ) ; return scanner . readRaw ( keyinfo . size ) ; } else { throw '* OUT OF FILE RANGE * ' + keyinfo + ' @offset=' + block . comp_offset ; } }


Input: Find word definition for given keyinfo object . [CODESPLIT] function findWord ( keyinfo ) { var block = RECORD_BLOCK_TABLE . find ( keyinfo . offset ) ; return _slice ( block . comp_offset , block . comp_size ) . exec ( read_definition , block , keyinfo ) . spread ( function ( definition ) { return resolve ( followLink ( definition , LOOKUP . mdx ) ) ; } ) ; }


Input: Find resource ( image sound etc . ) for given keyinfo object . [CODESPLIT] function findResource ( keyinfo ) { var block = RECORD_BLOCK_TABLE . find ( keyinfo . offset ) ; return _slice ( block . comp_offset , block . comp_size ) . exec ( read_object , block , keyinfo ) . spread ( function ( blob ) { return resolve ( blob ) ; } ) ; }


Input: a oneway increased ticket used to cancel unfinished pattern match Reduce the key index array to an element which contains or is the nearest one matching a given phrase . [CODESPLIT] function reduce ( arr , phrase ) { var len = arr . length ; if ( len > 1 ) { len = len >> 1 ; return phrase > _adaptKey ( arr [ len - 1 ] . last_word ) ? reduce ( arr . slice ( len ) , phrase ) : reduce ( arr . slice ( 0 , len ) , phrase ) ; } else { return arr [ 0 ] ; } }


Input: Reduce the array to index of an element which contains or is the nearest one matching a given phrase . [CODESPLIT] function shrink ( arr , phrase ) { var len = arr . length , sub ; if ( len > 1 ) { len = len >> 1 ; var key = _adaptKey ( arr [ len ] ) ; if ( phrase < key ) { sub = arr . slice ( 0 , len ) ; sub . pos = arr . pos ; } else { sub = arr . slice ( len ) ; sub . pos = ( arr . pos || 0 ) + len ; } return shrink ( sub , phrase ) ; } else { return ( arr . pos || 0 ) + ( phrase <= _adaptKey ( arr [ 0 ] ) ? 0 : 1 ) ; } }


Input: Load keys for a keyword index object from mdx / mdd file . [CODESPLIT] function loadKeys ( kdx ) { if ( _cached_keys && _cached_keys . pilot === kdx . first_word ) { return resolve ( _cached_keys . list ) ; } else { return slicedKeyBlock . then ( function ( input ) { var scanner = Scanner ( input ) , list = Array ( kdx . num_entries ) ; scanner . forward ( kdx . offset ) ; scanner = scanner . readBlock ( kdx . comp_size , kdx . decomp_size ) ; for ( var i = 0 ; i < kdx . num_entries ; i ++ ) { var offset = scanner . readNum ( ) ; list [ i ] = new Object ( scanner . readText ( ) ) ; list [ i ] . offset = offset ; if ( i > 0 ) { list [ i - 1 ] . size = offset - list [ i - 1 ] . offset ; } } _cached_keys = { list : list , pilot : kdx . first_word } ; return list ; } ) ; } }


Input: Search for the first keyword match given phrase . [CODESPLIT] function seekVanguard ( phrase ) { phrase = _adaptKey ( phrase ) ; var kdx = reduce ( KEY_INDEX , phrase ) ; // look back for the first record block containing keyword for the specified phrase if ( phrase <= _adaptKey ( kdx . last_word ) ) { var index = kdx . index - 1 , prev ; while ( prev = KEY_INDEX [ index ] ) { if ( _adaptKey ( prev . last_word ) !== _adaptKey ( kdx . last_word ) ) { break ; } kdx = prev ; index -- ; } } return loadKeys ( kdx ) . then ( function ( list ) { var idx = shrink ( list , phrase ) ; // look back for the first matched keyword position while ( idx > 0 ) { if ( _adaptKey ( list [ -- idx ] ) !== _adaptKey ( phrase ) ) { idx ++ ; break ; } } return [ kdx , Math . min ( idx , list . length - 1 ) , list ] ; } ) ; }


Input: TODO : have to restrict max count to improve response Append more to word list according to a filter or expected size . [CODESPLIT] function appendMore ( word , list , nextKdx , expectedSize , filter , ticket ) { if ( ticket !== mutual_ticket ) { throw 'force terminated' ; } if ( filter ) { if ( _trail . count < expectedSize && nextKdx && nextKdx . first_word . substr ( 0 , word . length ) === word ) { return loadKeys ( nextKdx ) . delay ( 30 ) . then ( function ( more ) { _trail . offset = 0 ; _trail . block = nextKdx . index ; Array . prototype . push . apply ( list , more . filter ( filter , _trail ) ) ; return appendMore ( word , list , KEY_INDEX [ nextKdx . index + 1 ] , expectedSize , filter , ticket ) ; } ) ; } else { if ( list . length === 0 ) { _trail . exhausted = true ; } return resolve ( list ) ; } } else { var shortage = expectedSize - list . length ; if ( shortage > 0 && nextKdx ) { _trail . block = nextKdx . index ; return loadKeys ( nextKdx ) . then ( function ( more ) { _trail . offset = 0 ; _trail . pos = Math . min ( shortage , more . length ) ; Array . prototype . push . apply ( list , more . slice ( 0 , shortage ) ) ; return appendMore ( word , list , KEY_INDEX [ nextKdx . index + 1 ] , expectedSize , filter , ticket ) ; } ) ; } else { if ( _trail . pos > expectedSize ) { _trail . pos = expectedSize ; } list = list . slice ( 0 , expectedSize ) ; _trail . count = list . length ; _trail . total += _trail . count ; return resolve ( list ) ; } } }


Input: Match the first element in list with given offset . [CODESPLIT] function matchOffset ( list , offset ) { return list . some ( function ( el ) { return el . offset === offset ? list = [ el ] : false ; } ) ? list : [ ] ; }


Input: TODO : chain multiple mdd file [CODESPLIT] function ( phrase ) { var word = phrase . trim ( ) . toLowerCase ( ) ; word = '\\' + word . replace ( / (^[/\\])|([/]$) / , '' ) ; word = word . replace ( / \/ / g , '\\' ) ; return seekVanguard ( word ) . spread ( function ( kdx , idx , list ) { return list . slice ( idx ) . filter ( function ( one ) { return one . toLowerCase ( ) === word ; } ) ; } ) . then ( function ( candidates ) { if ( candidates . length === 0 ) { throw '*RESOURCE NOT FOUND* ' + phrase ; } else { return findResource ( candidates [ 0 ] ) ; } } ) ; }


Input: Determines whether the specified modifier keys match the modifier keys that were pressed . [CODESPLIT] function isValidModifierKeyCombo ( modifierKeys , e ) { var modifierKeyNames = [ 'alt' , 'ctrl' , 'meta' , 'shift' ] , numModKeys = modifierKeys . length , i , j , currModifierKey , isValid = true ; // check that all required modifier keys were pressed for ( i = 0 ; i < numModKeys ; i += 1 ) { if ( ! e [ modifierKeys [ i ] ] ) { isValid = false ; break ; } } // if the requirements were met, check for additional modifier keys if ( isValid ) { for ( i = 0 ; i < modifierKeyNames . length ; i += 1 ) { currModifierKey = modifierKeyNames [ i ] + 'Key' ; // if this key was pressed if ( e [ currModifierKey ] ) { // if there are required keys, check whether the current key // is required if ( numModKeys ) { isValid = false ; // if this is a required key, continue for ( j = 0 ; j < numModKeys ; j += 1 ) { if ( currModifierKey === modifierKeys [ j ] ) { isValid = true ; break ; } } } else { // no required keys, but one was pressed isValid = false ; } } // an extra key was pressed, don't check anymore if ( ! isValid ) { break ; } } } return isValid ; }


Input: Creates a function to get and set the specified key combination . [CODESPLIT] function createKeyComboFunction ( keyFunc , modifierKeys ) { return function ( keyCode , modifierKeyNames ) { var i , keyCombo = '' ; if ( arguments . length ) { if ( typeof keyCode === 'number' ) { keyFunc ( keyCode ) ; modifierKeys . length = 0 ; // clear the array if ( modifierKeyNames && modifierKeyNames . length ) { for ( i = 0 ; i < modifierKeyNames . length ; i += 1 ) { modifierKeys . push ( modifierKeyNames [ i ] + 'Key' ) ; } } } return this ; } for ( i = 0 ; i < modifierKeys . length ; i += 1 ) { keyCombo += modifierKeys [ i ] . slice ( 0 , - 3 ) + '+' ; } return keyCombo + keyFunc ( ) ; } ; }


Input: Event handler to insert or remove tabs and newlines on the keydown event for the tab or enter key . [CODESPLIT] function overrideKeyDown ( e ) { e = e || event ; // textarea elements can only contain text nodes which don't receive // keydown events, so the event target/srcElement will always be the // textarea element, however, prefer currentTarget in order to support // delegated events in compliant browsers var target = e . currentTarget || e . srcElement , // don't use the "this" keyword (doesn't work in old IE) key = e . keyCode , // the key code for the key that was pressed tab , // the string representing a tab tabLen , // the length of a tab text , // initial text in the textarea range , // the IE TextRange object tempRange , // used to calculate selection start and end positions in IE preNewlines , // the number of newline character sequences before the selection start (for IE) selNewlines , // the number of newline character sequences within the selection (for IE) initScrollTop , // initial scrollTop value used to fix scrolling in Firefox selStart , // the selection start position selEnd , // the selection end position sel , // the selected text startLine , // for multi-line selections, the first character position of the first line endLine , // for multi-line selections, the last character position of the last line numTabs , // the number of tabs inserted / removed in the selection startTab , // if a tab was removed from the start of the first line preTab , // if a tab was removed before the start of the selection whitespace , // the whitespace at the beginning of the first selected line whitespaceLen , // the length of the whitespace at the beginning of the first selected line CHARACTER = 'character' ; // string constant used for the Range.move methods // don't do any unnecessary work if ( ( target . nodeName && target . nodeName . toLowerCase ( ) !== 'textarea' ) || ( key !== tabKey && key !== untabKey && ( key !== 13 || ! autoIndent ) ) ) { return ; } // initialize variables used for tab and enter keys inWhitespace = false ; // this will be set to true if enter is pressed in the leading whitespace text = target . value ; // this is really just for Firefox, but will be used by all browsers that support // selectionStart and selectionEnd - whenever the textarea value property is reset, // Firefox scrolls back to the top - this is used to set it back to the original value // scrollTop is nonstandard, but supported by all modern browsers initScrollTop = target . scrollTop ; // get the text selection if ( typeof target . selectionStart === 'number' ) { selStart = target . selectionStart ; selEnd = target . selectionEnd ; sel = text . slice ( selStart , selEnd ) ; } else if ( document . selection ) { // IE range = document . selection . createRange ( ) ; sel = range . text ; tempRange = range . duplicate ( ) ; tempRange . moveToElementText ( target ) ; tempRange . setEndPoint ( 'EndToEnd' , range ) ; selEnd = tempRange . text . length ; selStart = selEnd - sel . length ; // whenever the value of the textarea is changed, the range needs to be reset // IE <9 (and Opera) use both \r and \n for newlines - this adds an extra character // that needs to be accounted for when doing position calculations with ranges // these values are used to offset the selection start and end positions if ( newlineLen > 1 ) { preNewlines = text . slice ( 0 , selStart ) . split ( newline ) . length - 1 ; selNewlines = sel . split ( newline ) . length - 1 ; } else { preNewlines = selNewlines = 0 ; } } else { return ; // cannot access textarea selection - do nothing } // tab / untab key - insert / remove tab if ( key === tabKey || key === untabKey ) { // initialize tab variables tab = aTab ; tabLen = tab . length ; numTabs = 0 ; startTab = 0 ; preTab = 0 ; // multi-line selection if ( selStart !== selEnd && sel . indexOf ( '\n' ) !== - 1 ) { // for multiple lines, only insert / remove tabs from the beginning of each line // find the start of the first selected line if ( selStart === 0 || text . charAt ( selStart - 1 ) === '\n' ) { // the selection starts at the beginning of a line startLine = selStart ; } else { // the selection starts after the beginning of a line // set startLine to the beginning of the first partially selected line // subtract 1 from selStart in case the cursor is at the newline character, // for instance, if the very end of the previous line was selected // add 1 to get the next character after the newline // if there is none before the selection, lastIndexOf returns -1 // when 1 is added to that it becomes 0 and the first character is used startLine = text . lastIndexOf ( '\n' , selStart - 1 ) + 1 ; } // find the end of the last selected line if ( selEnd === text . length || text . charAt ( selEnd ) === '\n' ) { // the selection ends at the end of a line endLine = selEnd ; } else if ( text . charAt ( selEnd - 1 ) === '\n' ) { // the selection ends at the start of a line, but no // characters are selected - don't indent this line endLine = selEnd - 1 ; } else { // the selection ends before the end of a line // set endLine to the end of the last partially selected line endLine = text . indexOf ( '\n' , selEnd ) ; if ( endLine === - 1 ) { endLine = text . length ; } } // tab key combo - insert tabs if ( tabKeyComboPressed ( key , e ) ) { numTabs = 1 ; // for the first tab // insert tabs at the beginning of each line of the selection target . value = text . slice ( 0 , startLine ) + tab + text . slice ( startLine , endLine ) . replace ( / \n / g , function ( ) { numTabs += 1 ; return '\n' + tab ; } ) + text . slice ( endLine ) ; // set start and end points if ( range ) { // IE range . collapse ( ) ; range . moveEnd ( CHARACTER , selEnd + ( numTabs * tabLen ) - selNewlines - preNewlines ) ; range . moveStart ( CHARACTER , selStart + tabLen - preNewlines ) ; range . select ( ) ; } else { // the selection start is always moved by 1 character target . selectionStart = selStart + tabLen ; // move the selection end over by the total number of tabs inserted target . selectionEnd = selEnd + ( numTabs * tabLen ) ; target . scrollTop = initScrollTop ; } } else if ( untabKeyComboPressed ( key , e ) ) { // if the untab key combo was pressed, remove tabs instead of inserting them if ( text . slice ( startLine ) . indexOf ( tab ) === 0 ) { // is this tab part of the selection? if ( startLine === selStart ) { // it is, remove it sel = sel . slice ( tabLen ) ; } else { // the tab comes before the selection preTab = tabLen ; } startTab = tabLen ; } target . value = text . slice ( 0 , startLine ) + text . slice ( startLine + preTab , selStart ) + sel . replace ( new RegExp ( '\n' + tab , 'g' ) , function ( ) { numTabs += 1 ; return '\n' ; } ) + text . slice ( selEnd ) ; // set start and end points if ( range ) { // IE // setting end first makes calculations easier range . collapse ( ) ; range . moveEnd ( CHARACTER , selEnd - startTab - ( numTabs * tabLen ) - selNewlines - preNewlines ) ; range . moveStart ( CHARACTER , selStart - preTab - preNewlines ) ; range . select ( ) ; } else { // set start first for Opera target . selectionStart = selStart - preTab ; // preTab is 0 or tabLen // move the selection end over by the total number of tabs removed target . selectionEnd = selEnd - startTab - ( numTabs * tabLen ) ; } } else { return ; // do nothing for invalid key combinations } } else { // single line selection // tab key combo - insert a tab if ( tabKeyComboPressed ( key , e ) ) { if ( range ) { // IE range . text = tab ; range . select ( ) ; } else { target . value = text . slice ( 0 , selStart ) + tab + text . slice ( selEnd ) ; target . selectionEnd = target . selectionStart = selStart + tabLen ; target . scrollTop = initScrollTop ; } } else if ( untabKeyComboPressed ( key , e ) ) { // if the untab key combo was pressed, remove a tab instead of inserting one // if the character before the selection is a tab, remove it if ( text . slice ( selStart - tabLen ) . indexOf ( tab ) === 0 ) { target . value = text . slice ( 0 , selStart - tabLen ) + text . slice ( selStart ) ; // set start and end points if ( range ) { // IE // collapses range and moves it by -1 tab range . move ( CHARACTER , selStart - tabLen - preNewlines ) ; range . select ( ) ; } else { target . selectionEnd = target . selectionStart = selStart - tabLen ; target . scrollTop = initScrollTop ; } } } else { return ; // do nothing for invalid key combinations } } } else if ( autoIndent ) { // Enter key // insert a newline and copy the whitespace from the beginning of the line // find the start of the first selected line if ( selStart === 0 || text . charAt ( selStart - 1 ) === '\n' ) { // the selection starts at the beginning of a line // do nothing special inWhitespace = true ; return ; } // see explanation under "multi-line selection" above startLine = text . lastIndexOf ( '\n' , selStart - 1 ) + 1 ; // find the end of the first selected line endLine = text . indexOf ( '\n' , selStart ) ; // if no newline is found, set endLine to the end of the text if ( endLine === - 1 ) { endLine = text . length ; } // get the whitespace at the beginning of the first selected line (spaces and tabs only) whitespace = text . slice ( startLine , endLine ) . match ( / ^[ \t]* / ) [ 0 ] ; whitespaceLen = whitespace . length ; // the cursor (selStart) is in the whitespace at beginning of the line // do nothing special if ( selStart < startLine + whitespaceLen ) { inWhitespace = true ; return ; } if ( range ) { // IE // insert the newline and whitespace range . text = '\n' + whitespace ; range . select ( ) ; } else { // insert the newline and whitespace target . value = text . slice ( 0 , selStart ) + '\n' + whitespace + text . slice ( selEnd ) ; // Opera uses \r\n for a newline, instead of \n, // so use newlineLen instead of a hard-coded value target . selectionEnd = target . selectionStart = selStart + newlineLen + whitespaceLen ; target . scrollTop = initScrollTop ; } } if ( e . preventDefault ) { e . preventDefault ( ) ; } else { e . returnValue = false ; return false ; } }


Input: Event handler to prevent the default action for the keypress event when tab or enter is pressed . Opera and Firefox also fire a keypress event when the tab or enter key is pressed . Opera requires that the default action be prevented on this event or the textarea will lose focus . [CODESPLIT] function overrideKeyPress ( e ) { e = e || event ; var key = e . keyCode ; if ( tabKeyComboPressed ( key , e ) || untabKeyComboPressed ( key , e ) || ( key === 13 && autoIndent && ! inWhitespace ) ) { if ( e . preventDefault ) { e . preventDefault ( ) ; } else { e . returnValue = false ; return false ; } } }


Input: Executes all registered extension functions for the specified hook . [CODESPLIT] function executeExtensions ( hook , args ) { var i , extensions = hooks [ hook ] || [ ] , len = extensions . length ; for ( i = 0 ; i < len ; i += 1 ) { extensions [ i ] . apply ( null , args ) ; } }


Input: @typedef { Object } tabOverride . utils~listenersObj [CODESPLIT] function createListeners ( handlerList ) { var i , len = handlerList . length , remove , add ; function loop ( func ) { for ( i = 0 ; i < len ; i += 1 ) { func ( handlerList [ i ] . type , handlerList [ i ] . handler ) ; } } // use the standard event handler registration method when available if ( document . addEventListener ) { remove = function ( elem ) { loop ( function ( type , handler ) { elem . removeEventListener ( type , handler , false ) ; } ) ; } ; add = function ( elem ) { // remove listeners before adding them to make sure they are not // added more than once remove ( elem ) ; loop ( function ( type , handler ) { elem . addEventListener ( type , handler , false ) ; } ) ; } ; } else if ( document . attachEvent ) { // support IE 6-8 remove = function ( elem ) { loop ( function ( type , handler ) { elem . detachEvent ( 'on' + type , handler ) ; } ) ; } ; add = function ( elem ) { remove ( elem ) ; loop ( function ( type , handler ) { elem . attachEvent ( 'on' + type , handler ) ; } ) ; } ; } return { add : add , remove : remove } ; }


Input: / * global threesixty : true [CODESPLIT] function generateImagesToPreload ( totalImages ) { for ( var i = 0 , images = [ ] , index ; i < totalImages ; i ++ ) { index = ( i < 10 ) ? '0' + i : i images . push ( 'https://github.com/rbartoli/threesixty/raw/master/example/images/sequence-' + index + '.png' ) } return images }


Input: Helper function that asynchronously converts ImapMessage instance to instance of Message class . [CODESPLIT] function ( imapMessage ) { var deferred = Q . defer ( ) ; var message = new Message ( ) ; imapMessage . on ( 'body' , function ( stream , info ) { var buffer = '' ; stream . on ( 'data' , function ( chunk ) { buffer += chunk . toString ( 'utf8' ) ; } ) ; stream . on ( 'end' , function ( ) { if ( info . which === 'TEXT' ) { message . body = buffer ; } else { message . headers = Imap . parseHeader ( buffer ) ; } } ) ; } ) ; imapMessage . on ( 'attributes' , function ( attrs ) { message . attributes = attrs ; } ) ; imapMessage . on ( 'end' , function ( ) { deferred . resolve ( message ) ; } ) ; return deferred . promise ; }


Input: GUID Partition Table [CODESPLIT] function GPT ( options ) { if ( ! ( this instanceof GPT ) ) { return new GPT ( options ) } options = options != null ? options : { } /** @type {Number} Storage device's block size in bytes */ this . blockSize = options . blockSize || 512 /** @type {String} GUID of the GUID Partition Table */ this . guid = options . guid || GPT . GUID . ZERO /** @type {Number} GPT format revision (?) */ this . revision = options . revision || 0 /** @type {Number} Size of the GPT header in bytes */ this . headerSize = options . headerSize || GPT . HEADER_SIZE /** @type {Number} GPT header's CRC32 checksum */ this . headerChecksum = 0 /** @type {Number} Logical block address of *this* GPT */ this . currentLBA = options . currentLBA || 1 /** @type {Number} Logical block address of the secondary GPT */ this . backupLBA = options . backupLBA || 0 /** @type {Number} Address of the first user-space usable logical block */ this . firstLBA = options . firstLBA || 34 /** @type {Number} Address of the last user-space usable logical block */ this . lastLBA = options . lastLBA || 0 /** @type {Number} LBA of partition table */ this . tableOffset = options . tableOffset || GPT . TABLE_OFFSET /** @type {Number} Number of partition table entries */ this . entries = options . entries || GPT . TABLE_ENTRIES /** @type {Number} Partition entry's size in bytes */ this . entrySize = options . entrySize || GPT . TABLE_ENTRY_SIZE /** @type {Number} Partition table's CRC32 checksum */ this . tableChecksum = 0 // Array of partition entries this . partitions = [ ] }


Input: Resolves . and .. elements in a path with directory names [CODESPLIT] function normalizeString ( path , allowAboveRoot ) { var res = '' var lastSegmentLength = 0 var lastSlash = - 1 var dots = 0 var code for ( var i = 0 ; i <= path . length ; i += 1 ) { if ( i < path . length ) code = path . charCodeAt ( i ) else if ( code === CHAR_FORWARD_SLASH ) break else code = CHAR_FORWARD_SLASH if ( code === CHAR_FORWARD_SLASH ) { if ( lastSlash === i - 1 || dots === 1 ) { // NOOP } else if ( lastSlash !== i - 1 && dots === 2 ) { if ( res . length < 2 || lastSegmentLength !== 2 || res . charCodeAt ( res . length - 1 ) !== CHAR_DOT || res . charCodeAt ( res . length - 2 ) !== CHAR_DOT ) { if ( res . length > 2 ) { var lastSlashIndex = res . lastIndexOf ( '/' ) if ( lastSlashIndex !== res . length - 1 ) { if ( lastSlashIndex === - 1 ) { res = '' lastSegmentLength = 0 } else { res = res . slice ( 0 , lastSlashIndex ) lastSegmentLength = res . length - 1 - res . lastIndexOf ( '/' ) } lastSlash = i dots = 0 continue } } else if ( res . length === 2 || res . length === 1 ) { res = '' lastSegmentLength = 0 lastSlash = i dots = 0 continue } } if ( allowAboveRoot ) { if ( res . length > 0 ) res += '/..' else res = '..' lastSegmentLength = 2 } } else { if ( res . length > 0 ) res += '/' + path . slice ( lastSlash + 1 , i ) else res = path . slice ( lastSlash + 1 , i ) lastSegmentLength = i - lastSlash - 1 } lastSlash = i dots = 0 } else if ( code === CHAR_DOT && dots !== - 1 ) { ++ dots } else { dots = - 1 } } return res }


Input: path . resolve ( [ from ... ] to ) [CODESPLIT] function resolve ( ) { var resolvedPath = '' var resolvedAbsolute = false var cwd for ( var i = arguments . length - 1 ; i >= - 1 && ! resolvedAbsolute ; i -= 1 ) { var path if ( i >= 0 ) { path = arguments [ i ] } else { if ( cwd === undefined ) { cwd = posix . dirname ( sketchSpecifics . cwd ( ) ) } path = cwd } path = sketchSpecifics . getString ( path , 'path' ) // Skip empty entries if ( path . length === 0 ) { continue } resolvedPath = path + '/' + resolvedPath resolvedAbsolute = path . charCodeAt ( 0 ) === CHAR_FORWARD_SLASH } // At this point the path should be resolved to a full absolute path, but // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path resolvedPath = normalizeString ( resolvedPath , ! resolvedAbsolute ) if ( resolvedAbsolute ) { if ( resolvedPath . length > 0 ) return '/' + resolvedPath else return '/' } else if ( resolvedPath . length > 0 ) { return resolvedPath } else { return '.' } }


Input: return gpt } [CODESPLIT] function readBackupGPT ( primaryGPT ) { var backupGPT = new GPT ( { blockSize : primaryGPT . blockSize } ) var buffer = Buffer . alloc ( 33 * primaryGPT . blockSize ) var offset = ( ( primaryGPT . backupLBA - 32 ) * blockSize ) fs . readSync ( fd , buffer , 0 , buffer . length , offset ) backupGPT . parseBackup ( buffer ) return backupGPT }


Input: PartitionEntry [CODESPLIT] function PartitionEntry ( options ) { if ( ! ( this instanceof PartitionEntry ) ) { return new PartitionEntry ( options ) } options = options != null ? options : { } /** @type {String} Type GUID */ this . type = options . type || GUID . ZERO /** @type {String} GUID */ this . guid = options . guid || GUID . ZERO /** @type {String} Partition label */ this . name = options . name || '' /** @type {Number} First addressable block address */ this . firstLBA = options . firstLBA || 0 /** @type {Number} Last addressable block address */ this . lastLBA = options . lastLBA || 0 // NOTE: Can't use this as uint64 as logical ops will cast to uint32; // Maybe revert to buffer, or use bitfield module? /** @type {Number} Attribute flags */ this . attr = options . attr || 0 }


Input: Limit the execution rate of a function using a leaky bucket algorithm . [CODESPLIT] function stopcock ( fn , options ) { options = Object . assign ( { queueSize : Math . pow ( 2 , 32 ) - 1 , bucketSize : 40 , interval : 1000 , limit : 2 } , options ) ; const bucket = new TokenBucket ( options ) ; const queue = [ ] ; let timer = null ; function shift ( ) { clearTimeout ( timer ) ; while ( queue . length ) { const delay = bucket . consume ( ) ; if ( delay > 0 ) { timer = setTimeout ( shift , delay ) ; break ; } const data = queue . shift ( ) ; data [ 2 ] ( fn . apply ( data [ 0 ] , data [ 1 ] ) ) ; } } function limiter ( ) { const args = arguments ; return new Promise ( ( resolve , reject ) => { if ( queue . length === options . queueSize ) { return reject ( new Error ( 'Queue is full' ) ) ; } queue . push ( [ this , args , resolve ] ) ; shift ( ) ; } ) ; } Object . defineProperty ( limiter , 'size' , { get : ( ) => queue . length } ) ; return limiter ; }


Input: Format quantity values either encode to hex or decode to BigNumber should intake null stringNumber number BN [CODESPLIT] function formatQuantity ( value , encode , pad ) { if ( [ 'string' , 'number' , 'object' ] . indexOf ( typeof value ) === - 1 || value === null ) { return value ; } const numberValue = numberToBN ( value ) ; const numPadding = numberValue . lt ( ten ) && pad === true && ! numberValue . isZero ( ) ? '0' : '' ; if ( numberToBN ( value ) . isNeg ( ) ) { throw new Error ( ` ${ numberValue . toString ( 10 ) } ` ) ; } return encode ? ` ${ numPadding } ${ numberValue . toString ( 16 ) } ` : numberValue ; }


Input: Format quantity or tag if tag bypass return else format quantity should intake null stringNumber number BN string tag [CODESPLIT] function formatQuantityOrTag ( value , encode ) { var output = value ; // eslint-disable-line // if the value is a tag, bypass if ( schema . tags . indexOf ( value ) === - 1 ) { output = formatQuantity ( value , encode ) ; } return output ; }


Input: FormatData under strict conditions hex prefix [CODESPLIT] function formatData ( value , byteLength ) { var output = value ; // eslint-disable-line var outputByteLength = 0 ; // eslint-disable-line // prefix only under strict conditions, else bypass if ( typeof value === 'string' ) { output = ` ${ padToEven ( stripHexPrefix ( value ) ) } ` ; outputByteLength = getBinarySize ( output ) ; } // format double padded zeros. if ( output === '0x00' ) { output = '0x0' ; } // throw if bytelength is not correct if ( typeof byteLength === 'number' && value !== null && output !== '0x' && output !== '0x0' // support empty values && ( ! / ^[0-9A-Fa-f]+$ / . test ( stripHexPrefix ( output ) ) || outputByteLength !== 2 + byteLength * 2 ) ) { throw new Error ( ` ${ output } ${ 2 + byteLength * 2 } ${ outputByteLength } ` ) ; } return output ; }


Input: Format object even with random RPC caviets [CODESPLIT] function formatObject ( formatter , value , encode ) { var output = Object . assign ( { } , value ) ; // eslint-disable-line var formatObject = null ; // eslint-disable-line // if the object is a string flag, then retreive the object if ( typeof formatter === 'string' ) { if ( formatter === 'Boolean|EthSyncing' ) { formatObject = Object . assign ( { } , schema . objects . EthSyncing ) ; } else if ( formatter === 'DATA|Transaction' ) { formatObject = Object . assign ( { } , schema . objects . Transaction ) ; } else { formatObject = Object . assign ( { } , schema . objects [ formatter ] ) ; } } // check if all required data keys are fulfilled if ( ! arrayContainsArray ( Object . keys ( value ) , formatObject . __required ) ) { // eslint-disable-line throw new Error ( ` ${ JSON . stringify ( value ) } ${ formatObject . __required . join ( ', ' ) } ` ) ; // eslint-disable-line } // assume formatObject is an object, go through keys and format each Object . keys ( formatObject ) . forEach ( ( valueKey ) => { if ( valueKey !== '__required' && typeof value [ valueKey ] !== 'undefined' ) { output [ valueKey ] = format ( formatObject [ valueKey ] , value [ valueKey ] , encode ) ; } } ) ; return output ; }


Input: Format array [CODESPLIT] function formatArray ( formatter , value , encode , lengthRequirement ) { var output = value . slice ( ) ; // eslint-disable-line var formatObject = formatter ; // eslint-disable-line // if the formatter is an array or data, then make format object an array data if ( formatter === 'Array|DATA' ) { formatObject = [ 'D' ] ; } // if formatter is a FilterChange and acts like a BlockFilter // or PendingTx change format object to tx hash array if ( formatter === 'FilterChange' && typeof value [ 0 ] === 'string' ) { formatObject = [ 'D32' ] ; } // enforce minimum value length requirements if ( encode === true && typeof lengthRequirement === 'number' && value . length < lengthRequirement ) { throw new Error ( ` ${ JSON . stringify ( value ) } ${ lengthRequirement } ${ value . length } ` ) ; // eslint-disable-line } // make new array, avoid mutation formatObject = formatObject . slice ( ) ; // assume formatObject is an object, go through keys and format each value . forEach ( ( valueKey , valueIndex ) => { // use key zero as formatter for all values, unless otherwise specified var formatObjectKey = 0 ; // eslint-disable-line // if format array is exact, check each argument against formatter argument if ( formatObject . length > 1 ) { formatObjectKey = valueIndex ; } output [ valueIndex ] = format ( formatObject [ formatObjectKey ] , valueKey , encode ) ; } ) ; return output ; }


Input: Format various kinds of data to RPC spec or into digestable JS objects [CODESPLIT] function format ( formatter , value , encode , lengthRequirement ) { var output = value ; // eslint-disable-line // if formatter is quantity or quantity or tag if ( formatter === 'Q' ) { output = formatQuantity ( value , encode ) ; } else if ( formatter === 'QP' ) { output = formatQuantity ( value , encode , true ) ; } else if ( formatter === 'Q|T' ) { output = formatQuantityOrTag ( value , encode ) ; } else if ( formatter === 'D' ) { output = formatData ( value ) ; // dont format data flagged objects like compiler output } else if ( formatter === 'D20' ) { output = formatData ( value , 20 ) ; // dont format data flagged objects like compiler output } else if ( formatter === 'D32' ) { output = formatData ( value , 32 ) ; // dont format data flagged objects like compiler output } else { // if value is an object or array if ( typeof value === 'object' && value !== null && Array . isArray ( value ) === false ) { output = formatObject ( formatter , value , encode ) ; } else if ( Array . isArray ( value ) ) { output = formatArray ( formatter , value , encode , lengthRequirement ) ; } } return output ; }


Input: Format RPC inputs generally to the node or TestRPC [CODESPLIT] function formatInputs ( method , inputs ) { return format ( schema . methods [ method ] [ 0 ] , inputs , true , schema . methods [ method ] [ 2 ] ) ; }


Input: / * Register methods for this model [CODESPLIT] function ( model , schema ) { function apply ( method , schema ) { Object . defineProperty ( model . prototype , method , { get : function ( ) { var h = { } ; for ( var k in schema . methods [ method ] ) { h [ k ] = schema . methods [ method ] [ k ] . bind ( this ) ; } return h ; } , configurable : true , } ) ; } for ( var method in schema . methods ) { if ( typeof schema . methods [ method ] === 'function' ) { model . prototype [ method ] = schema . methods [ method ] ; } else { apply ( method , schema ) ; } } }


Input: / * Register statics for this model [CODESPLIT] function ( model , schema ) { for ( var i in schema . statics ) { model [ i ] = schema . statics [ i ] ; } }


Input: Returns a merged set of yaml files [CODESPLIT] function ( files ) { if ( ! _ . isArray ( files ) ) { throw new Error ( 'Arguments to config-helper.mergeConfig should be an array' ) ; } var appConfig = { } ; files . forEach ( function ( filePath ) { if ( gruntFile . exists ( filePath ) ) { var fileConfig = gruntFile . readYAML ( filePath ) ; // Use lodash to do a 'deep merge' which only overwrites the properties // specified in previous config files, without wiping out their child properties. _ . merge ( appConfig , fileConfig ) ; } } ) ; return appConfig ; }


Input: Parses [CODESPLIT] function parseBinding ( node ) { consume ( ) ; // '@' var binding = [ ] , first = once ( true ) ; while ( hasNext ( ) ) { if ( validChar ( peek ( ) , first ( ) ) ) { binding [ binding . length ] = next ( ) ; } else { break ; } } if ( binding . length > 0 ) { node . binding = binding . join ( '' ) ; } else { throw "No binding name given at " + index + " for " + node . type ; } }


Input:
Parses the ( ... ) component of an array pattern . [CODESPLIT] function parseArrayList ( node ) { consume ( ) ; // '(' // a() matches the empty list. if ( peek ( ) === ')' ) { node . type = '()' ; return ; } while ( true ) { // The whole array may be matched with 'a(|)' or (preferably) 'a'. if ( peek ( ) === '|' ) { break ; } /**
       * Use clear() to allow whitespace on certain locations:
       * (n,n@x), (n, n@x), ( n , n@x ) are all accepted.
       * (n, n @x) is not accepted: bindings do not allow
       * any whitespace.
       */ clear ( ) ; stage1 ( node . nodes ) ; clear ( ) ; if ( peek ( ) !== ',' ) { break ; } consume ( ) ; // ',' } }


Input:
Parse a single property . Valid property names can contain upper - and lowercase letters _ $ and numbers . [CODESPLIT] function parseProperty ( node , proto ) { consume ( ) ; // '.' var name = [ ] , property , first = once ( true ) ; while ( hasNext ( ) && validChar ( peek ( ) , first ( ) ) ) { name [ name . length ] = next ( ) ; } if ( name . length > 0 ) { property = newNode ( proto ? ':' : '.' , node . nodes ) ; property . name = name . join ( '' ) ; /**
       * Properties may have type specifiers. This is the way to go
       * to match nested objects.
       *
       * e.g. 'o(.coord:o(.x, .y))' matches objects like
       *  '{coord: {x: 5, y: 7} }'
       */ if ( hasNext ( ) && peek ( ) === ':' ) { consume ( ) ; // '(' stage1 ( property . nodes ) ; } // The property value might be bound to a name if ( hasNext ( ) && peek ( ) === '@' ) { parseBinding ( property ) ; } } else { throw "No property name given at " + index + " for " + node . type ; } }


Input:
Parse the property list of an object pattern . [CODESPLIT] function parseProperties ( node ) { consume ( ) ; // '(' while ( true ) { clear ( ) ; /**
       * Properties always have to start with '.' or ':'
       * o(.x, :y) matches an object with at least an owned property
       * 'x' and a owned or inherited property 'y'.
       */ if ( peek ( ) === '.' ) { parseProperty ( node , false ) ; // own property } else if ( peek ( ) === ':' ) { parseProperty ( node , true ) ; // prototype property } else { unexpectedTokenException ( '. or :' ) ; } clear ( ) ; if ( peek ( ) !== ',' ) { break ; } consume ( ) ; // ',' } }


Input: Parse a list of literals . The type of literal is determined by the second parameter : a function to parse a certain type ( string numeric boolean date ) of literals [CODESPLIT] function parseLiteralList ( AST , parseFunction ) { consume ( ) ; // '(' while ( true ) { clear ( ) ; parseFunction ( AST ) ; clear ( ) ; if ( peek ( ) !== ',' ) { break ; } consume ( ) ; // ',' } }


Input: String literals might start with or [CODESPLIT] function extractStringLiteral ( ) { var literal = [ ] , enclosing = next ( ) ; if ( ! ( enclosing === '"' || enclosing === "'" ) ) { throw "Unexpected token at index " + index + " expected 'string' but found " + enclosing ; } while ( hasNext ( ) && peek ( ) !== enclosing ) { literal [ literal . length ] = next ( ) ; } consume ( ) ; // ' or " return literal . join ( '' ) ; }


Input: A string literal list may contain strings or regular expressions . [CODESPLIT] function parseStringLiteral ( AST ) { if ( peek ( ) === '/' ) { newNode ( extractRegex ( ) , newNode ( 'r=' , AST ) . nodes ) ; } else { newNode ( extractStringLiteral ( ) , newNode ( '=' , AST ) . nodes ) ; } }


Input:
Parse numeric literals like 1 1 . 05 . 05 8e5 ... [CODESPLIT] function parseNumericLiteral ( AST ) { var literal = [ ] , value ; while ( hasNext ( ) && validNum ( peek ( ) ) ) { literal [ literal . length ] = next ( ) ; } value = parseFloat ( literal . join ( '' ) ) ; /**
     * Thanks to CMS's answer on StackOverflow:
     * http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric
     */ if ( ! isNaN ( value ) && isFinite ( value ) ) { newNode ( value , newNode ( '=' , AST ) . nodes ) ; } else { unexpectedTokenException ( 'numeric' ) ; } }


Input: Matches any of ( a o n s b f d r _ ) [CODESPLIT] function parseGeneric ( AST , type ) { var node = newNode ( next ( ) , AST ) ; // Parse literal lists, e.g. s("a", "b", ...) if ( peek ( ) === '(' ) { switch ( type ) { case "s" : parseLiteralList ( node . nodes , parseStringLiteral ) ; break ; case "n" : parseLiteralList ( node . nodes , parseNumericLiteral ) ; break ; case "b" : parseLiteralList ( node . nodes , parseBooleanLiteral ) ; break ; case "d" : parseLiteralList ( node . nodes , parseDateLiteral ) ; break ; } node . type = '||' ; consume ( ) ; // ')' } if ( peek ( ) === '@' ) { parseBinding ( node ) ; } }


Input: Parser entry point [CODESPLIT] function stage1 ( AST ) { if ( hasNext ( ) ) { switch ( peek ( ) ) { case 'a' : parseArray ( AST ) ; break ; case 'o' : parseObject ( AST ) ; break ; default : if ( / [nsSbfdr_] / . test ( peek ( ) ) ) { parseGeneric ( AST , peek ( ) ) ; } else { unexpectedTokenException ( 'one of (a,o,n,s,S,b,f,d,r,_)' ) ; } } } return AST ; }


Input: curry takes a function and a partial list of arguments and returns a function that can be executed with the rest of the arguments . [CODESPLIT] function curry ( fun , args ) { return function ( x ) { return fun . apply ( bindingContext , args . concat ( [ x ] ) ) ; } ; }


Input:
bind acts like a predicate but it also binds a variable to a name and puts it in the binding context . The parameters are : n : the binding name p : the actual predicate associated with this binding v : the value that this function is executed on . [CODESPLIT] function bind ( n , p , v ) { var m = p ( v ) ; if ( m . result ) { // Throw an exception if the same name is bound multiple times.  if ( bindingContext . hasOwnProperty ( n ) ) { throw "Name '" + n + "' is already used in another binding." ; } bindingContext [ n ] = m . obj ? m . obj [ m . param ] : m . param ; } /**
     * When the rest of an array is matched, the binding value has to
     * be changed after executing bind. Thats because at bind time the
     * rest of the array is not known. Therefore the name of the last
     * binding is stored and can be retrieved in the continuing function.
     */ m . this_binding = n ; return m ; }


Input: / * matches exactly the same date object [CODESPLIT] function equalsDate ( x , o ) { return { result : x . getTime ( ) === o . getTime ( ) , param : x } ; }


Input: / * Match a property that is owned by the object [CODESPLIT] function hasProperty ( m , x , o ) { return testProperty ( m , x , o , o . hasOwnProperty ( x ) ) ; }


Input: / * Match a property somewhere in the prototype chain [CODESPLIT] function hasPrototypeProperty ( m , x , o ) { return testProperty ( m , x , o , x in o ) ; }


Input: or takes a list of predicate functions ( m ) and executes them on it s second parameter ( o ) . If one of the predicates return true then or returns true . Otherwise false . [CODESPLIT] function or ( m , o ) { var index , result = { result : false , param : o } ; for ( index = 0 ; index < m . length ; index ++ ) { if ( m [ index ] ( o ) . result ) { result . result = true ; break ; } } return result ; }


Input:
m is an array of predicates a is the array to match [CODESPLIT] function matchArray ( m , a ) { var from = 0 , rest = false , restBindingResult , index , matcher , item , matchResult , restOfArray = [ ] , i , result = { result : false , param : a } ; // If this isn't an array then it can't match if ( ! is ( a , '[object Array]' ) ) { return result ; } // If there are more matchers than array elements it also can't match unless the // last matcher is a rest matcher if ( m . length > a . length && ! m [ m . length - 1 ] . name ) { return result ; } /**
     * If there are no predicates at all, this matches because it is
     * already ensured that argument a is an array.
     */ if ( m . length === 0 ) { result . result = true ; return result ; } for ( index = 0 ; index < a . length ; index ++ ) { matcher = m [ index ] ; item = a [ index ] ; if ( ! matcher ) { return result ; } matchResult = matcher ( item ) ; if ( ! matchResult . result ) { return result ; } /**
       * If the rest of an array is matched, the predicate will
       * return an object that has a'rest' parameter. We can't
       * recognize the rest predicate by it's function name, because
       * it might be hidden behind a 'bind' call.
       */ if ( matchResult . rest ) { restBindingResult = matchResult ; from = index ; rest = true ; break ; } } if ( rest && restBindingResult . this_binding ) { for ( i = from ; i < a . length ; i ++ ) { restOfArray [ restOfArray . length ] = a [ i ] ; } bindingContext [ restBindingResult . this_binding ] = restOfArray ; } result . result = true ; return result ; }


Input: Compile a single level of the AST [CODESPLIT] function compileNode ( ast ) { var result = [ ] , index , node , matcher ; for ( index = 0 ; index < ast . length ; index ++ ) { node = ast [ index ] ; switch ( node . type ) { case 'a' : matcher = curry ( matchArray , [ compileNode ( node . nodes ) ] ) ; break ; case 'o' : matcher = curry ( matchObject , [ compileNode ( node . nodes ) ] ) ; break ; case '.' : matcher = curry ( hasProperty , [ compileNode ( node . nodes ) , node . name ] ) ; break ; case ':' : matcher = curry ( hasPrototypeProperty , [ compileNode ( node . nodes ) , node . name ] ) ; break ; case '=' : matcher = curry ( equals , [ node . nodes [ 0 ] . type ] ) ; break ; case 'd=' : matcher = curry ( equalsDate , [ node . nodes [ 0 ] . type ] ) ; break ; case 'r=' : matcher = curry ( matchesRegex , [ node . nodes [ 0 ] . type ] ) ; break ; case '||' : matcher = curry ( or , [ compileNode ( node . nodes ) ] ) ; break ; case 'n' : matcher = curry ( matchType , [ 'number' ] ) ; break ; case 's' : matcher = curry ( matchType , [ 'string' ] ) ; break ; case 'S' : matcher = matchNonBlankString ; break ; case 'b' : matcher = curry ( matchType , [ 'boolean' ] ) ; break ; case 'f' : matcher = curry ( matchType , [ 'function' ] ) ; break ; case '_' : matcher = any ; break ; case '|' : matcher = rest ; break ; case '()' : matcher = matchEmptyArray ; break ; case 'd' : matcher = curry ( matchInstanceOf , [ '[object Date]' ] ) ; break ; case 'r' : matcher = curry ( matchInstanceOf , [ '[object RegExp]' ] ) ; break ; default : throw "Unknown AST entity: " + node . type ; } // Bind requested. Wrap the matcher function with a call to bind. if ( node . binding ) { matcher = curry ( bind , [ node . binding , matcher ] ) ; } result [ result . length ] = matcher ; } return result ; }


Input: [ o 42 ] = > { o : 42 } [CODESPLIT] function arrayToObject ( array ) { var obj = { } , i ; if ( array . length % 2 !== 0 ) { throw "Missing handler for pattern" ; } for ( i = 0 ; i < array . length ; i += 2 ) { obj [ array [ i ] ] = array [ i + 1 ] ; } return obj ; }


Input: Returns name of given matched token [CODESPLIT] function getName ( tag ) { return tag . name ? tag . name . value . toLowerCase ( ) : ` ${ tag . type } ` ; }


Input: Consumes attribute value from given location [CODESPLIT] function eatAttributeValue ( stream ) { const start = stream . pos ; if ( eatQuoted ( stream ) ) { // Should return token that points to unquoted value. // Use stream readers’ public API to traverse instead of direct // manipulation const current = stream . pos ; let valueStart , valueEnd ; stream . pos = start ; stream . next ( ) ; valueStart = stream . start = stream . pos ; stream . pos = current ; stream . backUp ( 1 ) ; valueEnd = stream . pos ; const result = token ( stream , valueStart , valueEnd ) ; stream . pos = current ; return result ; } return eatPaired ( stream ) || eatUnquoted ( stream ) ; }


Input: Check if given character code is valid unquoted value [CODESPLIT] function isUnquoted ( code ) { return ! isNaN ( code ) && ! isQuote ( code ) && ! isSpace ( code ) && ! isTerminator ( code ) ; }


Input: sarcasm mark ( ! ) / * Sentiment Constructor To be instantiated for a certain language [CODESPLIT] function Sentiment ( args ) { this . path = args . path || "" ; this . language = args . language ; this . confidence = args . confidence || null ; this . synset = args . synset ; this . synsets = { } ; this . labeler = { } ; this . negations = def ( args . negations , [ "no" , "not" , "n't" , "never" ] ) ; this . modifiers = def ( args . modifiers , [ "RB" ] ) ; this . modifier = def ( args . modifier , function ( w ) { return _str . endsWith ( w , "ly" ) ; } ) ; this . tokenizer = def ( args . tokenizer , find_tokens ) ; }


Input: var syn = self . synsets [ id ] ; if ( _ . isUndefined ( syn )) { syn = def ( self . synsets [ id . replace ( / - 0 + / - ) ] [ 0 . 0 0 . 0 ] ) ; } return syn . slice ( 0 2 ) ; } } ; [CODESPLIT] function avgAssessment ( assessments , weighted ) { var w ; var s = 0 ; var n = 0 ; assessments . forEach ( function ( ws ) { w = weighted ( ws [ 0 ] ) ; s += w * ws [ 1 ] ; n += w ; } ) ; if ( n === 0 ) { return 0 ; } else { return s / n ; } }


Input: / * Auxiliary Functions Average of number vector ( 0 if empty ) [CODESPLIT] function avg ( vct ) { if ( vct . length === 0 ) { return 0 ; } return ( vct . reduce ( function ( a , c ) { return a + c ; } , 0 ) / vct . length ) ; }