Input: Tell the classifier that the given sample belongs to the given classes . [CODESPLIT] function ( sample , labels ) { labels = multilabelutils . normalizeOutputLabels ( labels ) ; for ( var i in labels ) this . allClasses [ labels [ i ] ] = true ; return this . trainOnlineRecursive ( sample , labels . map ( this . splitLabel ) , this . root ) ; }


Input: Recursive internal subroutine of trainOnline . [CODESPLIT] function ( sample , splitLabels , treeNode ) { var superlabels = { } ; // the first parts of each of the splitLabels var mapSuperlabelToRest = { } ; // each value is a list of continuations of the key.  for ( var i in splitLabels ) { var splitLabel = splitLabels [ i ] ; var superlabel = splitLabel [ 0 ] ; superlabels [ superlabel ] = true ; if ( splitLabel . length > 1 ) { if ( ! mapSuperlabelToRest [ superlabel ] ) mapSuperlabelToRest [ superlabel ] = [ ] ; mapSuperlabelToRest [ superlabel ] . push ( splitLabel . slice ( 1 ) ) ; } } treeNode . superlabelClassifier . trainOnline ( sample , Object . keys ( superlabels ) ) ; for ( var superlabel in mapSuperlabelToRest ) { if ( ! ( superlabel in treeNode . mapSuperlabelToBranch ) ) { treeNode . mapSuperlabelToBranch [ superlabel ] = { superlabelClassifier : this . newMultilabelClassifier ( ) , mapSuperlabelToBranch : { } } } this . trainOnlineRecursive ( sample , mapSuperlabelToRest [ superlabel ] , treeNode . mapSuperlabelToBranch [ superlabel ] ) ; } }


Input: Train the classifier with all the given documents . [CODESPLIT] function ( dataset ) { dataset = dataset . map ( function ( datum ) { var normalizedLabels = multilabelutils . normalizeOutputLabels ( datum . output ) ; for ( var i in normalizedLabels ) this . allClasses [ normalizedLabels [ i ] ] = true ; return { input : datum . input , output : normalizedLabels . map ( this . splitLabel ) } } , this ) ; // [ [ 'Offer', 'Leased Car', 'Without leased car' ], [ 'Offer', 'Working Hours', '9 hours' ] ] return this . trainBatchRecursive ( dataset , this . root ) ; }


Input:
Recursive internal subroutine of trainBatch . [CODESPLIT] function ( dataset , treeNode ) { var superlabelsDataset = [ ] ; var mapSuperlabelToRestDataset = { } ; dataset . forEach ( function ( datum ) { var splitLabels = datum . output ; // [ [ 'Offer', 'Leased Car', 'Without leased car' ], [ 'Offer', 'Working Hours', '9 hours' ] ] var superlabels = { } ; // the first parts of each of the splitLabels var mapSuperlabelToRest = { } ; // each value is a list of continuations of the key.  for ( var i in splitLabels ) { var splitLabel = splitLabels [ i ] ; //[ 'Offer', 'Leased Car', 'Without leased car' ] var superlabel = splitLabel [ 0 ] ; superlabels [ superlabel ] = true ; //superlabels['Offer'] = true if ( splitLabel . length > 1 ) { // if it have more than one label (superlabel) if ( ! mapSuperlabelToRest [ superlabel ] ) mapSuperlabelToRest [ superlabel ] = [ ] ; mapSuperlabelToRest [ superlabel ] . push ( splitLabel . slice ( 1 ) ) ; //['Leased Car', 'Without leased car'] } } /*			Sample of mapSuperlabelToRest
			{ Offer:
			[ [ 'Leased Car', 'Without leased car' ],
   			  [ 'Working Hours', '9 hours' ] ] }

			Sample of superlabelsDataset, initial dataset with superlabel instead of entire output
			'. [end]': 0.965080896043587 },
			output: [ 'Offer' ] } ]
*/ superlabelsDataset . push ( { input : datum . input , output : Object . keys ( superlabels ) } ) ; for ( var superlabel in mapSuperlabelToRest ) { if ( ! ( superlabel in mapSuperlabelToRestDataset ) ) mapSuperlabelToRestDataset [ superlabel ] = [ ] ; mapSuperlabelToRestDataset [ superlabel ] . push ( { input : datum . input , output : mapSuperlabelToRest [ superlabel ] } ) ; } } , this ) ; /*		Sample of mapSuperlabelToRestDataset
		{ Offer: [ { input: [Object], output: [["Leased Car","Without leased car"],["Working Hours","9 hours"]] } ] }
*/ // train the classifier only on superlabels treeNode . superlabelClassifier . trainBatch ( superlabelsDataset ) ; for ( var superlabel in mapSuperlabelToRestDataset ) { if ( ! ( superlabel in treeNode . mapSuperlabelToBranch ) ) { treeNode . mapSuperlabelToBranch [ superlabel ] = { superlabelClassifier : this . newMultilabelClassifier ( ) , mapSuperlabelToBranch : { } } } /*			train the next level classifier for a give superlabel classifier superlabel (from loop)
			with the dataset from new structure mapSuperlabelToRestDataset (see above)
*/ this . trainBatchRecursive ( mapSuperlabelToRestDataset [ superlabel ] , treeNode . mapSuperlabelToBranch [ superlabel ] ) ; } }


Input: Use the model trained so far to classify a new sample . [CODESPLIT] function ( sample , explain ) { var splitLabels = this . classifyRecursive ( sample , explain , this . root ) ; //console.log("splitLabels:"+JSON.stringify(splitLabels)); if ( explain > 0 ) { splitLabels . classes = splitLabels . classes . map ( this . joinLabel ) ; } else { splitLabels = splitLabels . map ( this . joinLabel ) ; } return splitLabels ; }


Input: Recursive internal subroutine of classify . [CODESPLIT] function ( sample , explain , treeNode , depth ) { if ( ! depth ) depth = 1 ; // classify the superlabel  var superlabelsWithExplain = treeNode . superlabelClassifier . classify ( sample , explain ) ; var superlabels = ( explain > 0 ? superlabelsWithExplain . classes : superlabelsWithExplain ) ; var splitLabels = [ ] ; if ( explain > 0 ) { var explanations = [ "depth=" + depth + ": " + superlabels , superlabelsWithExplain . explanation ] ; } // for all superlabels that were classified, may be there are more than one that were classified with it for ( var i in superlabels ) { var superlabel = superlabels [ i ] ; var splitLabel = [ superlabel ] ; // classifier of [Offer] types / second level / classifies Offer's parameters var branch = treeNode . mapSuperlabelToBranch [ superlabel ] ; if ( branch ) { // [ [ 'Without leased car' ] ] var branchLabelsWithExplain = this . classifyRecursive ( sample , explain , branch , depth + 1 ) ; var branchLabels = ( explain > 0 ? branchLabelsWithExplain . classes : branchLabelsWithExplain ) ; for ( var j in branchLabels ) splitLabels . push ( splitLabel . concat ( branchLabels [ j ] ) ) ; if ( explain > 0 ) explanations = explanations . concat ( branchLabelsWithExplain . explanation ) ; } else { splitLabels . push ( splitLabel ) ; } } return ( explain > 0 ? { classes : splitLabels , explanation : explanations } : splitLabels ) ; }


Input: Link to a FeatureLookupTable from a higher level in the hierarchy ( typically from an EnhancedClassifier ) used ONLY for generating meaningful explanations . [CODESPLIT] function ( featureLookupTable , treeNode ) { if ( treeNode . superlabelClassifier && treeNode . superlabelClassifier . setFeatureLookupTable ) treeNode . superlabelClassifier . setFeatureLookupTable ( featureLookupTable ) ; for ( var superlabel in treeNode . mapSuperlabelToBranch ) this . setFeatureLookupTableRecursive ( featureLookupTable , treeNode . mapSuperlabelToBranch [ superlabel ] ) ; }


Input: BinarySegmentation - Multi - label text classifier based on a segmentation scheme using base binary classifiers . [CODESPLIT] function ( opts ) { if ( ! ( 'binaryClassifierType' in opts ) ) { console . dir ( opts ) ; throw new Error ( "opts must contain binaryClassifierType" ) ; } if ( ! opts . binaryClassifierType ) { console . dir ( opts ) ; throw new Error ( "opts.binaryClassifierType is null" ) ; } this . binaryClassifierType = opts . binaryClassifierType ; this . classifier = new this . binaryClassifierType ( ) ; switch ( opts . segmentSplitStrategy ) { case 'shortestSegment' : this . segmentSplitStrategy = this . shortestSegmentSplitStrategy ; break ; case 'longestSegment' : this . segmentSplitStrategy = this . longestSegmentSplitStrategy ; break ; case 'cheapestSegment' : this . segmentSplitStrategy = this . cheapestSegmentSplitStrategy ; break ; default : this . segmentSplitStrategy = null ; } this . mapClassnameToClassifier = { } ; }


Input: / * Tell the classifier that the given sample belongs to the given classes . [CODESPLIT] function ( sample , classes ) { sample = this . sampleToFeatures ( sample , this . featureExtractors ) ; classes = hash . normalized ( classes ) ; for ( var positiveClass in classes ) { this . makeSureClassifierExists ( positiveClass ) ; this . mapClassnameToClassifier [ positiveClass ] . trainOnline ( sample , 1 ) ; } for ( var negativeClass in this . mapClassnameToClassifier ) { if ( ! classes [ negativeClass ] ) this . mapClassnameToClassifier [ negativeClass ] . trainOnline ( sample , 0 ) ; } }


Input: Train the classifier with all the given documents . [CODESPLIT] function ( dataset ) { // add ['start'] and ['end'] as a try to resolve Append:previous FP _ . map ( dataset , function ( num ) { num [ 'input' ] = "['start'] " + num [ 'input' ] + " ['end']" return num } ) ; this . classifier . trainBatch ( dataset ) }


Input: Internal function - use the model trained so far to classify a single segment of a sentence . [CODESPLIT] function ( segment , explain ) { var classes = this . classifySegment ( segment , explain ) ; if ( classes . classes . length == 0 ) { // FEATURES return [ '' , 0 , '' ] ; // return ['', 0]; } else { // HERE // console.log([classes.classes[0], classes.scores[classes.classes[0]]]) // FEATURES return [ classes . classes [ 0 ] , classes . scores [ classes . classes [ 0 ] ] , classes [ 'explanation' ] [ 'positive' ] ] ; // return [classes.classes[0], classes.scores[classes.classes[0]]]; } }


Input: protected function : Strategy of finding the cheapest segmentation ( - most probable segmentation ) using a dynamic programming algorithm . Based on : Morbini Fabrizio Sagae Kenji . Joint Identification and Segmentation of Domain - Specific Dialogue Acts for Conversational Dialogue Systems . ACL - HLT 2011 http : // www . citeulike . org / user / erelsegal - halevi / article / 10259046 [CODESPLIT] function ( words , accumulatedClasses , explain , explanations ) { //for (var start=0; start<=words.length; ++start) { //	for (var end=start+1; end<=words.length; ++end) { //		var segment = words.slice(start,end).join(" "); //		var bestClassAndProbability = this.bestClassOfSegment(segment, explain); //		if (bestClassAndProbability[1] != Infinity) //		{ //			var bestClass = bestClassAndProbability[0]; //			var bestClassProbability = bestClassAndProbability[1]; //		digraph.add(start, end, -bestClassProbability); //		} //	} //} var cheapest_paths = require ( "graph-paths" ) . cheapest_paths ; var mini = Infinity _ ( words . length ) . times ( function ( nn ) { cheapestSegmentClassificationCosts = cheapest_paths ( segmentClassificationCosts , nn ) ; _ . each ( cheapestSegmentClassificationCosts , function ( value , key , list ) { if ( value . cost < mini ) { mini = value . cost cheapestSentenceClassificationCost = value } } , this ) } , this ) cheapestSegmentClassificationCosts = cheapest_paths ( segmentClassificationCosts , 0 ) ; cheapestSentenceClassificationCost = cheapestSegmentClassificationCosts [ words . length ] ; var path = cheapestSentenceClassificationCost . path ; for ( var i = 0 ; i < path . length - 1 ; ++ i ) { // var segment = words.slice(cheapestClassificationPath[i],cheapestClassificationPath[i+1]).join(" "); var segment = words . slice ( path [ i ] , path [ i + 1 ] ) . join ( " " ) ; //HERE var segmentClassesWithExplain = this . classifySegment ( segment , explain ) ; var segmentClasses = ( segmentClassesWithExplain . classes ? segmentClassesWithExplain . classes : segmentClassesWithExplain ) ; if ( segmentClasses . length > 0 ) accumulatedClasses [ segmentClasses [ 0 ] ] = true ; // explanations = [] if ( explain > 0 ) { if ( segmentClasses . length > 0 ) explanations . push ( [ segmentClasses [ 0 ] , segment , [ path [ i ] , path [ i + 1 ] ] , segmentClassesWithExplain [ 'explanation' ] [ 'positive' ] ] ) } ; } }


Input: protected function : Strategy of classifying the shortest segments with a single class . [CODESPLIT] function ( words , accumulatedClasses , explain , explanations ) { var currentStart = 0 ; for ( var currentEnd = 1 ; currentEnd <= words . length ; ++ currentEnd ) { var segment = words . slice ( currentStart , currentEnd ) . join ( " " ) ; var segmentClassesWithExplain = this . classifySegment ( segment , explain ) ; var segmentClasses = ( segmentClassesWithExplain . classes ? segmentClassesWithExplain . classes : segmentClassesWithExplain ) ; if ( segmentClasses . length == 1 ) { // greedy algorithm: found a section with a single class - cut it and go on accumulatedClasses [ segmentClasses [ 0 ] ] = true ; currentStart = currentEnd ; if ( explain > 0 ) { explanations . push ( segment ) ; explanations . push ( segmentClassesWithExplain . explanation ) ; } ; } } }


Input:
protected function : Strategy of classifying the longest segments with a single class . [CODESPLIT] function ( words , accumulatedClasses , explain , explanations ) { var currentStart = 0 ; var segment = null ; var segmentClassesWithExplain = null ; var segmentClasses = null ; for ( var currentEnd = 1 ; currentEnd <= words . length ; ++ currentEnd ) { var nextSegment = words . slice ( currentStart , currentEnd ) . join ( " " ) ; var nextSegmentClassesWithExplain = this . classifySegment ( nextSegment , explain ) ; var nextSegmentClasses = ( nextSegmentClassesWithExplain . classes ? nextSegmentClassesWithExplain . classes : nextSegmentClassesWithExplain ) ; //console.log("\t"+JSON.stringify(nextSegment) +" -> "+nextSegmentClasses) nextSegmentClasses . sort ( ) ; if ( segmentClasses && segmentClasses . length == 1 && ( nextSegmentClasses . length > 1 || ! _ ( nextSegmentClasses ) . isEqual ( segmentClasses ) ) ) { // greedy algorithm: found a section with a single class - cut it and go on accumulatedClasses [ segmentClasses [ 0 ] ] = true ; currentStart = currentEnd - 1 ; if ( explain > 0 ) { explanations . push ( segment ) ; explanations . push ( segmentClassesWithExplain . explanation ) ; } ; } segment = nextSegment ; segmentClassesWithExplain = nextSegmentClassesWithExplain ; segmentClasses = nextSegmentClasses ; } // add the classes of the last section: for ( var i in segmentClasses ) accumulatedClasses [ segmentClasses [ i ] ] = true ; if ( explain > 0 ) { explanations . push ( segment ) ; explanations . push ( segmentClassesWithExplain . explanation ) ; } ; /*if (words.length>20)  {
			console.dir(explanations);
			process.exit(1);
		}*/ }


Input: Use the model trained so far to classify a new sample . [CODESPLIT] function ( sentence , explain ) { // sentence = "['start'] " + sentence + " ['end']" var minWordsToSplit = 2 ; var words = sentence . split ( /   / ) ; // var words = tokenizer.tokenize(sentence); if ( this . segmentSplitStrategy && words . length >= minWordsToSplit ) { var accumulatedClasses = { } ; var explanations = [ ] ; this . segmentSplitStrategy ( words , accumulatedClasses , explain , explanations ) ; var classes = Object . keys ( accumulatedClasses ) ; return ( explain > 0 ? { classes : classes , explanation : explanations } : classes ) ; } else { classification = this . bestClassOfSegment ( sentence , explain ) // classification = this.classifySegment(sentence, explain); //HERER // console.log(sentence) // console.log(classification) // process.exit(0) // process.exit(0) return ( explain > 0 ? { classes : classification [ 0 ] , // FEATURES explanation : [ [ classification [ 0 ] , sentence , [ 0 , sentence . length - 1 ] , classification [ 2 ] ] ] // explanation: [[classification[0], sentence, [0,sentence.length-1]]] } : classification [ 0 ] ) ; // return {classes: classification[0], // explanation: [[classification[0], sentence, [0,sentence.length-1]]]} // return {classes: classification.classes[0]} } }


Input: Multilabel online classifier based on Perceptron and Passive - Aggressive . [CODESPLIT] function ( opts ) { this . retrain_count = opts . retrain_count || 10 ; this . Constant = opts . Constant || 5.0 ; this . weights = { //DUMMY_CLASS:{} } ; this . weights_sum = { //DUMMY_CLASS:{} } ; this . seenFeatures = { } ; this . num_iterations = 0 }


Input: Tell the classifier that the given sample belongs to the given classes . [CODESPLIT] function ( sample , classes ) { var classesSet = hash . normalized ( classes ) ; var ranks = this . predict ( sample , /*averaging=*/ false ) ; // pairs of [class,score] sorted by decreasing score // find the lowest ranked relevant label r: var r = 0 var r_score = Number . MAX_VALUE ranks . forEach ( function ( labelAndScore ) { var label = labelAndScore [ 0 ] ; var score = labelAndScore [ 1 ] ; if ( ( label in classesSet ) && score < r_score ) { r = label r_score = score } } ) ; // find the highest ranked irrelevant label s var s = 0 var s_score = - Number . MAX_VALUE ranks . reverse ( ) ; ranks . forEach ( function ( labelAndScore ) { var label = labelAndScore [ 0 ] ; var score = labelAndScore [ 1 ] ; if ( ! ( label in classesSet ) && score > s_score ) { s = label ; s_score = score ; } } ) ; var loss = Math . max ( 1.0 - r_score , 0.0 ) + Math . max ( 1.0 + s_score , 0.0 ) ; if ( loss > 0 ) { var sample_norm2 = hash . sum_of_square_values ( sample ) ; var tau = Math . min ( this . Constant , loss / sample_norm2 ) ; if ( r_score < Number . MAX_VALUE ) hash . addtimes ( this . weights [ r ] , tau , sample ) ; // weights[r] += tau*sample if ( s_score > - Number . MAX_VALUE ) hash . addtimes ( this . weights [ s ] , - tau , sample ) ; // weights[s] -= tau*sample } // this.weights_sum = (this.weights + this.weights_sum); for ( category in this . weights ) hash . add ( this . weights_sum [ category ] , this . weights [ category ] ) ; hash . add ( this . seenFeatures , sample ) ; this . num_iterations += 1 ; }


Input: Train the classifier with all the given documents . [CODESPLIT] function ( dataset ) { // preprocessing: add all the classes in the dataset to the weights vector; dataset . forEach ( function ( datum ) { this . addClasses ( datum . output ) ; this . editFeatureValues ( datum . input , /*remove_unknown_features=*/ false ) ; } , this ) ; for ( var i = 0 ; i < this . retrain_count ; ++ i ) dataset . forEach ( function ( datum ) { this . update ( datum . input , datum . output ) ; } , this ) ; }


Input: Use the model trained so far to classify a new sample . [CODESPLIT] function ( features , explain , withScores ) { this . editFeatureValues ( features , /*remove_unknown_features=*/ true ) ; var scoresVector = this . predict ( features , /*averaging=*/ true , explain ) ; return multilabelutils . mapScoresVectorToMultilabelResult ( scoresVector , explain , withScores , /*threshold=*/ 0 ) ; }


Input: Tell the classifier that the given classes will be used for the following samples so that it will know to add negative samples to classes that do not appear . [CODESPLIT] function ( classes ) { classes = hash . normalized ( classes ) ; for ( var aClass in classes ) { if ( ! ( aClass in this . weights ) ) { this . weights [ aClass ] = { } ; this . weights_sum [ aClass ] = { } ; } } }


Input: PartialClassification is a test classifier that learns and classifies the components of the labels separately according to the splitLabel routine . One of the examples could be classifying intent attribute value separately by three different classifiers . When performing test by trainAndTest module there is a check for toFormat routine if it exists then pretest format converting occurs . [CODESPLIT] function ( opts ) { opts = opts || { } ; if ( ! opts . multilabelClassifierType ) { console . dir ( opts ) ; throw new Error ( "opts.multilabelClassifierType is null" ) ; } if ( ! opts . numberofclassifiers ) { console . dir ( opts ) ; throw new Error ( "opts.numberofclassifiers is null" ) ; } // this.splitLabel = opts.splitLabel || function(label)      {return label.split(/@/);} this . classifier = this . intializeClassifiers ( opts . numberofclassifiers , opts . multilabelClassifierType ) }


Input: github . com / erelsgl / limdu / blob / d61166c91a81daee62e3d67d5fff2b06cee8191f / utils / PrecisionRecall . js [CODESPLIT] function ( ) { this . count = 0 ; this . TP = 0 ; this . TN = 0 ; this . FP = 0 ; this . FN = 0 ; this . TRUE = 0 ; this . startTime = new Date ( ) ; this . labels = { } this . dep = { } this . confusion = { } }


Input: Record the result of a new binary experiment . [CODESPLIT] function ( expected , actual ) { this . count ++ ; if ( expected && actual ) this . TP ++ ; if ( ! expected && actual ) this . FP ++ ; if ( expected && ! actual ) this . FN ++ ; if ( ! expected && ! actual ) this . TN ++ ; if ( expected == actual ) this . TRUE ++ ; }


Input: Record the result of a new classes experiment per labels . [CODESPLIT] function ( expectedClasses , actualClasses ) { var explanations = [ ] ; actualClasses = hash . normalized ( actualClasses ) ; expectedClasses = hash . normalized ( expectedClasses ) ; var allTrue = true ; if ( ! ( Object . keys ( expectedClasses ) [ 0 ] in this . confusion ) ) this . confusion [ Object . keys ( expectedClasses ) [ 0 ] ] = { } if ( ! ( Object . keys ( actualClasses ) [ 0 ] in this . confusion [ Object . keys ( expectedClasses ) [ 0 ] ] ) ) this . confusion [ Object . keys ( expectedClasses ) [ 0 ] ] [ Object . keys ( actualClasses ) [ 0 ] ] = 0 this . confusion [ Object . keys ( expectedClasses ) [ 0 ] ] [ Object . keys ( actualClasses ) [ 0 ] ] += 1 for ( var actualClass in actualClasses ) { if ( ! ( actualClass in this . confusion ) ) this . confusion [ actualClass ] = { } if ( ! ( actualClass in this . labels ) ) { this . labels [ actualClass ] = { } this . labels [ actualClass ] [ 'TP' ] = 0 this . labels [ actualClass ] [ 'FP' ] = 0 this . labels [ actualClass ] [ 'FN' ] = 0 } if ( actualClass in expectedClasses ) { this . labels [ actualClass ] [ 'TP' ] += 1 } else { this . labels [ actualClass ] [ 'FP' ] += 1 } } for ( var expectedClass in expectedClasses ) { if ( ! ( expectedClass in this . labels ) ) { this . labels [ expectedClass ] = { } this . labels [ expectedClass ] [ 'TP' ] = 0 this . labels [ expectedClass ] [ 'FP' ] = 0 this . labels [ expectedClass ] [ 'FN' ] = 0 } if ( ! ( expectedClass in actualClasses ) ) { this . labels [ expectedClass ] [ 'FN' ] += 1 } } }


Input: Record the result of a new classes experiment . [CODESPLIT] function ( expectedClasses , actualClasses , logTruePositives ) { var explanations = [ ] ; actualClasses = hash . normalized ( actualClasses ) ; expectedClasses = hash . normalized ( expectedClasses ) ; var allTrue = true ; for ( var actualClass in actualClasses ) { if ( actualClass in expectedClasses ) { if ( logTruePositives ) explanations . push ( "\t\t+++ TRUE POSITIVE: " + actualClass ) ; this . TP ++ ; } else { explanations . push ( "\t\t--- FALSE POSITIVE: " + actualClass ) ; this . FP ++ ; allTrue = false ; } } for ( var expectedClass in expectedClasses ) { if ( ! ( expectedClass in actualClasses ) ) { explanations . push ( "\t\t--- FALSE NEGATIVE: " + expectedClass ) ; this . FN ++ ; allTrue = false ; } } if ( allTrue ) { if ( logTruePositives ) explanations . push ( "\t\t*** ALL TRUE!" ) ; this . TRUE ++ ; } this . count ++ ; return explanations ; }


Input: Record the result of a new classes experiment in a hash manner . Doesn t allowed to do a inner output all stats are put in hash [CODESPLIT] function ( expectedClasses , actualClasses , logTruePositives ) { var explanations = { } ; explanations [ 'TP' ] = [ ] ; explanations [ 'FP' ] = [ ] ; explanations [ 'FN' ] = [ ] ; actualClasses = hash . normalized ( actualClasses ) ; expectedClasses = hash . normalized ( expectedClasses ) ; var allTrue = true ; for ( var actualClass in actualClasses ) { if ( actualClass in expectedClasses ) { if ( logTruePositives ) explanations [ 'TP' ] . push ( actualClass ) ; this . TP ++ ; } else { explanations [ 'FP' ] . push ( actualClass ) ; this . FP ++ ; allTrue = false ; } } for ( var expectedClass in expectedClasses ) { if ( ! ( expectedClass in actualClasses ) ) { explanations [ 'FN' ] . push ( expectedClass ) ; this . FN ++ ; allTrue = false ; } } if ( allTrue ) { // if ((logTruePositives)&& (!only_false_cases)) explanations.push("\t\t*** ALL TRUE!"); this . TRUE ++ ; } this . count ++ ; _ . each ( explanations , function ( value , key , list ) { // explanations[key] = _.sortBy(explanations[key], function(num){ num }); explanations [ key ] . sort ( ) } , this ) if ( explanations [ 'FP' ] . length == 0 ) delete explanations [ 'FP' ] if ( explanations [ 'FN' ] . length == 0 ) delete explanations [ 'FN' ] return explanations ; }


Input: example of usage see in test [CODESPLIT] function ( expectedClasses , actualClasses , logTruePositives ) { var ex = [ ] var ac = [ ] var matchlist = [ ] // clean up expected list _ . each ( expectedClasses , function ( expected , key , list ) { if ( ( expected . length == 2 ) || ( expected . length == 3 ) ) ex . push ( expected ) } , this ) // ac = actualClasses // // filtering actual classes		 // _.each(actualClasses, function(actual, key, list){  // 	var found = _.filter(ac, function(num){ return ((num[0] == actual[0]) && (this.intersection(num[1], actual[1]) == true)) }, this); // 	if (found.length == 0) // 		ac.push(actual) // }, this) // console.log(JSON.stringify(actualClasses, null, 4)) // var ac = this.uniquecandidate(this.uniqueaggregate(actualClasses)) var ac = actualClasses // filling interdependencies between labels  // for every candidate (actual) it looks for intersection between actual labels with different  // intents, intersection means that different intents came to the common substring, then arrange  // all the data in the hash, and mention only keyphrases. _ . each ( ac , function ( actual , key , list ) { if ( actual . length > 3 ) { label = actual [ 0 ] // keyphrase str = actual [ 2 ] if ( ! ( label in this . dep ) ) { this . dep [ label ] = { } this . dep [ label ] [ label ] = [ ] } this . dep [ label ] [ label ] . push ( str ) // intersection, different intents but actual intersection var found = _ . filter ( ac , function ( num ) { return ( ( num [ 0 ] != actual [ 0 ] ) && ( this . intersection ( num [ 1 ] , actual [ 1 ] ) == true ) ) } , this ) ; _ . each ( found , function ( sublabel , key , list ) { if ( ! ( sublabel [ 0 ] in this . dep [ label ] ) ) this . dep [ label ] [ sublabel [ 0 ] ] = [ ] this . dep [ label ] [ sublabel [ 0 ] ] . push ( [ [ actual [ 2 ] , actual [ 4 ] ] , [ sublabel [ 2 ] , sublabel [ 4 ] ] ] ) } , this ) } } , this ) var explanations = { } ; explanations [ 'TP' ] = [ ] ; explanations [ 'FP' ] = [ ] ; explanations [ 'FN' ] = [ ] ; var explanations_detail = { } ; explanations_detail [ 'TP' ] = [ ] ; explanations_detail [ 'FP' ] = [ ] ; explanations_detail [ 'FN' ] = [ ] ; var allTrue = true ; for ( var actualClassindex in ac ) { if ( ! ( ac [ actualClassindex ] [ 0 ] in this . labels ) ) { this . labels [ ac [ actualClassindex ] [ 0 ] ] = { } this . labels [ ac [ actualClassindex ] [ 0 ] ] [ 'TP' ] = 0 this . labels [ ac [ actualClassindex ] [ 0 ] ] [ 'FP' ] = 0 this . labels [ ac [ actualClassindex ] [ 0 ] ] [ 'FN' ] = 0 } var found = false _ . each ( ex , function ( exc , key , list ) { if ( ac [ actualClassindex ] [ 0 ] == exc [ 0 ] ) { if ( ( exc [ 1 ] . length == 0 ) || ( ac [ actualClassindex ] [ 1 ] [ 0 ] == - 1 ) ) { found = true matchlist . push ( ac [ actualClassindex ] ) } else { if ( this . intersection ( ac [ actualClassindex ] [ 1 ] , exc [ 1 ] ) ) { found = true matchlist . push ( ac [ actualClassindex ] ) } } } } , this ) if ( found ) { if ( logTruePositives ) { explanations [ 'TP' ] . push ( ac [ actualClassindex ] [ 0 ] ) ; explanations_detail [ 'TP' ] . push ( ac [ actualClassindex ] ) ; this . labels [ ac [ actualClassindex ] [ 0 ] ] [ 'TP' ] += 1 this . TP ++ } } else { explanations [ 'FP' ] . push ( ac [ actualClassindex ] [ 0 ] ) ; explanations_detail [ 'FP' ] . push ( ac [ actualClassindex ] ) ; this . labels [ ac [ actualClassindex ] [ 0 ] ] [ 'FP' ] += 1 this . FP ++ allTrue = false ; } } for ( var expectedClassindex in ex ) { var found = false if ( ! ( ex [ expectedClassindex ] [ 0 ] in this . labels ) ) { this . labels [ ex [ expectedClassindex ] [ 0 ] ] = { } this . labels [ ex [ expectedClassindex ] [ 0 ] ] [ 'TP' ] = 0 this . labels [ ex [ expectedClassindex ] [ 0 ] ] [ 'FP' ] = 0 this . labels [ ex [ expectedClassindex ] [ 0 ] ] [ 'FN' ] = 0 } _ . each ( ac , function ( acc , key , list ) { if ( ex [ expectedClassindex ] [ 0 ] == acc [ 0 ] ) { if ( ( ex [ expectedClassindex ] [ 1 ] . length == 0 ) || ( acc [ 1 ] [ 0 ] == - 1 ) ) found = true else { if ( this . intersection ( ex [ expectedClassindex ] [ 1 ] , acc [ 1 ] ) ) found = true } } } , this ) if ( ! found ) { explanations [ 'FN' ] . push ( ex [ expectedClassindex ] [ 0 ] ) ; explanations_detail [ 'FN' ] . push ( ex [ expectedClassindex ] ) ; this . labels [ ex [ expectedClassindex ] [ 0 ] ] [ 'FN' ] += 1 this . FN ++ ; allTrue = false ; } } if ( allTrue ) { // if ((logTruePositives)&& (!only_false_cases)) explanations.push("\t\t*** ALL TRUE!"); this . TRUE ++ ; } this . count ++ ; // _.each(explanations, function(value, key, list){  // explanations[key] = _.sortBy(explanations[key], function(num){ num }); // explanations[key].sort() // }, this) // console.log(explanations) // console.log(matchlist) // if (expectedClasses.length > 1) // process.exit(0) return { 'explanations' : explanations , 'match' : matchlist , 'explanations_detail' : explanations_detail } }


Input: simple intersection [CODESPLIT] function ( begin , end ) { if ( ( begin [ 0 ] <= end [ 0 ] ) && ( begin [ 1 ] >= end [ 0 ] ) ) return true if ( ( begin [ 0 ] >= end [ 0 ] ) && ( begin [ 0 ] <= end [ 1 ] ) ) return true return false }


Input: for explanations [CODESPLIT] function WinnowHash ( opts ) { if ( ! opts ) opts = { } this . debug = opts . debug || false ; // Default values are based on Carvalho and Cohen, 2006, section 4.2:	 this . default_positive_weight = opts . default_positive_weight || 2.0 ; this . default_negative_weight = opts . default_negative_weight || 1.0 ; this . do_averaging = opts . do_averaging || false ; this . threshold = ( 'threshold' in opts ? opts . threshold : 1 ) ; this . promotion = opts . promotion || 1.5 ; this . demotion = opts . demotion || 0.5 ; this . margin = ( 'margin' in opts ? opts . margin : 1.0 ) ; this . retrain_count = opts . retrain_count || 0 ; this . detailed_explanations = opts . detailed_explanations || false ; this . bias = ( 'bias' in opts ? opts . bias : 1.0 ) ; this . positive_weights = { } ; this . negative_weights = { } ; this . positive_weights_sum = { } ; // for averaging; count only weight vectors with successful predictions (Carvalho and Cohen, 2006). this . negative_weights_sum = { } ; // for averaging; count only weight vectors with successful predictions (Carvalho and Cohen, 2006). }


Input: Batch training ( a set of samples ) . Uses the option this . retrain_count . [CODESPLIT] function ( dataset ) { //			var normalized_inputs = []; for ( var i = 0 ; i < dataset . length ; ++ i ) this . editFeatureValues ( dataset [ i ] . input , /*remove_unknown_features=*/ false ) ; //				normalized_inputs[i] = this.normalized_features(dataset[i].input, /*remove_unknown_features=*/false); for ( var r = 0 ; r <= this . retrain_count ; ++ r ) for ( var i = 0 ; i < dataset . length ; ++ i ) this . train_features ( dataset [ i ] . input , dataset [ i ] . output ) ; }


Input: Send the given dataset to svm_perf_learn . [CODESPLIT] function ( dataset ) { if ( this . debug ) console . log ( "trainBatch start" ) ; var timestamp = new Date ( ) . getTime ( ) + "_" + process . pid var learnFile = svmcommon . writeDatasetToFile ( dataset , this . bias , /*binarize=*/ true , this . model_file_prefix + "_" + timestamp , "SvmPerf" , FIRST_FEATURE_NUMBER ) ; var modelFile = learnFile . replace ( / [.]learn / , ".model" ) ; var command = "svm_perf_learn " + this . learn_args + " " + learnFile + " " + modelFile ; if ( this . debug ) console . log ( "running " + command ) ; console . log ( command ) var result = execSync ( command ) ; if ( result . code > 0 ) { console . dir ( result ) ; console . log ( fs . readFileSync ( learnFile , 'utf-8' ) ) ; throw new Error ( "Failed to execute: " + command ) ; } this . setModel ( fs . readFileSync ( modelFile , "utf-8" ) ) ; if ( this . debug ) console . log ( "trainBatch end" ) ; }


Input: weights smaller than this are ignored to save space A utility that converts a model in the SVMPerf format to a map of feature weights . [CODESPLIT] function modelStringToModelMap ( modelString ) { var matches = SVM_PERF_MODEL_PATTERN . exec ( modelString ) ; if ( ! matches ) { console . log ( modelString ) ; throw new Error ( "Model does not match SVM-perf format" ) ; } ; //var threshold = parseFloat(matches[1]);  // not needed - we use our own bias var featuresAndWeights = matches [ 2 ] . split ( " " ) ; var mapFeatureToWeight = { } ; //mapFeatureToWeight.threshold = threshold; // not needed - we use our own bias //String alphaTimesY = featuresAndWeights[0]; // always 1 in svmperf for ( var i = 1 ; i < featuresAndWeights . length ; ++ i ) { var featureAndWeight = featuresAndWeights [ i ] ; var featureWeight = featureAndWeight . split ( ":" ) ; if ( featureWeight . length != 2 ) throw new Error ( "Model featureAndWeight doesn't match svm-perf pattern: featureAndWeight=" + featureAndWeight ) ; var feature = parseInt ( featureWeight [ 0 ] ) ; if ( feature <= 0 ) throw new IllegalArgumentException ( "Non-positive feature id: featureAndWeight=" + featureAndWeight ) ; var weight = parseFloat ( featureWeight [ 1 ] ) ; if ( Math . abs ( weight ) >= MIN_WEIGHT ) mapFeatureToWeight [ feature - FIRST_FEATURE_NUMBER ] = weight ; // start feature values from 0. // Note: if there is bias, then mapFeatureToWeight[0] is its weight. } return mapFeatureToWeight ; }


Input: convert a single dataset to Weka ARFF string . [CODESPLIT] function ( dataset , relationName , featureLookupTable ) { var arff = "% Automatically generated by Node.js\n" ; arff += "@relation " + relationName + "\n" ; featureLookupTable . featureIndexToFeatureName . forEach ( function ( featureName ) { if ( _ . isUndefined ( featureName ) ) arff += "@attribute undefined {0,1}" + "\n" ; else if ( ! _ . isString ( featureName ) ) throw new Error ( "Expected featureName to be a string, but found " + JSON . stringify ( featureName ) ) ; else arff += "@attribute " + featureName . replace ( / [^a-zA-Z0-9] / g , "_" ) + " " + "{0,1}" + "\n" ; } ) ; arff += "\n@data\n" ; dataset . forEach ( function ( datum ) { var datumArff = _ . clone ( datum . input , { } ) ; for ( var i = 0 ; i < datum . output . length ; ++ i ) datumArff [ datum . output [ i ] ] = 1 ; //console.dir(datumArff); var array = featureLookupTable . hashToArray ( datumArff ) ; arff += array + "\n" ; } ) ; return arff ; }


Input: in lib linear feature numbers start with 1 [CODESPLIT] function SvmLinear ( opts ) { this . learn_args = opts . learn_args || "" ; this . model_file_prefix = opts . model_file_prefix || null ; this . bias = opts . bias || 1.0 ; this . multiclass = opts . multiclass || false ; this . debug = opts . debug || false ; this . train_command = opts . train_command || 'liblinear_train' ; this . test_command = opts . test_command || 'liblinear_test' ; this . timestamp = "" if ( ! SvmLinear . isInstalled ( ) ) { var msg = "Cannot find the executable 'liblinear_train'. Please download it from the LibLinear website, and put a link to it in your path." ; console . error ( msg ) throw new Error ( msg ) ; } }


Input: Send the given dataset to liblinear_train . [CODESPLIT] function ( dataset ) { this . timestamp = new Date ( ) . getTime ( ) + "_" + process . pid // check for multilabel _ . each ( dataset , function ( datum , key , list ) { if ( _ . isArray ( datum . output ) ) if ( datum . output . length > 1 ) { console . log ( "Multi-label is not allowed" ) console . log ( JSON . stringify ( darum . output , null , 4 ) ) process . exit ( 0 ) } } , this ) //  convert all arraay-like outputs to just values dataset = _ . map ( dataset , function ( datum ) { if ( _ . isArray ( datum . output ) ) datum . output = datum . output [ 0 ] return datum } ) ; this . allLabels = _ ( dataset ) . map ( function ( datum ) { return datum . output } ) ; this . allLabels = _ . uniq ( _ . flatten ( this . allLabels ) ) // dataset = _.map(dataset, function(datum){ // 	datum.output = this.allLabels.indexOf(datum.output) // 	return datum }); if ( this . allLabels . length == 1 ) // a single label return ; //console.log(util.inspect(dataset,{depth:1})); if ( this . debug ) console . log ( "trainBatch start" ) ; var learnFile = svmcommon . writeDatasetToFile ( dataset , this . bias , /*binarize=*/ false , this . model_file_prefix + "_" + this . timestamp , "SvmLinear" , FIRST_FEATURE_NUMBER ) ; var modelFile = learnFile . replace ( / [.]learn / , ".model" ) ; var command = this . train_command + " " + this . learn_args + " " + learnFile + " " + modelFile ; console . log ( "running " + command ) ; var result = child_process . execSync ( command ) ; if ( result . code > 0 ) { console . dir ( result ) ; console . log ( fs . readFileSync ( learnFile , 'utf-8' ) ) ; throw new Error ( "Failed to execute: " + command ) ; } this . modelFileString = modelFile ; if ( this . debug ) console . log ( "trainBatch end" ) ; }


Input: weights smaller than this are ignored to save space A utility that converts a model in the SvmLinear format to a matrix of feature weights per label . [CODESPLIT] function modelStringToModelMap ( modelString ) { var matches = LIB_LINEAR_MODEL_PATTERN . exec ( modelString ) ; if ( ! matches ) { console . log ( modelString ) ; throw new Error ( "Model does not match SVM-Linear format" ) ; } ; var labels = matches [ 1 ] . split ( / \s+ / ) ; var mapLabelToMapFeatureToWeight = { } ; for ( var iLabel in labels ) { var label = labels [ iLabel ] ; mapLabelToMapFeatureToWeight [ label ] = { } ; } var weightsMatrix = matches [ 3 ] ; // each line represents a feature; each column represents a label: var weightsLines = weightsMatrix . split ( NEWLINE ) ; for ( var feature in weightsLines ) { var weights = weightsLines [ feature ] . split ( / \s+ / ) ; weights . pop ( ) ; // ignore lal]st weight, which is empty (-space) if ( weights . length == 0 ) continue ; // ignore empty lines //		if (isNaN(parseFloat(weights[weights.length-1]))) //			weights.pop(); if ( weights . length == 1 && labels . length == 2 ) weights [ 1 ] = - weights [ 0 ] ; if ( weights . length != labels . length ) throw new Error ( "Model does not match SVM-Linear format: there are " + labels . length + " labels (" + labels + ") and " + weights . length + " weights (" + weights + ")" ) ; for ( var iLabel in labels ) { var label = labels [ iLabel ] ; var weight = parseFloat ( weights [ iLabel ] ) ; if ( Math . abs ( weight ) >= MIN_WEIGHT ) mapLabelToMapFeatureToWeight [ label ] [ feature ] = weight ; } } return mapLabelToMapFeatureToWeight ; }


Input: MetaLabeler - Multi - label classifier based on : [CODESPLIT] function ( opts ) { if ( ! opts . rankerType ) { console . dir ( opts ) ; throw new Error ( "opts.rankerType not found" ) ; } if ( ! opts . counterType ) { console . dir ( opts ) ; throw new Error ( "opts.counterType not found" ) ; } this . ranker = new opts . rankerType ( ) ; this . counter = new opts . counterType ( ) ; }


Input: Tell the classifier that the given sample belongs to the given classes . [CODESPLIT] function ( sample , labels ) { // The ranker is just trained by the given set of relevant labels: this . ranker . trainOnline ( sample , labels ) ; // The counter is trained by the *number* of relevant labels: var labelCount = ( Array . isArray ( labels ) ? labels : Object . keys ( labels ) ) . length ; this . counter . trainOnline ( sample , labelCount ) ; }


Input: Train the classifier with all the given documents . [CODESPLIT] function ( dataset ) { // The ranker is just trained by the given set of labels relevant to each sample: this . ranker . trainBatch ( dataset ) ; // The counter is trained by the *number* of labels relevant to each sample: var labelCountDataset = dataset . map ( function ( datum ) { var labelCount = ( Array . isArray ( datum . output ) ? datum . output . length : 1 ) ; return { input : datum . input , output : labelCount } ; } ) ; this . counter . trainBatch ( labelCountDataset ) ; }


Input: Use the model trained so far to classify a new sample . [CODESPLIT] function ( sample , explain ) { var rankedLabelsWithExplain = this . ranker . classify ( sample , explain , /*withScores=*/ true ) ; var rankedLabels = ( explain > 0 ? rankedLabelsWithExplain . classes : rankedLabelsWithExplain ) ; var labelCountWithExplain = this . counter . classify ( sample , explain , /*withScores=*/ true ) ; var labelCount = ( explain > 0 ? labelCountWithExplain . classes [ 0 ] [ 0 ] : labelCountWithExplain [ 0 ] [ 0 ] ) ; if ( _ . isString ( labelCount ) ) labelCount = parseInt ( labelCount ) ; // Pick the labelCount most relevant labels from the list returned by the ranker:    var positiveLabelsWithScores = rankedLabels . slice ( 0 , labelCount ) ; var positiveLabels = positiveLabelsWithScores if ( positiveLabelsWithScores . length != 0 ) if ( _ . isArray ( positiveLabelsWithScores [ 0 ] ) ) var positiveLabels = positiveLabelsWithScores . map ( function ( labelWithScore ) { return labelWithScore [ 0 ] } ) ; return ( explain > 0 ? { classes : positiveLabels , explanation : { ranking : rankedLabelsWithExplain . explanation , counting : labelCountWithExplain . explanation } } : positiveLabels ) }


Input: Link to a FeatureLookupTable from a higher level in the hierarchy ( typically from an EnhancedClassifier ) used ONLY for generating meaningful explanations . [CODESPLIT] function ( featureLookupTable ) { if ( this . ranker . setFeatureLookupTable ) this . ranker . setFeatureLookupTable ( featureLookupTable ) ; if ( this . counter . setFeatureLookupTable ) this . counter . setFeatureLookupTable ( featureLookupTable ) ; }


Input: var fs = require ( fs ) ; BinaryRelevance - Multi - label classifier based on a collection of binary classifiers . Also known as : One - vs - All . [CODESPLIT] function ( opts ) { if ( ! opts . binaryClassifierType ) { console . dir ( opts ) ; throw new Error ( "opts.binaryClassifierType not found" ) ; } this . binaryClassifierType = opts . binaryClassifierType ; this . debug = opts . debug || false this . mapClassnameToClassifier = { } ; }


Input: Tell the classifier that the given sample belongs to the given labels . [CODESPLIT] function ( sample , labels ) { labels = multilabelutils . normalizeOutputLabels ( labels ) ; for ( var l in labels ) { var positiveLabel = labels [ l ] ; this . makeSureClassifierExists ( positiveLabel ) ; this . mapClassnameToClassifier [ positiveLabel ] . trainOnline ( sample , 1 ) ; } for ( var negativeLabel in this . mapClassnameToClassifier ) { if ( labels . indexOf ( negativeLabel ) < 0 ) this . mapClassnameToClassifier [ negativeLabel ] . trainOnline ( sample , 0 ) ; } }


Input: Train the classifier with all the given documents . [CODESPLIT] function ( dataset ) { // this variable will hold a dataset for each binary classifier: var mapClassnameToDataset = { } ; // create positive samples for each class: for ( var d in dataset ) { var sample = dataset [ d ] . input ; dataset [ d ] . output = multilabelutils . normalizeOutputLabels ( dataset [ d ] . output ) ; var labels = dataset [ d ] . output ; for ( var l in labels ) { var positiveLabel = labels [ l ] ; this . makeSureClassifierExists ( positiveLabel ) ; if ( ! ( positiveLabel in mapClassnameToDataset ) ) // make sure dataset for this class exists mapClassnameToDataset [ positiveLabel ] = [ ] ; mapClassnameToDataset [ positiveLabel ] . push ( { input : sample , output : 1 } ) } } // create negative samples for each class (after all labels are in the array): for ( var d in dataset ) { var sample = dataset [ d ] . input ; var labels = dataset [ d ] . output ; for ( var negativeLabel in this . mapClassnameToClassifier ) { if ( ! ( negativeLabel in mapClassnameToDataset ) ) // make sure dataset for this class exists mapClassnameToDataset [ negativeLabel ] = [ ] ; if ( labels . indexOf ( negativeLabel ) < 0 ) mapClassnameToDataset [ negativeLabel ] . push ( { input : sample , output : 0 } ) ; } } // train all classifiers: for ( var label in mapClassnameToDataset ) { if ( this . debug ) console . dir ( "TRAIN class=" + label ) ; this . mapClassnameToClassifier [ label ] . trainBatch ( mapClassnameToDataset [ label ] ) ; } }


Input: Use the model trained so far to classify a new sample . [CODESPLIT] function ( sample , explain , withScores ) { var labels = [ ] var scores = [ ] var explanations = [ ] ; var positive_explanations = { } ; var negative_explanations = [ ] for ( var label in this . mapClassnameToClassifier ) { var classifier = this . mapClassnameToClassifier [ label ] ; if ( this . debug ) console . dir ( "Classify for class=" + label ) // fs.writeFileSync('/tmp/labels/'+label, JSON.stringify(classifier.getFeatures(), null, 4), 'utf8'); var scoreWithExplain = classifier . classify ( sample , explain , withScores ) ; if ( this . debug ) console . log ( JSON . stringify ( scoreWithExplain , null , 4 ) ) var score = scoreWithExplain . explanation ? scoreWithExplain . classification : scoreWithExplain ; if ( this . debug ) console . dir ( "score=" + score ) explanations_string = scoreWithExplain . explanation // if (score>0.5) if ( score > 0 ) { labels . push ( [ label , score ] ) if ( explanations_string ) positive_explanations [ label ] = explanations_string ; } else { if ( explanations_string ) negative_explanations . push ( [ label , score , explanations_string ] ) } scores . push ( [ label , score ] ) } if ( this . debug ) console . dir ( scores ) if ( explain > 0 ) { scores = _ . sortBy ( scores , function ( num ) { return num [ 1 ] } ) . reverse ( ) var scores_hash = _ . object ( scores ) negative_explanations = _ . sortBy ( negative_explanations , function ( num ) { return num [ 1 ] } ) . reverse ( ) negative_explanations = _ . map ( negative_explanations , function ( num ) { return [ num [ 0 ] , num [ 2 ] ] } ) ; var negative_explanations_hash = _ . object ( negative_explanations ) } labels = _ . sortBy ( labels , function ( num ) { return num [ 1 ] } ) ; labels = _ . map ( labels . reverse ( ) , function ( num ) { return num [ 0 ] } ) ; return ( explain > 0 ? { classes : labels , scores : scores_hash , explanation : { positive : positive_explanations , negative : negative_explanations_hash , } } : labels ) ; }


Input: Link to a FeatureLookupTable from a higher level in the hierarchy ( typically from an EnhancedClassifier ) used ONLY for generating meaningful explanations . [CODESPLIT] function ( featureLookupTable ) { //console.log("BR setFeatureLookupTable "+featureLookupTable); this . featureLookupTable = featureLookupTable ; for ( var label in this . mapClassnameToClassifier ) if ( featureLookupTable && this . mapClassnameToClassifier [ label ] . setFeatureLookupTable ) this . mapClassnameToClassifier [ label ] . setFeatureLookupTable ( featureLookupTable ) ; }


Input: private function : [CODESPLIT] function ( label ) { if ( ! this . mapClassnameToClassifier [ label ] ) { // make sure classifier exists this . mapClassnameToClassifier [ label ] = new this . binaryClassifierType ( ) ; if ( this . featureLookupTable && this . mapClassnameToClassifier [ label ] . setFeatureLookupTable ) this . mapClassnameToClassifier [ label ] . setFeatureLookupTable ( this . featureLookupTable ) ; } }


Input: / * ThresholdClassifier - classifier that converts multi - class classifier to multi - label classifier by finding the best appropriate threshold . [CODESPLIT] function ( opts ) { opts = opts || { } ; if ( ! ( 'multiclassClassifierType' in opts ) ) { console . dir ( opts ) ; throw new Error ( "opts must contain multiclassClassifierType" ) ; } if ( ! opts . multiclassClassifierType ) { console . dir ( opts ) ; throw new Error ( "opts.multiclassClassifierType is null" ) ; } if ( ! ( 'evaluateMeasureToMaximize' in opts ) ) { console . dir ( opts ) ; throw new Error ( "opts must contain evaluateMeasureToMaximize" ) ; } if ( ! opts . evaluateMeasureToMaximize ) { console . dir ( opts ) ; throw new Error ( "opts.evaluateMeasureToMaximize is null" ) ; } if ( ! opts . numOfFoldsForThresholdCalculation ) { console . dir ( opts ) ; throw new Error ( "opts.numOfFoldsForThresholdCalculation is null" ) ; } this . multiclassClassifier = new opts . multiclassClassifierType ( ) ; // [F1, Accuracy]	 this . evaluateMeasureToMaximize = opts . evaluateMeasureToMaximize ; // constant size of validation set this . devsetsize = 0.1 // > 1, n - fold cross - validation, otherwise validation set this . numOfFoldsForThresholdCalculation = opts . numOfFoldsForThresholdCalculation }


Input: Train the classifier with all the given documents and identify the best possible threshold simply by running over all relevant scores and determining the value of feedback function ( F1 by default ) [CODESPLIT] function ( dataset ) { _ . times ( 3 , function ( n ) { dataset = _ . shuffle ( dataset ) } ) if ( this . numOfFoldsForThresholdCalculation > 1 ) { thresholds = [ ] best_performances = [ ] average_performances = [ ] median_performances = [ ] partitions . partitions_consistent ( dataset , this . numOfFoldsForThresholdCalculation , ( function ( trainSet , testSet , index ) { this . multiclassClassifier . trainBatch ( trainSet ) ; result = this . receiveScores ( testSet ) performance = this . CalculatePerformance ( result [ 0 ] , testSet , result [ 1 ] ) best_performances . push ( performance ) } ) . bind ( this ) ) this . stats = best_performances threshold_average = ulist . average ( _ . pluck ( best_performances , 'Threshold' ) ) threshold_median = ulist . median ( _ . pluck ( best_performances , 'Threshold' ) ) Threshold = threshold_median } else { dataset = partitions . partition ( dataset , 1 , Math . round ( dataset . length * this . devsetsize ) ) trainSet = dataset [ 'train' ] testSet = dataset [ 'test' ] this . multiclassClassifier . trainBatch ( trainSet ) ; result = this . receiveScores ( testSet ) performance = this . CalculatePerformance ( result [ 0 ] , testSet , result [ 1 ] ) Threshold = performance [ 'Threshold' ] } this . multiclassClassifier . threshold = Threshold }


Input: / * Classify dataset and return the scored result in sorted list [CODESPLIT] function ( dataset ) { list_of_scores = [ ] ; FN = 0 for ( var i = 0 ; i < dataset . length ; ++ i ) { var scoresVector = this . multiclassClassifier . classify ( dataset [ i ] . input , false , true ) ; for ( score in scoresVector ) { if ( dataset [ i ] . output . indexOf ( scoresVector [ score ] [ 0 ] ) > - 1 ) { scoresVector [ score ] . push ( "+" ) FN += 1 } else { scoresVector [ score ] . push ( "-" ) } scoresVector [ score ] . push ( i ) } list_of_scores = list_of_scores . concat ( scoresVector ) } // list_of_scores = [['d',4],['b',2],['a',1],['c',3]] list_of_scores . sort ( ( function ( index ) { return function ( a , b ) { return ( a [ index ] === b [ index ] ? 0 : ( a [ index ] < b [ index ] ? 1 : - 1 ) ) ; } ; } ) ( 1 ) ) return [ list_of_scores , FN ] }


Input: / * Calculate the bst threshold with the highest evaluateMeasureToMaximize [CODESPLIT] function ( list_of_scores , testSet , FN ) { current_set = [ ] TRUE = 0 FP = 0 TP = 0 result = [ ] for ( var th = 0 ; th < list_of_scores . length ; ++ th ) { if ( list_of_scores [ th ] [ 2 ] == "+" ) { TP += 1 ; FN -= 1 } if ( list_of_scores [ th ] [ 2 ] == "-" ) { FP += 1 ; } // console.log(list_of_scores[th]) // console.log("TP "+TP+" FP "+FP+" FN "+FN) index_in_testSet = list_of_scores [ th ] [ 3 ] if ( _ . isEqual ( current_set [ index_in_testSet ] , testSet [ index_in_testSet ] [ 'output' ] ) ) { TRUE -= 1 } if ( ! current_set [ index_in_testSet ] ) { current_set [ index_in_testSet ] = [ list_of_scores [ th ] [ 0 ] ] } else { current_set [ index_in_testSet ] . push ( list_of_scores [ th ] [ 0 ] ) } if ( _ . isEqual ( current_set [ index_in_testSet ] , testSet [ index_in_testSet ] [ 'output' ] ) ) { TRUE += 1 } PRF = calculate_PRF ( TP , FP , FN ) PRF [ 'Accuracy' ] = TRUE / testSet . length PRF [ 'Threshold' ] = list_of_scores [ th ] [ 1 ] result [ list_of_scores [ th ] [ 1 ] ] = PRF } optial_measure = 0 index = Object . keys ( result ) [ 0 ] for ( i in result ) { if ( result [ i ] [ this . evaluateMeasureToMaximize ] >= optial_measure ) { index = i optial_measure = result [ i ] [ this . evaluateMeasureToMaximize ] } } return result [ index ] }


Input: MulticlassSegmentation - Multi - label text classifier based on a segmentation scheme using a base multi - class classifier . [CODESPLIT] function ( opts ) { if ( ! opts . multiclassClassifierType ) { console . dir ( opts ) ; throw new Error ( "opts.multiclassClassifierType not found" ) ; } this . multiclassClassifierType = opts . multiclassClassifierType ; this . featureExtractor = FeaturesUnit . normalize ( opts . featureExtractor ) ; this . multiclassClassifier = new this . multiclassClassifierType ( ) ; }


Input:
Tell the classifier that the given sample belongs to the given classes . [CODESPLIT] function ( sample , classes ) { sample = this . sampleToFeatures ( sample , this . featureExtractor ) ; var category = ( Array . isArray ( classes ) ? classes [ 0 ] : classes ) ; this . multiclassClassifier . trainOnline ( sample , category ) ; /*for (var positiveClass in classes) {
			this.makeSureClassifierExists(positiveClass);
			this.mapClassnameToClassifier[positiveClass].trainOnline(sample, 1);
		}
		for (var negativeClass in this.mapClassnameToClassifier) {
			if (!classes[negativeClass])
				this.mapClassnameToClassifier[negativeClass].trainOnline(sample, 0);
		}*/ }


Input: Train the classifier with all the given documents . [CODESPLIT] function ( dataset ) { for ( var i = 0 ; i < dataset . length ; ++ i ) { dataset [ i ] = { input : this . sampleToFeatures ( dataset [ i ] . input , this . featureExtractor ) , output : ( Array . isArray ( dataset [ i ] . output ) ? dataset [ i ] . output [ 0 ] : dataset [ i ] . output ) } ; } this . multiclassClassifier . trainBatch ( dataset ) ; }


Input: Internal function - use the model trained so far to classify a single segment of a sentence . [CODESPLIT] function ( segment , explain ) { var sample = this . sampleToFeatures ( segment , this . featureExtractor ) ; return this . multiclassClassifier . classify ( sample , explain ) ; }


Input: protected function : Strategy of finding the cheapest segmentation ( - most probable segmentation ) using a dynamic programming algorithm . Based on : Morbini Fabrizio Sagae Kenji . Joint Identification and Segmentation of Domain - Specific Dialogue Acts for Conversational Dialogue Systems . ACL - HLT 2011 http : // www . citeulike . org / user / erelsegal - halevi / article / 10259046 [CODESPLIT] function ( words , accumulatedClasses , explain , explanations ) { // Calculate the cost of classification of the segment from i to j. // (Cost = - log probability). var segmentClassificationCosts = [ ] ; // best cost to classify segment [i,j] for ( var start = 0 ; start <= words . length ; ++ start ) { segmentClassificationCosts [ start ] = [ ] ; for ( var end = 0 ; end < start ; ++ end ) segmentClassificationCosts [ start ] [ end ] = Infinity ; segmentClassificationCosts [ start ] [ start ] = 0 ; for ( var end = start + 1 ; end <= words . length ; ++ end ) { var segment = words . slice ( start , end ) . join ( " " ) ; var classification = this . bestClassOfSegment ( segment ) ; segmentClassificationCosts [ start ] [ end ] = - Math . log ( classification . probability ) ; } } //console.log(words+":  ");		console.log("segmentClassificationCosts");		console.dir(segmentClassificationCosts); var cheapest_paths = require ( "graph-paths" ) . cheapest_paths ; cheapestSegmentClassificationCosts = cheapest_paths ( segmentClassificationCosts , 0 ) ; cheapestSentenceClassificationCost = cheapestSegmentClassificationCosts [ words . length ] ; if ( ! cheapestSentenceClassificationCost ) throw new Error ( "cheapestSegmentClassificationCosts[" + words . length + "] is empty" ) ; //console.log("cheapestSentenceClassificationCost");		console.dir(cheapestSentenceClassificationCost); var cheapestClassificationPath = cheapestSentenceClassificationCost . path ; explanations . push ( cheapestSentenceClassificationCost ) ; for ( var i = 0 ; i < cheapestClassificationPath . length - 1 ; ++ i ) { var segment = words . slice ( cheapestClassificationPath [ i ] , cheapestClassificationPath [ i + 1 ] ) . join ( " " ) ; //console.log(segment+":  "); var segmentCategoryWithExplain = this . classifySegment ( segment , explain ) ; //console.dir(segmentCategoryWithExplain); var segmentCategory = ( segmentCategoryWithExplain . category ? segmentCategoryWithExplain . category : segmentCategoryWithExplain ) ; accumulatedClasses [ segmentCategory ] = true ; if ( explain > 0 ) { explanations . push ( segment ) ; explanations . push ( segmentCategoryWithExplain . explanation ) ; } ; } }


Input: Use the model trained so far to classify a new sample . [CODESPLIT] function ( sentence , explain ) { var minWordsToSplit = 2 ; var words = sentence . split ( /   / ) ; if ( words . length >= minWordsToSplit ) { var accumulatedClasses = { } ; var explanations = [ ] ; this . cheapestSegmentSplitStrategy ( words , accumulatedClasses , explain , explanations ) ; var classes = Object . keys ( accumulatedClasses ) ; return ( explain > 0 ? { classes : classes , explanation : explanations } : classes ) ; } else { return this . classifySegment ( sentence , explain ) ; } }


Input: private function : [CODESPLIT] function ( sample , featureExtractor ) { var features = sample ; if ( featureExtractor ) { try { features = { } ; featureExtractor ( sample , features ) ; } catch ( err ) { throw new Error ( "Cannot extract features from '" + JSON . stringify ( sample ) + "': " + JSON . stringify ( err ) ) ; } } return features ; }


Input: Loads the package definition ( if it exists ) and picks specific properties to expose . These properties are later merged into the options object as default values . [CODESPLIT] function loadPackageProperties ( grunt ) { var packageFile = 'package.json' ; if ( grunt . file . exists ( packageFile ) ) { return _ . pick ( grunt . file . readJSON ( packageFile ) , [ 'name' , 'version' , 'description' ] ) ; } return { } ; }


Input: Sets the prop property on options to the concatenation of that property from both options and data if both exist . Otherwise if either exist exclusively that array will be set to the options . When neither exist nothing is done to the options object . [CODESPLIT] function concatOptionDataArrays ( options , data , prop ) { if ( ! _ . has ( options , prop ) && ! _ . has ( data , prop ) ) { return ; } var combined = [ ] ; if ( _ . isArray ( options [ prop ] ) ) { combined = combined . concat ( options [ prop ] ) ; } if ( _ . isArray ( data [ prop ] ) ) { combined = combined . concat ( data [ prop ] ) ; } options [ prop ] = combined ; }


Input: Applies properties from the options object to the spec object . This is done explicitly to mitigate pollution from the options object and allow for notification of default assignments . [CODESPLIT] function applySpecSettings ( grunt , options , spec ) { spec . tags . name = options . name || spec . tags . name ; if ( ! _ . has ( options , 'version' ) ) { _defaultOptionNotice ( grunt , 'version' , '0.0.0' ) ; } spec . tags . version = options . version || '0.0.0' ; if ( ! _ . has ( options , 'release' ) ) { _defaultOptionNotice ( grunt , 'release' , '1' ) ; } spec . tags . release = options . release || '1' ; if ( ! _ . has ( options , 'buildArch' ) ) { _defaultOptionNotice ( grunt , 'buildArch' , 'noarch' ) ; } spec . tags . buildArch = options . buildArch || 'noarch' ; if ( ! _ . has ( options , 'description' ) ) { _defaultOptionNotice ( grunt , 'description' , 'No Description' ) ; } spec . tags . description = options . description || 'No Description' ; if ( ! _ . has ( options , 'summary' ) ) { _defaultOptionNotice ( grunt , 'summary' , 'No Summary' ) ; } spec . tags . summary = options . summary || 'No Summary' ; if ( ! _ . has ( options , 'license' ) ) { _defaultOptionNotice ( grunt , 'license' , 'MIT' ) ; } spec . tags . license = options . license || 'MIT' ; spec . tags . epoch = options . epoch || spec . tags . epoch ; spec . tags . distribution = options . distribution || spec . tags . distribution ; if ( ! _ . has ( options , 'vendor' ) ) { _defaultOptionNotice ( grunt , 'vendor' , 'Vendor' ) ; } spec . tags . vendor = options . vendor || 'Vendor' ; spec . tags . url = options . url || spec . tags . url ; if ( ! _ . has ( options , 'group' ) ) { _defaultOptionNotice ( grunt , 'group' , 'Development/Tools' ) ; } spec . tags . group = options . group || 'Development/Tools' ; spec . tags . packager = options . packager || spec . tags . packager ; if ( _ . has ( options , 'defines' ) ) { spec . addDefines . apply ( spec , options . defines ) ; } // To maintain backwards compatability with the older API, the arrays // `dependencies` and `requires` are synonymous. if ( _ . has ( options , 'dependencies' ) ) { // TODO deprecate post 1.5.0 grunt . log . writelns ( chalk . gray ( '[Notice] Deprecation warning: ' + 'the use of "dependencies" is deprecated in favour of ' + 'the RPM "requires" and "conflicts" tags.' ) ) ; spec . addRequirements . apply ( spec , options . dependencies ) ; } if ( _ . has ( options , 'requires' ) ) { spec . addRequirements . apply ( spec , options . requires ) ; } if ( _ . has ( options , 'buildRequires' ) ) { spec . addBuildRequirements . apply ( spec , options . buildRequires ) ; } if ( _ . has ( options , 'provides' ) ) { spec . addProvides . apply ( spec , options . provides ) ; } if ( options . autoReq === false ) { spec . tags . autoReq = options . autoReq ; } if ( options . autoProv === false ) { spec . tags . autoProv = options . autoProv ; } if ( options . hasOwnProperty ( 'excludeArchs' ) ) { spec . addExcludeArchs . apply ( spec , options . excludeArchs ) ; } if ( options . hasOwnProperty ( 'exclusiveArchs' ) ) { spec . addExclusiveArchs . apply ( spec , options . exclusiveArchs ) ; } if ( options . hasOwnProperty ( 'excludeOS' ) ) { spec . addExcludeOS . apply ( spec , options . excludeOS ) ; } if ( options . hasOwnProperty ( 'exclusiveOS' ) ) { spec . addExclusiveOS . apply ( spec , options . exclusiveOS ) ; } spec . tags . prefix = options . prefix || spec . tags . prefix ; spec . tags . buildRoot = options . buildRoot || spec . tags . buildRoot ; if ( options . hasOwnProperty ( 'sources' ) ) { spec . addSources . apply ( spec , options . sources ) ; } if ( options . hasOwnProperty ( 'noSources' ) ) { spec . addNoSources . apply ( spec , options . noSources ) ; } if ( options . hasOwnProperty ( 'patches' ) ) { spec . addPatches . apply ( spec , options . patches ) ; } if ( options . hasOwnProperty ( 'noPatches' ) ) { spec . addNoPatches . apply ( spec , options . noPatches ) ; } // Add scripts from options. if ( options . hasOwnProperty ( 'prepScript' ) ) { spec . addPrepScripts . apply ( spec , options . prepScript ) ; } if ( options . hasOwnProperty ( 'buildScript' ) ) { spec . addBuildScripts . apply ( spec , options . buildScript ) ; } if ( options . hasOwnProperty ( 'checkScript' ) ) { spec . addCheckScripts . apply ( spec , options . checkScript ) ; } if ( options . hasOwnProperty ( 'cleanScript' ) ) { spec . addCleanScripts . apply ( spec , options . cleanScript ) ; } if ( options . hasOwnProperty ( 'installScript' ) ) { spec . addInstallScripts . apply ( spec , options . installScript ) ; } if ( options . hasOwnProperty ( 'preInstallScript' ) ) { spec . addPreInstallScripts . apply ( spec , options . preInstallScript ) ; } if ( options . hasOwnProperty ( 'postInstallScript' ) ) { spec . addPostInstallScripts . apply ( spec , options . postInstallScript ) ; } if ( options . hasOwnProperty ( 'preUninstallScript' ) ) { spec . addPreUninstallScripts . apply ( spec , options . preUninstallScript ) ; } if ( options . hasOwnProperty ( 'postUninstallScript' ) ) { spec . addPostUninstallScripts . apply ( spec , options . postUninstallScript ) ; } if ( options . hasOwnProperty ( 'verifyScript' ) ) { spec . addVerifyScripts . apply ( spec , options . verifyScript ) ; } // Add the default file attributes from options. if ( options . hasOwnProperty ( 'defaultAttributes' ) ) { spec . setDefaultAttributes ( options . defaultAttributes ) ; } // Add the changelogs. if ( options . hasOwnProperty ( 'changelog' ) ) { var changelog ; if ( _ . isFunction ( options . changelog ) ) { changelog = options . changelog ( ) ; } else if ( _ . isArray ( options . changelog ) ) { changelog = options . changelog ; } spec . addChangelogs . apply ( spec , changelog ) ; } }


Input: API [CODESPLIT] function Couch ( opts ) { var self = this ; self . url = ( typeof opts . url === 'string' ) ? opts . url : null ; self . userCtx = opts . userCtx || null ; self . time_C = opts . time_C || null ; self . known_dbs = null ; self . log = debug ( 'cqs:couch:' + self . url ) ; }


Input: Utilities [CODESPLIT] function uuids_for ( couch ) { UUIDS [ couch . url ] = UUIDS [ couch . url ] || new UUIDGetter ( couch ) ; return UUIDS [ couch . url ] ; }


Input: Utilities [CODESPLIT] function templated_ddoc ( name ) { return stringify_functions ( TEMPLATE ) function stringify_functions ( obj ) { var copy = { } ; if ( Array . isArray ( obj ) ) return obj . map ( stringify_functions ) else if ( typeof obj === 'object' && obj !== null ) { Object . keys ( obj ) . forEach ( function ( key ) { copy [ key ] = stringify_functions ( obj [ key ] ) ; } ) return copy ; } else if ( typeof obj === 'function' ) return func_from_template ( obj ) else return lib . JDUP ( obj ) ; } }


Input: For example : 1 год 2 года 3 года 4 года 5 лет 6 лет … 11 лет 12 лет … 20 лет 21 год 31 год 22 года 32 года [CODESPLIT] function pluralize ( number , words ) { var magnitude = number % 100 ; var pluralWord = '' if ( ( magnitude > 10 && magnitude < 20 ) || ( number === 0 ) ) { pluralWord = words [ 2 ] ; } else { switch ( Math . abs ( number % 10 ) ) { case 1 : pluralWord = words [ 0 ] ; break case 2 : case 3 : case 4 : pluralWord = words [ 1 ] ; break default : pluralWord = words [ 2 ] ; break } } return [ number , pluralWord ] . join ( ' ' ) }


Input: API [CODESPLIT] function Message ( opts ) { var self = this ; events . EventEmitter . call ( self ) ; lib . copy ( opts , self , 'uppercase' ) ; self . MessageId = opts . MessageId || opts . _id || null ; self . Body = opts . MessageBody || opts . Body || opts . _str || null ; self . MD5OfMessageBody = null ; self . IdExtra = opts . IdExtra || null ; self . queue = opts . queue || null ; self . is_heartbeat = opts . is_heartbeat || false ; self . seq = opts . seq || null ; self . log = debug ( 'cqs:message:' + ( self . MessageId || 'untitled' ) ) ; }


Input: API [CODESPLIT] function Queue ( opts ) { var self = this ; if ( typeof opts == 'string' ) opts = { 'name' : opts } ; opts = defaultable . merge ( opts , DEFS ) ; self . name = opts . name || opts . QueueName || opts . _str || null ; self . time_C = opts . time_C || null ; self . db = new couch . Database ( { 'couch' : opts . couch , 'db' : opts . db , time_C : self . time_C } ) ; self . VisibilityTimeout = opts . DefaultVisibilityTimeout || opts . VisibilityTimeout || DEFS . visibility_timeout ; self . cache_confirmation = true ; self . browser_attachments = ! ! ( opts . browser_attachments ) ; self . allow_foreign_docs = opts . allow_foreign_docs self . log = debug ( 'cqs:queue:' + ( self . name || 'untitled' ) ) ; }


Input: Check and remove nodes recursively in preorder . For each composite node modify its children array in - place . [CODESPLIT] function preorder ( node , nodeIndex , parent ) { var children var length var index var position var child if ( is ( test , node , nodeIndex , parent ) ) { return null } children = node . children if ( ! children || children . length === 0 ) { return node } // Move all living children to the beginning of the children array. position = 0 length = children . length index = - 1 while ( ++ index < length ) { child = preorder ( children [ index ] , index , node ) if ( child ) { children [ position ++ ] = child } } // Cascade delete. if ( cascade && position === 0 ) { return null } // Drop other nodes. children . length = position return node }


Input: / * Parse data into a IPV6 address string [CODESPLIT] function asAAAA ( consumer , packet ) { var data = '' ; for ( var i = 0 ; i < 7 ; i ++ ) { data += consumer . short ( ) . toString ( 16 ) + ':' ; } data += consumer . short ( ) . toString ( 16 ) ; packet . address = data ; }


Input: Filters models so they are formatted correctly . [CODESPLIT] function filterRelations ( relation ) { var mappedData = includedData . find ( function ( inc ) { return inc . id === relation . id ; } ) ; var RelationModel = getModel ( relation . type ) ; var modeledData = new RelationModel ( mappedData ) ; return checkForRelations ( modeledData , modeledData . data ) ; }


Input: The Locator walks the filesystem and gives semantic meaning to files in the application . @module Locator @class Locator @constructor @param { object } [ options ] Options for how the configuration files are located . @param { string } [ options . applicationDirectory ] Where the application will be found . If not given it defaults to the current working directory . @param { [ string ] } [ options . exclude ] folder names that should not be analyzed @param { integer } options . maxPackageDepth Maximum depth in node_modules / to walk . Defaults to 9999 . @param { function } options . rulesetFn Function hook to compute rules per bundle dynamically . This hook allow to analyze the pkg and produce the proper rules when needed . [CODESPLIT] function BundleLocator ( options ) { this . _options = options || { } ; if ( this . _options . applicationDirectory ) { this . _options . applicationDirectory = libpath . resolve ( process . cwd ( ) , this . _options . applicationDirectory ) ; } else { this . _options . applicationDirectory = process . cwd ( ) ; } this . _options . maxPackageDepth = this . _options . maxPackageDepth || DEFAULT_MAX_PACKAGES_DEPTH ; this . _options . exclude = this . _options . exclude || [ ] ; this . _cacheRules = { } ; // rulename + package directory: rules this . _bundles = { } ; this . _bundlePaths = { } ; // path: name this . _bundleUpdates = { } ; // name: object describing why the update happened }


Input: Parses the directory to turn it into a bundle . @method parseBundle @param { string } dir The directory for the bundle . @param { object } [ options ] Options for processing the bundle . [CODESPLIT] function ( dir , options ) { var self = this , bundleSeeds ; // Normalize the root directory before storing its value. If it is // stored before normalizing, other paths created afterwards may be // normalized and fail comparisons against the root directory dir = libpath . normalize ( dir ) ; this . _rootDirectory = dir ; bundleSeeds = this . _walkNPMTree ( dir ) ; bundleSeeds = this . _filterBundleSeeds ( bundleSeeds ) ; bundleSeeds . forEach ( function ( bundleSeed ) { var opts = ( bundleSeed . baseDirectory === dir ) ? options : { } ; self . _walkBundle ( bundleSeed , opts ) ; } ) ; this . _rootBundleName = this . _bundlePaths [ libfs . realpathSync ( dir ) ] ; return this . _bundles [ this . _rootBundleName ] ; }


Input: Utility method for listing all files in a bundle . [CODESPLIT] function ( bundleName , filter ) { var bundle , files = [ ] ; bundle = this . _bundles [ bundleName ] ; if ( ! bundle ) { throw new Error ( 'Unknown bundle "' + bundleName + '"' ) ; } Object . keys ( bundle . files ) . forEach ( function ( fullpath ) { var res = { ext : libpath . extname ( fullpath ) . substr ( 1 ) } ; if ( this . _filterResource ( res , filter ) ) { files . push ( fullpath ) ; } } , this ) ; return files ; }


Input: Utility method for listing all resources in a bundle . [CODESPLIT] function ( bundleName , filter ) { var bundle = this . _bundles [ bundleName ] ; if ( ! bundle ) { throw new Error ( 'Unknown bundle "' + bundleName + '"' ) ; } return this . _walkBundleResources ( bundle , filter ) ; }


Input: Returns a list of resources in all the bundles . [CODESPLIT] function ( filter ) { var self = this , ress = [ ] ; Object . keys ( this . _bundles ) . forEach ( function ( bundleName ) { var bundle = self . _bundles [ bundleName ] ; self . _walkBundleResources ( bundle , filter ) . forEach ( function ( res ) { ress . push ( res ) ; } ) ; } ) ; return ress ; }


Input: Returns a list of all located bundle names . The names are not ordered . [CODESPLIT] function ( filter ) { var bundleName , bundles = this . _bundles , bundleNames = [ ] ; if ( 'function' !== typeof filter ) { return Object . keys ( this . _bundles ) ; } for ( bundleName in bundles ) { if ( bundles . hasOwnProperty ( bundleName ) ) { if ( filter ( bundles [ bundleName ] ) ) { bundleNames . push ( bundleName ) ; } } } return bundleNames ; }


Input: Returns the name of the bundle to which the path belongs . [CODESPLIT] function ( findPath ) { // FUTURE OPTIMIZATION:  use a more complicated datastructure for faster lookups var found = { } , // length: path longest ; // expands path in case of symlinks findPath = libfs . realpathSync ( findPath ) ; // searchs based on expanded path Object . keys ( this . _bundlePaths ) . forEach ( function ( bundlePath ) { if ( 0 === findPath . indexOf ( bundlePath ) && ( findPath . length === bundlePath . length || libpath . sep === findPath . charAt ( bundlePath . length ) ) ) { found [ bundlePath . length ] = bundlePath ; } } ) ; longest = Math . max . apply ( Math , Object . keys ( found ) ) ; return this . _bundlePaths [ found [ longest ] ] ; }


Input: Creates the seed of a potential bundle . [CODESPLIT] function ( baseDirectory , name , version , pkg , options ) { var seed ; seed = { baseDirectory : baseDirectory , name : name , version : version } ; if ( pkg ) { seed . name = ( pkg . locator && pkg . locator . name ? pkg . locator . name : pkg . name ) ; seed . version = pkg . version ; seed . options = pkg . locator ; seed . pkg = pkg ; } if ( options ) { if ( seed . options ) { // merge options under seed.options mix ( seed . options , options ) ; } else { seed . options = options ; } } return seed ; }


Input: Makes a bundle out of a directory . [CODESPLIT] function ( seed , parent ) { var bundle , ruleset = this . _loadRuleset ( seed ) , msg ; if ( seed . options . location ) { // This is fairly legacy, and we might be able to remove it. seed . baseDirectory = libpath . resolve ( seed . baseDirectory , seed . options . location ) ; } if ( ! ruleset ) { msg = 'Bundle "' + seed . name + '" has unknown ruleset ' + JSON . stringify ( seed . options . ruleset ) ; if ( seed . options . rulesets ) { msg += ' in rulesets ' + JSON . stringify ( seed . options . rulesets ) ; } throw new Error ( msg ) ; } bundle = new Bundle ( seed . baseDirectory , seed . options ) ; bundle . name = seed . name ; bundle . version = seed . version ; bundle . type = ruleset . _name ; this . _bundles [ bundle . name ] = bundle ; this . _bundlePaths [ libfs . realpathSync ( bundle . baseDirectory ) ] = bundle . name ; // wire into parent if ( parent ) { if ( ! parent . bundles ) { parent . bundles = { } ; } parent . bundles [ bundle . name ] = bundle ; } return bundle ; }


Input: Turns the path into a resource in the associated bundle if applicable . [CODESPLIT] function ( fullPath ) { var bundleName , bundle , ruleset , relativePath , pathParts , subBundleSeed , res ; bundleName = this . _getBundleNameByPath ( fullPath ) ; bundle = this . _bundles [ bundleName ] ; if ( bundle . baseDirectory === fullPath . substr ( 0 , bundle . baseDirectory . length ) ) { relativePath = fullPath . substr ( bundle . baseDirectory . length + 1 ) ; } // This mainly happens during watch(), since we skip node_modules // in _walkBundle(). if ( relativePath . indexOf ( 'node_modules' ) === 0 ) { pathParts = relativePath . split ( libpath . sep ) ; while ( pathParts [ 0 ] === 'node_modules' && pathParts . length >= 2 ) { pathParts . shift ( ) ; bundleName = pathParts . shift ( ) ; } relativePath = pathParts . join ( libpath . sep ) ; bundle = this . _bundles [ bundleName ] ; // The package's directory is not a resource (... and is mostly uninteresting). if ( ! relativePath ) { return ; } // unknown bundle if ( ! bundle ) { return ; } } ruleset = this . _loadRuleset ( bundle ) ; if ( ruleset . _skip && this . _ruleSkip ( fullPath , relativePath , ruleset . _skip ) ) { return ; } if ( ruleset . _bundles ) { subBundleSeed = this . _ruleBundles ( fullPath , relativePath , ruleset . _bundles , bundle ) ; if ( subBundleSeed ) { // sub-bundle inherits options.rulesets from parent if ( ! subBundleSeed . options ) { subBundleSeed . options = { } ; } if ( ! subBundleSeed . options . rulesets ) { subBundleSeed . options . rulesets = bundle . options . rulesets ; } this . _makeBundle ( subBundleSeed , bundle ) ; return ; } } // This is the base "meta" for a file.  If a rule matches we'll // augment this. res = { bundleName : bundleName , fullPath : fullPath , relativePath : relativePath , ext : libpath . extname ( fullPath ) . substr ( 1 ) } ; this . _onFile ( res , ruleset ) ; }


Input: Processes the _skip rule to decide if the path should be skipped . [CODESPLIT] function ( fullPath , relativePath , rule ) { var r , regex ; relativePath = BundleLocator . _toUnixPath ( relativePath ) ; for ( r = 0 ; r < rule . length ; r += 1 ) { regex = rule [ r ] ; if ( regex . test ( relativePath ) ) { return true ; } } return false ; }


Input: Processes the _bundles rule looking for child bundles . Returns a bundle seed as described by _makeBundleSeed () . [CODESPLIT] function ( fullPath , relativePath , rule , parent ) { var r , matches , defaultVersion = DEFAULT_VERSION , pkg ; if ( parent ) { defaultVersion = parent . version ; } relativePath = BundleLocator . _toUnixPath ( relativePath ) ; for ( r = 0 ; r < rule . length ; r += 1 ) { matches = relativePath . match ( rule [ r ] . regex ) ; if ( matches ) { try { pkg = require ( libpath . resolve ( fullPath , 'package.json' ) ) ; } catch ( packageErr ) { // It's OK for a sub-bundle to not have a package.json. } return this . _makeBundleSeed ( fullPath , libpath . normalize ( matches [ 1 ] ) , defaultVersion , pkg , rule [ r ] . options ) ; } } }


Input: Handles the file . [CODESPLIT] function ( res , ruleset ) { var bundle = this . _bundles [ res . bundleName ] , ruleName , rule , relativePath = BundleLocator . _toUnixPath ( res . relativePath ) , match ; bundle . files [ res . fullPath ] = true ; for ( ruleName in ruleset ) { if ( ruleset . hasOwnProperty ( ruleName ) ) { // Rules that start with "_" are special directives, // and have already been handle by the time we get here. if ( '_' !== ruleName . charAt ( 0 ) ) { rule = ruleset [ ruleName ] ; match = relativePath . match ( rule . regex ) ; if ( match ) { res . name = match [ rule . nameKey || 1 ] ; res . type = ruleName ; if ( rule . subtypeKey ) { res . subtype = match [ rule . subtypeKey ] || '' ; } if ( rule . selectorKey && match [ rule . selectorKey ] ) { res . selector = match [ rule . selectorKey ] ; } else { res . selector = DEFAULT_SELECTOR ; } // file will become a resource after the first match return this . _onResource ( res ) ; } } } } }


Input: Handles the resource . [CODESPLIT] function ( res ) { var bundle = this . _bundles [ res . bundleName ] , type = res . type , subtype , selector = res . selector , name = res . name ; if ( ! bundle . resources [ selector ] ) { bundle . resources [ selector ] = { } ; } if ( ! bundle . resources [ selector ] [ type ] ) { bundle . resources [ selector ] [ type ] = { } ; } if ( res . hasOwnProperty ( 'subtype' ) ) { subtype = res . subtype ; if ( ! bundle . resources [ selector ] [ type ] [ subtype ] ) { bundle . resources [ selector ] [ type ] [ subtype ] = { } ; } bundle . resources [ selector ] [ type ] [ subtype ] [ name ] = res ; } else { bundle . resources [ selector ] [ type ] [ name ] = res ; } }


Input: Determines whether a resource is filtered or not . [CODESPLIT] function ( res , filter ) { if ( ! filter || Object . keys ( filter ) . length === 0 ) { return true ; } var prop ; for ( prop in filter ) { if ( 'extensions' === prop ) { // sugar for users if ( 'string' === typeof filter . extensions ) { filter . extensions = filter . extensions . split ( ',' ) ; } if ( ! filter . extensions || filter . extensions . indexOf ( res . ext ) === - 1 ) { return false ; } } else if ( 'types' === prop ) { // sugar for users if ( 'string' === typeof filter . types ) { filter . types = filter . types . split ( ',' ) ; } if ( ! filter . types || filter . types . indexOf ( res . type ) === - 1 ) { return false ; } } else { return false ; // unknown filters should fail to pass } } return true ; }


Input: Walks a directory and returns a list of metadata about locator packages installed in that directory ( including the package for the directory itself ) . [CODESPLIT] function ( dir , _depth ) { var self = this , pkg , seed , seeds = [ ] , subdirs ; _depth = _depth || 0 ; try { pkg = require ( libpath . resolve ( dir , 'package.json' ) ) ; // top level package doesn't require a locator flag in package.json if ( ( 0 === _depth ) && ( ! pkg . locator ) ) { pkg . locator = { } ; } seed = this . _makeBundleSeed ( dir , libpath . basename ( dir ) , DEFAULT_VERSION , pkg ) ; if ( seed . options ) { seed . npmDepth = _depth ; seeds . push ( seed ) ; } } catch ( packageErr ) { // Some build environments leave extraneous directories in // node_modules and we should ignore them gracefully. // (trello board:Modown card:124) if ( 'MODULE_NOT_FOUND' !== packageErr . code ) { throw packageErr ; } return seeds ; } if ( _depth < this . _options . maxPackageDepth ) { try { subdirs = libfs . readdirSync ( libpath . join ( dir , 'node_modules' ) ) ; } catch ( readdirErr ) { if ( 'ENOENT' === readdirErr . code ) { // missing node_modules/ directory is OK return seeds ; } throw readdirErr ; } subdirs . reduce ( function ( memo , subdir ) { return memo . concat ( '@' === subdir . substring ( 0 , 1 ) ? libfs . readdirSync ( libpath . join ( dir , 'node_modules' , subdir ) ) . map ( function ( scopeddir ) { return libpath . join ( subdir , scopeddir ) ; } ) : [ subdir ] ) ; } , [ ] ) . forEach ( function ( subdir ) { var subpkgResults ; if ( '.' === subdir . substring ( 0 , 1 ) ) { return ; } subpkgResults = self . _walkNPMTree ( libpath . join ( dir , 'node_modules' , subdir ) , _depth + 1 ) ; // merge in found packages if ( subpkgResults && subpkgResults . length ) { seeds = seeds . concat ( subpkgResults ) ; } } ) ; } return seeds ; }


Input: Figures out which seed to use from the list of available packages . Select by depth then by semver . [CODESPLIT] function ( pkgDepths ) { // pkgDepths -> depth: [metas] var depths , minDepth , maxDepth , seeds ; depths = Object . keys ( pkgDepths ) ; minDepth = Math . min . apply ( Math , depths ) ; maxDepth = Math . max . apply ( Math , depths ) ; seeds = pkgDepths [ minDepth ] ; if ( 1 === seeds . length ) { if ( minDepth !== maxDepth ) { debug ( 'multiple "' + seeds [ 0 ] . name + '" packages found, using version ' + seeds [ 0 ] . version + ' from ' + seeds [ 0 ] . baseDirectory ) ; } return seeds [ 0 ] ; } seeds . sort ( function ( a , b ) { return libsemver . rcompare ( a . version , b . version ) ; } ) ; debug ( 'multiple "' + seeds [ 0 ] . name + '" packages found, using version ' + seeds [ 0 ] . version + ' from ' + seeds [ 0 ] . baseDirectory ) ; return seeds [ 0 ] ; }


Input: Figures out which bundles to use from the list . The returned list is sorted first by NPM package depth then by name . [CODESPLIT] function ( all ) { var byDepth = { } ; // name: depth: [metas] all . forEach ( function ( seed ) { if ( ! byDepth [ seed . name ] ) { byDepth [ seed . name ] = { } ; } if ( ! byDepth [ seed . name ] [ seed . npmDepth ] ) { byDepth [ seed . name ] [ seed . npmDepth ] = [ ] ; } byDepth [ seed . name ] [ seed . npmDepth ] . push ( seed ) ; } ) ; return Object . keys ( byDepth ) . map ( function ( name ) { return this . _dedupeSeeds ( byDepth [ name ] ) ; } , this ) ; }


Input: Creates a bundle from an NPM package and queues up files in the package . [CODESPLIT] function ( bundleSeed ) { var self = this , parentName , parent , bundle , filters ; // TODO -- merge options (second arg) over bundleSeed.options parentName = this . _getBundleNameByPath ( libpath . dirname ( bundleSeed . baseDirectory ) ) ; parent = this . _bundles [ parentName ] ; bundle = this . _makeBundle ( bundleSeed , parent ) ; this . _bundles [ bundle . name ] = bundle ; filters = this . _options . exclude . concat ( [ 'node_modules' , / ^\. / ] ) ; // adding the bundle dir itself for BC this . _processFile ( bundle . baseDirectory ) ; walk . walkSync ( bundle . baseDirectory , { filters : [ ] , listeners : { directories : function ( root , dirStatsArray , next ) { var i , dirStats , exclude ; function filterDir ( filter ) { if ( dirStats . name . match ( filter ) ) { return true ; } } for ( i = dirStatsArray . length - 1 ; i >= 0 ; i -= 1 ) { dirStats = dirStatsArray [ i ] ; exclude = filters . some ( filterDir ) ; if ( exclude ) { // the sync walk api is pretty bad, it requires to // mutate the actual dir array dirStatsArray . splice ( i , 1 ) ; } else { self . _processFile ( libpath . join ( root , dirStats . name ) ) ; } } next ( ) ; } , file : function ( root , fileStats , next ) { self . _processFile ( libpath . join ( root , fileStats . name ) ) ; next ( ) ; } , errors : function ( root , nodeStatsArray , next ) { next ( ) ; } } } ) ; return bundle ; }


Input: Loads the rulesets for the bundle ( or seed ) . [CODESPLIT] function ( bundle ) { var name = ( bundle . options && bundle . options . ruleset ) || DEFAULT_RULESET , cacheKey = name + '@' + bundle . baseDirectory , rulesetsPath , rulesets , dir , rules ; rules = this . _cacheRules [ cacheKey ] ; if ( rules ) { return rules ; } if ( bundle . options && bundle . options . rulesets ) { try { rulesetsPath = libpath . resolve ( bundle . baseDirectory , bundle . options . rulesets ) ; rulesets = require ( rulesetsPath ) ; } catch ( errLocal ) { if ( 'MODULE_NOT_FOUND' !== errLocal . code ) { throw errLocal ; } } if ( ! rulesets ) { dir = bundle . baseDirectory ; while ( dir ) { try { rulesetsPath = libpath . resolve ( dir , bundle . options . rulesets ) ; rulesets = require ( rulesetsPath ) ; break ; } catch ( errDir ) { if ( 'MODULE_NOT_FOUND' !== errDir . code ) { throw errDir ; } } try { rulesetsPath = libpath . resolve ( dir , 'node_modules' , bundle . options . rulesets ) ; rulesets = require ( rulesetsPath ) ; break ; } catch ( errDep ) { if ( 'MODULE_NOT_FOUND' !== errDep . code ) { throw errDep ; } } // not found, iterate dir = libpath . dirname ( dir ) ; if ( 'node_modules' === libpath . basename ( dir ) ) { dir = libpath . dirname ( dir ) ; } if ( this . _rootDirectory && dir . length < this . _rootDirectory . length ) { // if we can find the ruleset anywhere near in the filesystem // we should try to rely on npm lookup process try { rulesetsPath = Module . _resolveFilename ( bundle . options . rulesets , Module . _cache [ __filename ] ) ; rulesets = require ( rulesetsPath ) ; } catch ( errLocalMod ) { return ; } } } } // a ruleset pkg can contain multiple rulesets rules = rulesets [ name ] ; } else if ( this . _options . rulesetFn ) { // using the rulesetFn() hook to produce custom rules rules = this . _options . rulesetFn ( bundle ) ; } else { rules = DEFAULT_RULESETS [ name ] ; } if ( rules ) { rules . _name = name ; this . _cacheRules [ cacheKey ] = rules ; } return rules ; }


Input: Creates a new object with the certain keys excluded . This is used instead of delete since that has performance implications in V8 . [CODESPLIT] function ( srcObject , excludeKeys ) { var destObject = { } , key ; for ( key in srcObject ) { if ( srcObject . hasOwnProperty ( key ) ) { if ( - 1 === excludeKeys . indexOf ( key ) ) { destObject [ key ] = srcObject [ key ] ; } } } return destObject ; }


Input: The Locator walks the filesystem and gives semantic meaning to files in the application . [CODESPLIT] function Bundle ( baseDirectory , options ) { this . options = options || { } ; this . name = libpath . basename ( baseDirectory ) ; this . baseDirectory = baseDirectory ; this . type = undefined ; this . files = { } ; this . resources = { } ; }


Input: get a scale with logic for the x and y axis if the domain starts and finishes on the same number returns the mid range value [CODESPLIT] function getBaseScales ( type , domain , range , nice , tickCount ) { const factory = ( type === 'time' && scaleUtc ) || ( type === 'log' && scaleLog ) || scaleLinear const scale = createScale ( factory , domain , range ) if ( nice ) scale . nice ( tickCount ) return scale }


Input: generate the array of render data [CODESPLIT] function getLineRenderData ( props , data , idx ) { if ( isEmpty ( data ) ) return undefined const path2D = getPath2D ( ) const values = getPlotValues ( props , head ( data ) , idx , { hoverAlpha : 0.2 } ) if ( props . interpolate ) { splineInterpolation ( props , data , path2D ) } else { path2D . moveTo ( values . x , values . y ) reduce ( data , ( shouldDrawPoint , d ) => { const x = plotValue ( props , d , idx , 'x' ) const y = plotValue ( props , d , idx , 'y' ) if ( notPlotNumber ( [ x , y ] ) ) return false if ( shouldDrawPoint ) path2D . lineTo ( x , y ) else path2D . moveTo ( x , y ) return true } , true ) } return { ... values , data , hoverSolver , path2D , type : 'line' , } }


Input: / * points is used to generate render data for dots and similar . it handles x y radius and fill . [CODESPLIT] function getPointRenderData ( props , datum , idx ) { const values = getPlotValues ( props , datum , idx , { hoverAlpha : 0.75 , radius : 4 , x : getMidX ( props . plotRect ) , y : getMidY ( props . plotRect ) , } ) const path2D = getPath2D ( ) const hover2ndPath2D = getPath2D ( ) path2D . arc ( values . x , values . y , values . radius , 0 , 2 * Math . PI ) hover2ndPath2D . arc ( values . x , values . y , values . radius + 8 , 0 , 2 * Math . PI ) return { ... values , hover2ndPath2D , path2D , type : 'area' , } }


Input: Start with the input props send them to the first transform merge the returned new props back to the props . Do again with the next transform . const rootProps = chartTransformFlow ( props t1 t2 t3 ) [CODESPLIT] function removeDimArrays ( props ) { const names = map ( props . groupedKeys , key => ` ${ key } ` ) return omit ( props , names ) }


Input: generate the array of render data [CODESPLIT] function getTextRenderData ( props , datum , idx ) { const { plotRect , theme , width , height } = props const values = getPlotValues ( props , datum , idx , { x : getMidX ( props . plotRect ) , y : getMidY ( props . plotRect ) , } ) if ( values . textSnap === 'top' ) values . y = getMinY ( plotRect ) if ( values . textSnap === 'bottom' ) values . y = getMaxY ( plotRect ) if ( values . textSnap === 'left' ) values . x = getMinX ( plotRect ) if ( values . textSnap === 'right' ) values . x = getMaxX ( plotRect ) if ( values . textSnap === 'topLeft' ) { values . x = getMinX ( plotRect ) values . y = getMinY ( plotRect ) } if ( values . textSnap === 'topRight' ) { values . x = getMaxX ( plotRect ) values . y = getMinY ( plotRect ) } if ( values . textSnap === 'bottomLeft' ) { values . x = getMinX ( plotRect ) values . y = getMaxY ( plotRect ) } if ( values . textSnap === 'bottomRight' ) { values . x = getMaxX ( plotRect ) values . y = getMaxY ( plotRect ) } const newValues = fitCheckText ( values , width , height , theme ) return { ... newValues , type : 'text' } }


Input: Buffer traces and defer recording until maxTraces have been received or sendInterval has elapsed since the last trace was recorded . [CODESPLIT] function BufferingTracer ( tracer , options ) { options = options || { } ; var self = this ; this . _tracer = tracer ; this . _maxTraces = options . maxTraces || 50 ; this . _sendInterval = options . sendInterval ? ( options . sendInterval * 1000 ) : 10 * 1000 ; this . _lastSentTs = Date . now ( ) ; this . _buffer = [ ] ; this . _stopped = false ; this . _periodSendTimeoutId = setTimeout ( this . _periodicSendFunction . bind ( this ) , this . _sendInterval ) ; }


Input: A tracer that records to zipkin through the RESTkin http interface . Requires a keystone client ( { node - keystone - client } ) . [CODESPLIT] function RawRESTkinHTTPTracer ( traceUrl , keystoneClient ) { if ( traceUrl . charAt ( traceUrl . length - 1 ) === '/' ) { traceUrl = traceUrl . slice ( 0 , - 1 ) ; } this . _traceUrl = traceUrl ; this . _keystoneClient = keystoneClient ; EndAnnotationTracer . call ( this , this . sendTraces ) ; }


Input: A tracer that records to zipkin through the RESTkin http interface . Requires a keystone client ( { node - keystone - client } ) . [CODESPLIT] function RESTkinHTTPTracer ( traceUrl , keystoneClient , options ) { var rawTracer = new module . exports . RawRESTkinHTTPTracer ( traceUrl , keystoneClient ) ; this . _tracer = new module . exports . BufferingTracer ( rawTracer , options ) ; this . stop = this . _tracer . stop . bind ( this . _tracer ) ; EndAnnotationTracer . call ( this , this . sendTraces ) ; }


Input: A tracer that records directly to Zipkin Query HTTP API . [CODESPLIT] function RawZipkinQueryServiceHTTPTracer ( traceUrl ) { if ( traceUrl . charAt ( traceUrl . length - 1 ) === '/' ) { traceUrl = traceUrl . slice ( 0 , - 1 ) ; } this . _traceUrl = traceUrl ; EndAnnotationTracer . call ( this , this . sendTraces ) ; }


Input: A tracer that records directly to Zipkin Query HTTP API . [CODESPLIT] function ZipkinQueryServiceHTTPTracer ( serviceUrl , options ) { var rawTracer = new module . exports . RawZipkinQueryServiceHTTPTracer ( serviceUrl ) ; this . _tracer = new module . exports . BufferingTracer ( rawTracer , options ) ; this . stop = this . _tracer . stop . bind ( this . _tracer ) ; EndAnnotationTracer . call ( this , this . sendTraces ) ; }


Input: A tracer that records to zipkin through scribe . Requires a scribe client ( { node - scribe } ) . [CODESPLIT] function RawZipkinTracer ( scribeClient , category ) { this . scribeClient = scribeClient ; this . category = ( category ) ? category : 'zipkin' ; EndAnnotationTracer . call ( this , this . sendTraces ) ; }


Input: A tracer that records to zipkin through scribe . Requires a scribe client ( { node - scribe } ) . [CODESPLIT] function ZipkinTracer ( scribeClient , category , options ) { var rawTracer = new RawZipkinTracer ( scribeClient , category ) ; this . _tracer = new BufferingTracer ( rawTracer , options ) ; this . stop = this . _tracer . stop . bind ( this . _tracer ) ; EndAnnotationTracer . call ( this , this . sendTraces ) ; }


Input: A tracer that records to RESTkin through scribe . Requires a scribe client ( { node - scribe } ) . [CODESPLIT] function RawRESTkinScribeTracer ( scribeClient , category ) { this . scribeClient = scribeClient ; this . category = ( category ) ? category : 'restkin' ; EndAnnotationTracer . call ( this , this . sendTraces ) ; }


Input: A tracer that records to RESTkin through scribe . Requires a scribe client ( { node - scribe } ) . [CODESPLIT] function RESTkinScribeTracer ( scribeClient , category , options ) { var rawTracer = new RawRESTkinScribeTracer ( scribeClient , category ) ; this . _tracer = new module . exports . BufferingTracer ( rawTracer , options ) ; this . stop = this . _tracer . stop . bind ( this . _tracer ) ; EndAnnotationTracer . call ( this , this . sendTraces ) ; }


Input: Analyzes given gulp instance and build internal cache for further printing [CODESPLIT] function build ( gulp ) { // make sure we don't lose anything from required files // @see https://github.com/Mikhus/gulp-help-doc/issues/2 // currently this is not supported for typescript var source = OPTIONS . isTypescript ? fs . readFileSync ( 'gulpfile.ts' ) . toString ( ) : OPTIONS . gulpfile ? fs . readFileSync ( OPTIONS . gulpfile ) . toString ( ) : Object . keys ( require . cache || { 'gulpfile.js' : '' } ) . map ( function ( file ) { if ( ! / node_modules|\.json$ / . test ( file ) ) { return fs . readFileSync ( file ) . toString ( ) + '\n' ; } } ) . join ( '' ) ; var rxDoc = '\\/\\*\\*\\r?\n(((?!\\*\\/)[\\s\\S])*?)' + '@task\\s+\\{(.*)?\\}((?!\\*\\/)[\\s\\S])*?\\*\\/' ; var rxArgs = '@arg\\s+\\{(.*?)\\}(.*?)\\r?\\n' ; var rxOrder = '@order\\s+\\{(\\d+)\\}(.*?)\\r?\\n' ; var rxGroup = '@group\\s+\\{(.*?)\\}(.*?)\\r?\\n' ; var globalRxDoc = new RegExp ( rxDoc , 'g' ) ; var localRxDoc = new RegExp ( rxDoc ) ; var globalRxArgs = new RegExp ( rxArgs , 'g' ) ; var localRxArgs = new RegExp ( rxArgs ) ; var globalRxOrder = new RegExp ( rxOrder , 'g' ) ; var localRxOrder = new RegExp ( rxOrder ) ; var globalRxGroup = new RegExp ( rxGroup , 'g' ) ; var localRxGroup = new RegExp ( rxGroup ) ; var jsDoc = ( source . match ( globalRxDoc ) || [ ] ) ; var tasks = gulpTasks ( gulp ) ; Object . keys ( tasks ) . forEach ( function ( task ) { reflection [ task ] = { name : tasks [ task ] . name , desc : '' , dep : tasks [ task ] . dep } ; } ) ; jsDoc . map ( function ( block ) { var parts = block . match ( localRxDoc ) ; var name = parts [ 3 ] . trim ( ) ; var desc = parts [ 1 ] . replace ( / \s*\* / g , ' ' ) . replace ( / \s{2,} / g , ' ' ) . trim ( ) ; if ( ! reflection [ name ] ) { return ; } reflection [ name ] . desc = desc ; reflection [ name ] . public = true ; reflection [ name ] . args = ( block . match ( globalRxArgs ) || [ ] ) . map ( function ( def ) { var argsParts = def . match ( localRxArgs ) ; return { name : argsParts [ 1 ] , desc : argsParts [ 2 ] . replace ( / \s*\* / g , ' ' ) . replace ( / \s{2,} / g , ' ' ) . trim ( ) } ; } ) ; reflection [ name ] . order = ( function ( ) { var orderParts = block . match ( globalRxOrder ) ; if ( orderParts ) { return + orderParts [ 0 ] . match ( localRxOrder ) [ 1 ] ; } return Number . MAX_SAFE_INTEGER ; } ) ( ) ; reflection [ name ] . group = ( function ( ) { var groupParts = block . match ( globalRxGroup ) ; if ( groupParts ) { return groupParts [ 0 ] . match ( localRxGroup ) [ 1 ] ; } return OPTIONS . defaultGroupName ; } ) ( ) ; } ) ; // Re-group tasks using user-defined groups var tmp = { } ; Object . keys ( reflection ) . forEach ( function ( task ) { var group = reflection [ task ] . group || OPTIONS . defaultGroupName ; tmp [ group ] = tmp [ group ] || { } ; tmp [ group ] [ task ] = reflection [ task ] ; } ) ; reflection = tmp ; }


Input: Chunks given string into pieces making each chunk less or equal to OPTIONS . lineWidth taking into account safe word - break [CODESPLIT] function chunk ( str , maxLen ) { var len = maxLen || OPTIONS . lineWidth ; var curr = len ; var prev = 0 ; var out = [ ] ; while ( str [ curr ] ) { if ( str [ curr ++ ] == ' ' ) { out . push ( str . substring ( prev , curr ) ) ; prev = curr ; curr += len ; } } out . push ( str . substr ( prev ) ) ; return out ; }


Input: Prints usage help information for the given gulp instance . Usually it is used as a task within gulpfile . js in your project Please make sure all your comments are properly annotated [CODESPLIT] function usage ( gulp , options ) { // re-define options if needed if ( options ) { Object . assign ( OPTIONS , options ) ; } return new Promise ( function ( resolve ) { build ( gulp ) ; print ( ) ; resolve ( ) ; } ) ; }