function() {
	var metaDesc = this.data.metaDesc;

	if ( isEmpty( metaDesc ) ) {
		metaDesc = this.opts.defaultValue.metaDesc;
	}

	if ( this.hasPluggable() ) {
		metaDesc = this.refObj.pluggable._applyModifications( "data_meta_desc", metaDesc );
	}

	if ( ! isEmpty( this.opts.metaDescriptionDate ) && ! isEmpty( metaDesc ) ) {
		metaDesc = this.opts.metaDescriptionDate + " - " + this.data.metaDesc;
	}

	return stripSpaces( metaDesc );
}

function
(
)
{
var
metaDesc
=
this
.
data
.
metaDesc
;
if
(
isEmpty
(
metaDesc
)
)
{
metaDesc
=
this
.
opts
.
defaultValue
.
metaDesc
;
}
if
(
this
.
hasPluggable
(
)
)
{
metaDesc
=
this
.
refObj
.
pluggable
.
_applyModifications
(
"data_meta_desc"
,
metaDesc
)
;
}
if
(
!
isEmpty
(
this
.
opts
.
metaDescriptionDate
)
&&
!
isEmpty
(
metaDesc
)
)
{
metaDesc
=
this
.
opts
.
metaDescriptionDate
+
" - "
+
this
.
data
.
metaDesc
;
}
return
stripSpaces
(
metaDesc
)
;
}

Returns the metaDescription, includes the date if it is set.

@private
@this SnippetPreview

@returns {string} The meta data for the analyzer.

Returns the metaDescription includes the date if it is set .


function showTrace( errorMessage ) {
	if ( isUndefined( errorMessage ) ) {
		errorMessage = "";
	}

	if (
		! isUndefined( console ) &&
		! isUndefined( console.trace )
	) {
		console.trace( errorMessage );
	}
}

function showTrace ( errorMessage ) { if ( isUndefined ( errorMessage ) ) { errorMessage = "" ; } if ( ! isUndefined ( console ) && ! isUndefined ( console . trace ) ) { console . trace ( errorMessage ) ; } }

Shows and error trace of the error message in the console if the console is available.

@param {string} [errorMessage=""] The error message.
@returns {void}

Shows and error trace of the error message in the console if the console is available .


function getIndicesByWord( word, text ) {
	var startIndex = 0;
	var searchStringLength = word.length;
	var index, indices = [];
	while ( ( index = text.indexOf( word, startIndex ) ) > -1 ) {
		// Check if the previous and next character are word boundaries to determine if a complete word was detected
		var isPreviousCharacterWordBoundary = characterInBoundary( text[ index - 1 ] ) || index === 0;

		var isNextCharacterWordBoundary = characterInBoundary( text[ index + searchStringLength ] ) || ( text.length === index + searchStringLength );

		if ( isPreviousCharacterWordBoundary && isNextCharacterWordBoundary ) {
			indices.push(
				{
					index: index,
					match: word,
				}
			);
		}
		startIndex = index + searchStringLength;
	}
	return indices;
}

Returns the indices of a string in a text. If it is found multiple times, it will return multiple indices.

@param {string} word The word to find in the text.
@param {string} text The text to check for the given word.
@returns {Array} All indices found.

Returns the indices of a string in a text . If it is found multiple times it will return multiple indices .


function( words, text ) {
	var matchedWords = [];

	forEach( words, function( word ) {
		word = stripSpaces( word );
		if ( ! matchWordInSentence( word, text ) ) {
			return;
		}
		matchedWords = matchedWords.concat( getIndicesByWord( word, text ) );
	} );
	return matchedWords;
}

function ( words , text ) { var matchedWords = [ ] ; forEach ( words , function ( word ) { word = stripSpaces ( word ) ; if ( ! matchWordInSentence ( word , text ) ) { return ; } matchedWords = matchedWords . concat ( getIndicesByWord ( word , text ) ) ; } ) ; return matchedWords ; }

Matches string with an array, returns the word and the index it was found on.

@param {Array} words The array with strings to match.
@param {string} text The text to match the strings from the array to.
@returns {Array} The array with words, containing the index of the match and the matched string.
Returns an empty array if none are found.

Matches string with an array returns the word and the index it was found on .


function( indices ) {
	indices = sortIndices( indices );
	var filtered = [];
	for ( var i = 0; i < indices.length; i++ ) {
		// If the next index is within the range of the current index and the length of the word, remove it
		// This makes sure we don't match combinations twice, like "even though" and "though".
		if ( ! isUndefined( indices[ i + 1 ] ) && indices[ i + 1 ].index < indices[ i ].index + indices[ i ].match.length ) {
			filtered.push( indices[ i ] );

			// Adds 1 to i, so we skip the next index that is overlapping with the current index.
			i++;
			continue;
		}
		filtered.push( indices[ i ] );
	}
	return filtered;
}

Filters duplicate entries if the indices overlap.

@param {Array} indices The array with indices to be filtered.
@returns {Array} The filtered array.

Filters duplicate entries if the indices overlap .


function( words, text ) {
	var matchedWords = [];

	forEach( words, function( word ) {
		word = stripSpaces( word );
		if ( ! matchWordInSentence( word, text ) ) {
			return matchedWords;
		}
		matchedWords = matchedWords.concat( getIndicesByWord( word, text ) );
	} );

	matchedWords = matchedWords.sort( function( a, b ) {
		if ( a.index < b.index ) {
			return -1;
		}
		if ( a.index > b.index ) {
			return 1;
		}
		return 0;
	} );

	return matchedWords;
}

function ( words , text ) { var matchedWords = [ ] ; forEach ( words , function ( word ) { word = stripSpaces ( word ) ; if ( ! matchWordInSentence ( word , text ) ) { return matchedWords ; } matchedWords = matchedWords . concat ( getIndicesByWord ( word , text ) ) ; } ) ; matchedWords = matchedWords . sort ( function ( a , b ) { if ( a . index < b . index ) { return - 1 ; } if ( a . index > b . index ) { return 1 ; } return 0 ; } ) ; return matchedWords ; }

Matches string with an array, returns the word and the index it was found on, and sorts the match instances based on
the index property of the match.

@param {Array} words The array with strings to match.
@param {string} text The text to match the strings from the array to.
@returns {Array} The array with words, containing the index of the match and the matched string.
Returns an empty array if none are found.

Matches string with an array returns the word and the index it was found on and sorts the match instances based on the index property of the match .


function createMeasurementElement() {
	const hiddenElement = document.createElement( "div" );

	hiddenElement.id = elementId;

	// Styles to prevent unintended scrolling in Gutenberg.
	hiddenElement.style.position = "absolute";
	hiddenElement.style.left = "-9999em";
	hiddenElement.style.top = 0;
	hiddenElement.style.height = 0;
	hiddenElement.style.overflow = "hidden";
	hiddenElement.style.fontFamily = "arial, sans-serif";
	hiddenElement.style.fontSize = "18px";
	hiddenElement.style.fontWeight = "400";

	document.body.appendChild( hiddenElement );
	return hiddenElement;
}

Creates an hidden element with the purpose to calculate the sizes of elements and adds these elements to the body.

@returns {HTMLElement} The created hidden element.

Creates an hidden element with the purpose to calculate the sizes of elements and adds these elements to the body .


function( app ) {
	this.app = app;
	this.loaded = false;
	this.preloadThreshold = 3000;
	this.plugins = {};
	this.modifications = {};
	this.customTests = [];

	// Allow plugins 1500 ms to register before we start polling their
	setTimeout( this._pollLoadingPlugins.bind( this ), 1500 );
}

The plugins object takes care of plugin registrations, preloading and managing data modifications.

A plugin for YoastSEO.js is basically a piece of JavaScript that hooks into YoastSEO.js by registering modifications.
In order to do so, it must first register itself as a plugin with YoastSEO.js. To keep our content analysis fast, we
don't allow asynchronous modifications. That's why we require plugins to preload all data they need in order to modify
the content. If plugins need to preload data, they can first register, then preload using AJAX and call `ready` once
preloaded.

To minimize client side memory usage, we request plugins to preload as little data as possible. If you need to dynamically
fetch more data in the process of content creation, you can reload your data set and let YoastSEO.js know you've reloaded
by calling `reloaded`.

Setup Pluggable and set its default values.

@constructor
@param       {App}       app                 The App object to attach to.
@property    {number}    preloadThreshold	The maximum time plugins are allowed to preload before we load our content analysis.
@property    {object}    plugins             The plugins that have been registered.
@property    {object}    modifications 	    The modifications that have been registered. Every modification contains an array with callables.
@property    {Array}     customTests         All tests added by plugins.

The plugins object takes care of plugin registrations preloading and managing data modifications .


function( paper ) {
	this.setPaper( paper );

	this.defaultResearches = {
		urlLength: urlLength,
		wordCountInText: wordCountInText,
		findKeywordInPageTitle: findKeywordInPageTitle,
		calculateFleschReading: calculateFleschReading,
		getLinkStatistics: getLinkStatistics,
		getLinks: getLinks,
		linkCount: linkCount,
		imageCount: imageCount,
		altTagCount: altTagCount,
		matchKeywordInSubheadings: matchKeywordInSubheadings,
		keywordCount: keywordCount,
		getKeywordDensity: getKeywordDensity,
		stopWordsInKeyword: stopWordsInKeyword,
		stopWordsInUrl: stopWordsInUrl,
		metaDescriptionLength: metaDescriptionLength,
		keyphraseLength: keyphraseLength,
		keywordCountInUrl: keywordCountInUrl,
		firstParagraph: findKeywordInFirstParagraph,
		metaDescriptionKeyword: metaDescriptionKeyword,
		pageTitleWidth: pageTitleWidth,
		wordComplexity: wordComplexity,
		getParagraphLength: getParagraphLength,
		countSentencesFromText: countSentencesFromText,
		countSentencesFromDescription: countSentencesFromDescription,
		getSubheadingTextLengths: getSubheadingTextLengths,
		findTransitionWords: findTransitionWords,
		passiveVoice: passiveVoice,
		getSentenceBeginnings: getSentenceBeginnings,
		relevantWords: relevantWords,
		readingTime: readingTime,
		getTopicDensity: getTopicDensity,
		topicCount: topicCount,
		sentences,
		keyphraseDistribution: keyphraseDistribution,
		morphology: morphology,
		functionWordsInKeyphrase: functionWordsInKeyphrase,
		h1s: h1s,
	};

	this._data = {};

	this.customResearches = {};
}

function ( paper ) { this . setPaper ( paper ) ; this . defaultResearches = { urlLength : urlLength , wordCountInText : wordCountInText , findKeywordInPageTitle : findKeywordInPageTitle , calculateFleschReading : calculateFleschReading , getLinkStatistics : getLinkStatistics , getLinks : getLinks , linkCount : linkCount , imageCount : imageCount , altTagCount : altTagCount , matchKeywordInSubheadings : matchKeywordInSubheadings , keywordCount : keywordCount , getKeywordDensity : getKeywordDensity , stopWordsInKeyword : stopWordsInKeyword , stopWordsInUrl : stopWordsInUrl , metaDescriptionLength : metaDescriptionLength , keyphraseLength : keyphraseLength , keywordCountInUrl : keywordCountInUrl , firstParagraph : findKeywordInFirstParagraph , metaDescriptionKeyword : metaDescriptionKeyword , pageTitleWidth : pageTitleWidth , wordComplexity : wordComplexity , getParagraphLength : getParagraphLength , countSentencesFromText : countSentencesFromText , countSentencesFromDescription : countSentencesFromDescription , getSubheadingTextLengths : getSubheadingTextLengths , findTransitionWords : findTransitionWords , passiveVoice : passiveVoice , getSentenceBeginnings : getSentenceBeginnings , relevantWords : relevantWords , readingTime : readingTime , getTopicDensity : getTopicDensity , topicCount : topicCount , sentences , keyphraseDistribution : keyphraseDistribution , morphology : morphology , functionWordsInKeyphrase : functionWordsInKeyphrase , h1s : h1s , } ; this . _data = { } ; this . customResearches = { } ; }

This contains all possible, default researches.
@param {Paper} paper The Paper object that is needed within the researches.
@constructor
@throws {InvalidTypeError} Parameter needs to be an instance of the Paper object.

This contains all possible default researches .


function areEqual( urlA, urlB ) {
	// Make sure we are comparing URLs without query arguments and hashes.
	urlA = removeQueryArgs( removeHash( urlA ) );
	urlB = removeQueryArgs( removeHash( urlB ) );

	return addTrailingSlash( urlA ) === addTrailingSlash( urlB );
}

Returns whether or not the given URLs are equal.

@param {string} urlA The first URL to compare.
@param {string} urlB The second URL to compare.

@returns {boolean} Whether or not the given URLs are equal.

Returns whether or not the given URLs are equal .


function isInternalLink( url, host ) {
	const parsedUrl = urlMethods.parse( url, false, true );
	// Check if the URL starts with a single slash.
	if ( url.indexOf( "//" ) === -1 && url.indexOf( "/" ) === 0 ) {
		return true;
	}

	// Check if the URL starts with a # indicating a fragment.
	if ( url.indexOf( "#" ) === 0 ) {
		return false;
	}

	// No host indicates an internal link.
	if ( ! parsedUrl.host ) {
		return true;
	}

	return parsedUrl.host === host;
}

Determine whether a URL is internal.

@param {string} url The URL to test.
@param {string} host The current host.

@returns {boolean} Whether or not the URL is internal.


function( word, locale ) {
	var numberOfSyllables = 0;
	var vowelRegex = new RegExp( "[^" + syllableMatchers( locale ).vowels + "]", "ig" );
	var foundVowels = word.split( vowelRegex );
	var filteredWords = filter( foundVowels, function( vowel ) {
		return vowel !== "";
	} );
	numberOfSyllables += filteredWords.length;

	return numberOfSyllables;
}

function ( word , locale ) { var numberOfSyllables = 0 ; var vowelRegex = new RegExp ( "[^" + syllableMatchers ( locale ) . vowels + "]" , "ig" ) ; var foundVowels = word . split ( vowelRegex ) ; var filteredWords = filter ( foundVowels , function ( vowel ) { return vowel !== "" ; } ) ; numberOfSyllables += filteredWords . length ; return numberOfSyllables ; }

Counts vowel groups inside a word.

@param {string} word A text with words to count syllables.
@param {String} locale The locale to use for counting syllables.
@returns {number} the syllable count.


function( word, locale ) {
	var fullWordDeviations = syllableMatchers( locale ).deviations.words.full;

	var deviation = find( fullWordDeviations, function( fullWordDeviation ) {
		return fullWordDeviation.word === word;
	} );

	if ( ! isUndefined( deviation ) ) {
		return deviation.syllables;
	}

	return 0;
}

function ( word , locale ) { var fullWordDeviations = syllableMatchers ( locale ) . deviations . words . full ; var deviation = find ( fullWordDeviations , function ( fullWordDeviation ) { return fullWordDeviation . word === word ; } ) ; if ( ! isUndefined ( deviation ) ) { return deviation . syllables ; } return 0 ; }

Returns the number of syllables for the word if it is in the list of full word deviations.

@param {String} word The word to retrieve the syllables for.
@param {String} locale The locale to use for counting syllables.
@returns {number} The number of syllables found.

Returns the number of syllables for the word if it is in the list of full word deviations .


function createDeviationFragments( syllableConfig ) {
	var deviationFragments = [];

	var deviations = syllableConfig.deviations;

	if ( ! isUndefined( deviations.words ) && ! isUndefined( deviations.words.fragments ) ) {
		deviationFragments = flatMap( deviations.words.fragments, function( fragments, fragmentLocation ) {
			return map( fragments, function( fragment ) {
				fragment.location = fragmentLocation;

				return new DeviationFragment( fragment );
			} );
		} );
	}

	return deviationFragments;
}

function createDeviationFragments ( syllableConfig ) { var deviationFragments = [ ] ; var deviations = syllableConfig . deviations ; if ( ! isUndefined ( deviations . words ) && ! isUndefined ( deviations . words . fragments ) ) { deviationFragments = flatMap ( deviations . words . fragments , function ( fragments , fragmentLocation ) { return map ( fragments , function ( fragment ) { fragment . location = fragmentLocation ; return new DeviationFragment ( fragment ) ; } ) ; } ) ; } return deviationFragments ; }

Creates an array of deviation fragments for a certain locale.

@param {Object} syllableConfig Syllable config for a certain locale.
@returns {DeviationFragment[]} A list of deviation fragments

Creates an array of deviation fragments for a certain locale .


function( word, locale ) {
	var deviationFragments = createDeviationFragmentsMemoized( syllableMatchers( locale ) );
	var remainingParts = word;
	var syllableCount = 0;

	forEach( deviationFragments, function( deviationFragment ) {
		if ( deviationFragment.occursIn( remainingParts ) ) {
			remainingParts = deviationFragment.removeFrom( remainingParts );
			syllableCount += deviationFragment.getSyllables();
		}
	} );

	return { word: remainingParts, syllableCount: syllableCount };
}

function ( word , locale ) { var deviationFragments = createDeviationFragmentsMemoized ( syllableMatchers ( locale ) ) ; var remainingParts = word ; var syllableCount = 0 ; forEach ( deviationFragments , function ( deviationFragment ) { if ( deviationFragment . occursIn ( remainingParts ) ) { remainingParts = deviationFragment . removeFrom ( remainingParts ) ; syllableCount += deviationFragment . getSyllables ( ) ; } } ) ; return { word : remainingParts , syllableCount : syllableCount } ; }

Counts syllables in partial exclusions. If these are found, returns the number of syllables  found, and the modified word.
The word is modified so the excluded part isn't counted by the normal syllable counter.

@param {String} word The word to count syllables of.
@param {String} locale The locale to use for counting syllables.
@returns {object} The number of syllables found and the modified word.

Counts syllables in partial exclusions . If these are found returns the number of syllables found and the modified word . The word is modified so the excluded part isn t counted by the normal syllable counter .


function( word, locale ) {
	var syllableCount = 0;

	syllableCount += countVowelGroups( word, locale );
	syllableCount += countVowelDeviations( word, locale );

	return syllableCount;
}

function ( word , locale ) { var syllableCount = 0 ; syllableCount += countVowelGroups ( word , locale ) ; syllableCount += countVowelDeviations ( word , locale ) ; return syllableCount ; }

Count the number of syllables in a word, using vowels and exceptions.

@param {String} word The word to count the number of syllables of.
@param {String} locale The locale to use for counting syllables.
@returns {number} The number of syllables found in a word.

Count the number of syllables in a word using vowels and exceptions .


function( word, locale ) {
	var syllableCount = 0;

	var fullWordExclusion = countFullWordDeviations( word, locale );
	if ( fullWordExclusion !== 0 ) {
		return fullWordExclusion;
	}

	var partialExclusions = countPartialWordDeviations( word, locale );
	word = partialExclusions.word;
	syllableCount += partialExclusions.syllableCount;
	syllableCount += countUsingVowels( word, locale );

	return syllableCount;
}

function ( word , locale ) { var syllableCount = 0 ; var fullWordExclusion = countFullWordDeviations ( word , locale ) ; if ( fullWordExclusion !== 0 ) { return fullWordExclusion ; } var partialExclusions = countPartialWordDeviations ( word , locale ) ; word = partialExclusions . word ; syllableCount += partialExclusions . syllableCount ; syllableCount += countUsingVowels ( word , locale ) ; return syllableCount ; }

Counts the number of syllables in a word.

@param {string} word The word to count syllables of.
@param {string} locale The locale of the word.
@returns {number} The syllable count for the word.

Counts the number of syllables in a word .


function( text, locale ) {
	text = text.toLocaleLowerCase();
	var words = getWords( text );

	var syllableCounts = map( words,  function( word ) {
		return countSyllablesInWord( word, locale );
	} );

	return sum( syllableCounts );
}

function ( text , locale ) { text = text . toLocaleLowerCase ( ) ; var words = getWords ( text ) ; var syllableCounts = map ( words , function ( word ) { return countSyllablesInWord ( word , locale ) ; } ) ; return sum ( syllableCounts ) ; }

Counts the number of syllables in a text per word based on vowels.
Uses exclusion words for words that cannot be matched with vowel matching.

@param {String} text The text to count the syllables of.
@param {String} locale The locale to use for counting syllables.
@returns {int} The total number of syllables found in the text.

Counts the number of syllables in a text per word based on vowels . Uses exclusion words for words that cannot be matched with vowel matching .


function( array, language ) {
	if ( isUndefined( language ) || language === "" ) {
		language = "en";
	}

	const functionWords = get( getFunctionWords, [ language ], [] );

	if ( array.length > 1 ) {
		const arrayFiltered = filter( array, function( word ) {
			return ( ! includes( functionWords.all, word.trim().toLocaleLowerCase() ) );
		} );

		if ( arrayFiltered.length > 0 ) {
			return arrayFiltered;
		}
	}

	return array;
}

function ( array , language ) { if ( isUndefined ( language ) || language === "" ) { language = "en" ; } const functionWords = get ( getFunctionWords , [ language ] , [ ] ) ; if ( array . length > 1 ) { const arrayFiltered = filter ( array , function ( word ) { return ( ! includes ( functionWords . all , word . trim ( ) . toLocaleLowerCase ( ) ) ) ; } ) ; if ( arrayFiltered . length > 0 ) { return arrayFiltered ; } } return array ; }

Filters function words from an array of words based on the language.

@param {Array} array The words to check.
@param {string} language The language to take function words for.

@returns {Array} The original array with the function words filtered out.

Filters function words from an array of words based on the language .


function( keyphrase, synonyms, language = "en", morphologyData ) {
	const synonymsSplit = parseSynonyms( synonyms );

	const keyphraseForms = buildForms( keyphrase, language, morphologyData );
	const synonymsForms = synonymsSplit.map( synonym => buildForms( synonym, language, morphologyData ) );

	return {
		keyphraseForms: keyphraseForms,
		synonymsForms: synonymsForms,
	};
}

function ( keyphrase , synonyms , language = "en" , morphologyData ) { const synonymsSplit = parseSynonyms ( synonyms ) ; const keyphraseForms = buildForms ( keyphrase , language , morphologyData ) ; const synonymsForms = synonymsSplit . map ( synonym => buildForms ( synonym , language , morphologyData ) ) ; return { keyphraseForms : keyphraseForms , synonymsForms : synonymsForms , } ; }

Builds morphological forms of words of the keyphrase and of each synonym phrase.

@param {string} keyphrase The paper's keyphrase.
@param {string} synonyms The paper's synonyms.
@param {string} language The paper's language.
@param {Object} morphologyData The available morphology data to be used by the getForms function (language specific).

@returns {Object} Object with an array of keyphrase forms and an array of arrays of synonyms forms.

Builds morphological forms of words of the keyphrase and of each synonym phrase .


function collectForms( keyphrase, synonyms, language = "en", morphologyData ) {
	const collectFormsWithMorphologyData = primeMorphologyData( morphologyData );

	return collectFormsWithMorphologyData( keyphrase, synonyms, language );
}

function collectForms ( keyphrase , synonyms , language = "en" , morphologyData ) { const collectFormsWithMorphologyData = primeMorphologyData ( morphologyData ) ; return collectFormsWithMorphologyData ( keyphrase , synonyms , language ) ; }

Retrieves morphological forms of words of the keyphrase and of each synonym phrase using the function that caches
the results of previous calls of this function.

@param {string} keyphrase The paper's keyphrase.
@param {string} synonyms The paper's synonyms.
@param {string} language The paper's language.
@param {Object} morphologyData The available morphology data to be used by the getForms function (language specific).

@returns {Object} Object with an array of keyphrase forms and an array of arrays of synonyms forms.

Retrieves morphological forms of words of the keyphrase and of each synonym phrase using the function that caches the results of previous calls of this function .


function research( paper, researcher ) {
	const language = getLanguage( paper.getLocale() );

	const morphologyData = get( researcher.getData( "morphology" ), [ language ], false );

	return collectForms( paper.getKeyword(), paper.getSynonyms(), language, morphologyData );
}

function research ( paper , researcher ) { const language = getLanguage ( paper . getLocale ( ) ) ; const morphologyData = get ( researcher . getData ( "morphology" ) , [ language ] , false ) ; return collectForms ( paper . getKeyword ( ) , paper . getSynonyms ( ) , language , morphologyData ) ; }

Calls the function that builds keyphrase and synonyms forms for a specific research data.

@param {Paper} paper The paper to build keyphrase and synonym forms for.
@param {Researcher} researcher The researcher prototype.

@returns {Object} Object with an array of keyphrase forms and an array of arrays of synonyms forms.

Calls the function that builds keyphrase and synonyms forms for a specific research data .


function InvalidTypeError( message ) {
	Error.captureStackTrace( this, this.constructor );
	this.name = this.constructor.name;
	this.message = message;
}

function InvalidTypeError ( message ) { Error . captureStackTrace ( this , this . constructor ) ; this . name = this . constructor . name ; this . message = message ; }

Throws an invalid type error

@param {string} message The message to show when the error is thrown

@returns {void}


function getRegexFromDoubleArray( twoPartTransitionWords ) {
	const cacheKey = flattenDeep( twoPartTransitionWords ).join( "" );
	if ( regexFromDoubleArrayCacheKey !== cacheKey || regexFromDoubleArray === null ) {
		regexFromDoubleArrayCacheKey = cacheKey;
		regexFromDoubleArray = createRegexFromDoubleArray( twoPartTransitionWords );
	}
	return regexFromDoubleArray;
}

function getRegexFromDoubleArray ( twoPartTransitionWords ) { const cacheKey = flattenDeep ( twoPartTransitionWords ) . join ( "" ) ; if ( regexFromDoubleArrayCacheKey !== cacheKey || regexFromDoubleArray === null ) { regexFromDoubleArrayCacheKey = cacheKey ; regexFromDoubleArray = createRegexFromDoubleArray ( twoPartTransitionWords ) ; } return regexFromDoubleArray ; }

Memoizes the createRegexFromDoubleArray with the twoPartTransitionWords.

@param {Array} twoPartTransitionWords The array containing two-part transition words.

@returns {RegExp} The RegExp to match text with a double array.

Memoizes the createRegexFromDoubleArray with the twoPartTransitionWords .


function( sentence, twoPartTransitionWords ) {
	sentence = normalizeSingleQuotes( sentence );
	const twoPartTransitionWordsRegex = getRegexFromDoubleArray( twoPartTransitionWords );
	return sentence.match( twoPartTransitionWordsRegex );
}

function ( sentence , twoPartTransitionWords ) { sentence = normalizeSingleQuotes ( sentence ) ; const twoPartTransitionWordsRegex = getRegexFromDoubleArray ( twoPartTransitionWords ) ; return sentence . match ( twoPartTransitionWordsRegex ) ; }

Matches the sentence against two part transition words.

@param {string} sentence The sentence to match against.
@param {Array} twoPartTransitionWords The array containing two-part transition words.
@returns {Array} The found transitional words.

Matches the sentence against two part transition words .


function( sentence, transitionWords ) {
	sentence = normalizeSingleQuotes( sentence );
	return transitionWords.filter( word => matchWordInSentence( word, sentence ) );
}

function ( sentence , transitionWords ) { sentence = normalizeSingleQuotes ( sentence ) ; return transitionWords . filter ( word => matchWordInSentence ( word , sentence ) ) ; }

Matches the sentence against transition words.

@param {string} sentence The sentence to match against.
@param {Array} transitionWords The array containing transition words.
@returns {Array} The found transitional words.

Matches the sentence against transition words .


function( sentences, transitionWords ) {
	const results = [];

	sentences.forEach( sentence => {
		const twoPartMatches = matchTwoPartTransitionWords( sentence, transitionWords.twoPartTransitionWords() );

		if ( twoPartMatches !== null ) {
			results.push( {
				sentence: sentence,
				transitionWords: twoPartMatches,
			} );

			return;
		}

		const transitionWordMatches = matchTransitionWords( sentence, transitionWords.transitionWords );

		if ( transitionWordMatches.length !== 0 ) {
			results.push( {
				sentence: sentence,
				transitionWords: transitionWordMatches,
			} );

			return;
		}
	} );

	return results;
}

function ( sentences , transitionWords ) { const results = [ ] ; sentences . forEach ( sentence => { const twoPartMatches = matchTwoPartTransitionWords ( sentence , transitionWords . twoPartTransitionWords ( ) ) ; if ( twoPartMatches !== null ) { results . push ( { sentence : sentence , transitionWords : twoPartMatches , } ) ; return ; } const transitionWordMatches = matchTransitionWords ( sentence , transitionWords . transitionWords ) ; if ( transitionWordMatches . length !== 0 ) { results . push ( { sentence : sentence , transitionWords : transitionWordMatches , } ) ; return ; } } ) ; return results ; }

Checks the passed sentences to see if they contain transition words.

@param {Array} sentences The sentences to match against.
@param {Object} transitionWords The object containing both transition words and two part transition words.
@returns {Array} Array of sentence objects containing the complete sentence and the transition words.

Checks the passed sentences to see if they contain transition words .


function getIndicesOfWords( text ) {
	const indices = [];
	const words = getWords( text );
	let startSearchFrom = 0;

	words.forEach( function( word ) {
		const currentIndex = text.indexOf( word, startSearchFrom );
		indices.push( currentIndex );
		startSearchFrom = currentIndex + word.length;
	} );

	return indices;
}

function getIndicesOfWords ( text ) { const indices = [ ] ; const words = getWords ( text ) ; let startSearchFrom = 0 ; words . forEach ( function ( word ) { const currentIndex = text . indexOf ( word , startSearchFrom ) ; indices . push ( currentIndex ) ; startSearchFrom = currentIndex + word . length ; } ) ; return indices ; }

Gets positions of the first character of a word in the input text.

@param {string} text The original text, for which the indices of word beginnings need to be determined.

@returns {Array} indices The array of indices in the text at which words start.

Gets positions of the first character of a word in the input text .


function getIndicesOfCharacter( text, characterToFind ) {
	const indices = [];

	if ( text.indexOf( characterToFind ) > -1 ) {
		for ( let i = 0; i < text.length; i++ ) {
			if ( text[ i ] === characterToFind ) {
				indices.push( i );
			}
		}
	}

	return indices;
}

function getIndicesOfCharacter ( text , characterToFind ) { const indices = [ ] ; if ( text . indexOf ( characterToFind ) > - 1 ) { for ( let i = 0 ; i < text . length ; i ++ ) { if ( text [ i ] === characterToFind ) { indices . push ( i ) ; } } } return indices ; }

Gets indices of a specific character in the input text.

@param {string} text The original text, for which the indices of specific characters have to be determined.
@param {string} characterToFind The character that needs to be found in the text.

@returns {Array} indices The array of indices in the text at which the characterToFind occurs.

Gets indices of a specific character in the input text .


function replaceCharactersByIndex( text, indices, substitute ) {
	const modifiedTextSplitByLetter = text.split( "" );

	indices.forEach( function( index ) {
		modifiedTextSplitByLetter.splice( index, 1, substitute );
	} );

	return modifiedTextSplitByLetter.join( "" );
}

function replaceCharactersByIndex ( text , indices , substitute ) { const modifiedTextSplitByLetter = text . split ( "" ) ; indices . forEach ( function ( index ) { modifiedTextSplitByLetter . splice ( index , 1 , substitute ) ; } ) ; return modifiedTextSplitByLetter . join ( "" ) ; }

Replaces characters on specified indices in the input text.

@param {string} text The original text, for which the characters have to be substituted.
@param {Array} indices The array of indices that have to be substituted.
@param {string} substitute The character that is used to substitute in the text.

@returns {string} result The string of the original text with the characters on specified indices are substituted with the substitute character.

Replaces characters on specified indices in the input text .


function( values ) {
	this._hasScore = false;
	this._identifier = "";
	this._hasMarks = false;
	this._marker = emptyMarker;
	this.score = 0;
	this.text = "";
	this.marks = [];

	if ( isUndefined( values ) ) {
		values = {};
	}

	if ( ! isUndefined( values.score ) ) {
		this.setScore( values.score );
	}

	if ( ! isUndefined( values.text ) ) {
		this.setText( values.text );
	}

	if ( ! isUndefined( values.marks ) ) {
		this.setMarks( values.marks );
	}
}

function ( values ) { this . _hasScore = false ; this . _identifier = "" ; this . _hasMarks = false ; this . _marker = emptyMarker ; this . score = 0 ; this . text = "" ; this . marks = [ ] ; if ( isUndefined ( values ) ) { values = { } ; } if ( ! isUndefined ( values . score ) ) { this . setScore ( values . score ) ; } if ( ! isUndefined ( values . text ) ) { this . setText ( values . text ) ; } if ( ! isUndefined ( values . marks ) ) { this . setMarks ( values . marks ) ; } }

Construct the AssessmentResult value object.

@param {Object} [values] The values for this assessment result.

@constructor

Construct the AssessmentResult value object .


function( sentence, locale ) {
	this._sentenceText = sentence || "";
	this._locale = locale || defaultAttributes.locale;
	this._isPassive = false;
}

function ( sentence , locale ) { this . _sentenceText = sentence || "" ; this . _locale = locale || defaultAttributes . locale ; this . _isPassive = false ; }

Construct the Sentence object and set the sentence text and locale.

@param {string} sentence The text of the sentence.
@param {string} locale The locale.
@constructor

Construct the Sentence object and set the sentence text and locale .


function( app ) {
	var elems = [ "content", "focusKeyword", "synonyms" ];
	for ( var i = 0; i < elems.length; i++ ) {
		document.getElementById( elems[ i ] ).addEventListener( "input", app.refresh.bind( app ) );
	}
	document.getElementById( "locale" ).addEventListener( "input", setLocale.bind( app ) );
	document.getElementById( "premium" ).addEventListener( "input", setPremium.bind( app ) );
}

function ( app ) { var elems = [ "content" , "focusKeyword" , "synonyms" ] ; for ( var i = 0 ; i < elems . length ; i ++ ) { document . getElementById ( elems [ i ] ) . addEventListener ( "input" , app . refresh . bind ( app ) ) ; } document . getElementById ( "locale" ) . addEventListener ( "input" , setLocale . bind ( app ) ) ; document . getElementById ( "premium" ) . addEventListener ( "input" , setPremium . bind ( app ) ) ; }

Binds the renewData function on the change of input elements.

@param {YoastSEO.App} app The YoastSEO.js app.

@returns {void}

Binds the renewData function on the change of input elements .


async function streamToString(readableStream) {
  return new Promise((resolve, reject) => {
    const chunks = [];
    readableStream.on("data", data => {
      chunks.push(data.toString());
    });
    readableStream.on("end", () => {
      resolve(chunks.join(""));
    });
    readableStream.on("error", reject);
  });
}

async function streamToString ( readableStream ) { return new Promise ( ( resolve , reject ) => { const chunks = [ ] ; readableStream . on ( "data" , data => { chunks . push ( data . toString ( ) ) ; } ) ; readableStream . on ( "end" , ( ) => { resolve ( chunks . join ( "" ) ) ; } ) ; readableStream . on ( "error" , reject ) ; } ) ; }

A helper method used to read a Node.js readable stream into string

A helper method used to read a Node . js readable stream into string


function authenticate() {
  const authPromtpts = [
    {
      type: "text",
      name: "username",
      message: "Username"
    },
    {
      type: "password",
      name: "password",
      message: "Password"
    }
  ];

  let session;

  // prompts returns a `Promise` that resolves with the users input
  return prompts(authPromtpts)
    .then(({ username, password }) => {
      session = new UserSession({
        username,
        password
      });

      // this will generate a token and use it to get into about a user
      return session.getUser();
    })
    .then(self => {
      return session;
    })
    .catch(error => {
      // in case of an `ArcGISRequestError` assume the `username` and `password`
      // are incorrect run the `authenticate` function again
      if (error.name === "ArcGISRequestError") {
        console.log(
          chalk.bold.red("Incorrect username and/or password please try again")
        );
        return authenticate();
      }

      // if this is a different error just log the error message and exit
      console.log(
        `${chalk.bold.red(error.name)} ${chalk.bold.red(error.message)}`
      );
    });
}

Prompt the user for a `username` and `password` return a `UserSession` This function will run again on any error so it will retry until it works

Prompt the user for a username and password return a UserSession This function will run again on any error so it will retry until it works


function searchForItems(session) {
  const searchPrompts = [
    {
      type: "text",
      name: "searchText",
      message: "Search Query"
    },
    {
      type: "list",
      name: "itemTypes",
      message: "Item Types"
    },
    {
      type: "list",
      name: "itemTags",
      message: "Tags"
    },
    {
      type: "number",
      name: "number",
      message: "How Many?"
    }
  ];

  // prompts returns a `Promise` that resolves with the users input
  return prompts(searchPrompts).then(
    //use ES2015 destructuring so we don't make any extra variables
    ({ searchText, itemTypes, itemTags, number }) => {
      const query = new SearchQueryBuilder()
        .match(session.username)
        .in("owner");

      // format the search query for item types
      const types = itemTypes.filter(type => type.length);

      // format the search query for item types
      if (types.length) {
        query.and().startGroup();
        types.forEach((type, index, types) => {
          query.match(type).in("type");
          if (index !== types.length - 1) {
            query.or();
          }
        });
        query.endGroup();
      }

      // format the search query for item tags
      const tags = itemTags.filter(tag => tag.length);

      if (tags.length) {
        query.and().startGroup();
        tags.forEach((tag, index, tags) => {
          query.match(tag).in("tags");
          if (index !== tags.length - 1) {
            query.or();
          }
        });
        query.endGroup();
      }

      // format the search query for the search text
      if (searchText.length) {
        query.and().match(searchText);
      }

      console.log(chalk.blue(`Searching ArcGIS Online: ${query.toParam()}`));

      return searchItems({
        authentication: session,
        q: query,
        num: number
      })
      .then(response => {
        return { response, session };
      })
      .catch(err => {
        console.warn(err);
      })
    }
  );
}

given a `UserSession` prompt the user for some search params and search for items

given a UserSession prompt the user for some search params and search for items


async function deleteItems(items, session) {
  // create our iterator which should return a `Promise`
  const asyncIterable = {
    [Symbol.asyncIterator]: () => ({
      // every time we ask for a new item
      next: function() {
        // remove the next item from the array
        const item = items.pop();

        // we are done if there is no item
        if (!item) {
          return Promise.resolve({ done: true });
        }

        // prompt to delete this item.
        return deleteItem(item, session);
      }
    })
  };

  // lets get our `next` function so we can itterate over it
  const { next } = asyncIterable[Symbol.asyncIterator]();

  for (
    let { done, deleted, item } = await next(); // start condition, call next and wait for the `Promise` to resolve, results are destructed.
    !done; // end condition,
    { done, deleted, item } = await next() // action on every loop, sets up the next round of checks
  ) {
    if (deleted) {
      console.log(chalk.green(`${item.title} deleted successfuly\n`));
    } else {
      console.log(chalk.gray(`${item.title} skipped\n`));
    }
  }

  // since this is inside an async function code execution is stopped at the loop
  // this will return an empty resolved `Promise` when the loop is done.
  return Promise.resolve();
}

this give a list of `items` and a `UserSession` this will ask us 1 at a time if we want to delte this item. This uses the new async iteration syntax with `Symbol.asyncIterator` to perform an async function in a loop

this give a list of items and a UserSession this will ask us 1 at a time if we want to delte this item . This uses the new async iteration syntax with Symbol . asyncIterator to perform an async function in a loop


function() {
        // remove the next item from the array
        const item = items.pop();

        // we are done if there is no item
        if (!item) {
          return Promise.resolve({ done: true });
        }

        // prompt to delete this item.
        return deleteItem(item, session);
      }

function
(
)
{
// remove the next item from the array
const
item
=
items
.
pop
(
)
;
// we are done if there is no item
if
(
!
item
)
{
return
Promise
.
resolve
(
{
done
:
true
}
)
;
}
// prompt to delete this item.
return
deleteItem
(
item
,
session
)
;
}


function (kb, x, displayables) {
      var t = kb.findTypeURIs(subject)
      for (var k = 0; k < displayables.length; k++) {
        if ($rdf.Util.mediaTypeClass(displayables[k]).uri in t) {
          return true
        }
      }
      return false
    }

function ( kb , x , displayables ) { var t = kb . findTypeURIs ( subject ) for ( var k = 0 ; k < displayables . length ; k ++ ) { if ( $rdf . Util . mediaTypeClass ( displayables [ k ] ) . uri in t ) { return true } } return false }

This data coul d come from a fetch OR from ldp comtaimner


function (newPaneOptions) {
    var kb = UI.store
    var newInstance = newPaneOptions.newInstance
    if (!newInstance) {
      let uri = newPaneOptions.newBase
      if (uri.endsWith('/')) {
        uri = uri.slice(0, -1)
        newPaneOptions.newBase = uri
      }
      newInstance = kb.sym(uri)
    }

    var contentType = mime.lookup(newInstance.uri)
    if (!contentType || !contentType.includes('html')) {
      newInstance = $rdf.sym(newInstance.uri + '.html')
    }
    newPaneOptions.newInstance = newInstance // Save for creation system

    console.log('New dokieli will make: ' + newInstance)

    var htmlContents = DOKIELI_TEMPLATE
    var filename = newInstance.uri.split('/').slice(-1)[0]
    filename = decodeURIComponent(filename.split('.')[0])
    const encodedTitle = filename.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
    htmlContents = htmlContents.replace('<title>', '<title>' + encodedTitle)
    htmlContents = htmlContents.replace('
', '
' + encodedTitle + '

')
    console.log('@@ New HTML for Dok:' + htmlContents)
    return new Promise(function (resolve, reject) {
      kb.fetcher.webOperation('PUT', newInstance.uri, { data: htmlContents, contentType: 'text/html' })
        .then(function () {
          console.log('new Dokieli document created at ' + newPaneOptions.newInstance)
          resolve(newPaneOptions)
        }).catch(function (err) {
          console.log('Error creating dokelili dok at ' +
            newPaneOptions.newInstance + ': ' + err)
        })
    })
  }

function
(
newPaneOptions
)
{
var
kb
=
UI
.
store
var
newInstance
=
newPaneOptions
.
newInstance
if
(
!
newInstance
)
{
let
uri
=
newPaneOptions
.
newBase
if
(
uri
.
endsWith
(
'/'
)
)
{
uri
=
uri
.
slice
(
0
,
1
)
newPaneOptions
.
newBase
=
uri
}
newInstance
=
kb
.
sym
(
uri
)
}
var
contentType
=
mime
.
lookup
(
newInstance
.
uri
)
if
(
!
contentType
||
!
contentType
.
includes
(
'html'
)
)
{
newInstance
=
$rdf
.
sym
(
newInstance
.
uri
+
'.html'
)
}
newPaneOptions
.
newInstance
=
newInstance
// Save for creation system
console
.
log
(
'New dokieli will make: '
+
newInstance
)
var
htmlContents
=
DOKIELI_TEMPLATE
var
filename
=
newInstance
.
uri
.
split
(
'/'
)
.
slice
(
1
)
[
0
]
filename
=
decodeURIComponent
(
filename
.
split
(
'.'
)
[
0
]
)
const
encodedTitle
=
filename
.
replace
(
/
&
/
g
,
'&'
)
.
replace
(
/
<
/
g
,
'<'
)
.
replace
(
/
>
/
g
,
'>'
)
htmlContents
=
htmlContents
.
replace
(
'<title>'
,
'<title>'
+
encodedTitle
)
htmlContents
=
htmlContents
.
replace
(
'
'
,
'
'
+
encodedTitle
+
'

'
)
console
.
log
(
'@@ New HTML for Dok:'
+
htmlContents
)
return
new
Promise
(
function
(
resolve
,
reject
)
{
kb
.
fetcher
.
webOperation
(
'PUT'
,
newInstance
.
uri
,
{
data
:
htmlContents
,
contentType
:
'text/html'
}
)
.
then
(
function
(
)
{
console
.
log
(
'new Dokieli document created at '
+
newPaneOptions
.
newInstance
)
resolve
(
newPaneOptions
)
}
)
.
catch
(
function
(
err
)
{
console
.
log
(
'Error creating dokelili dok at '
+
newPaneOptions
.
newInstance
+
': '
+
err
)
}
)
}
)
}

Create a new folder in a Solid system, with a dokieli editable document in it

Create a new folder in a Solid system with a dokieli editable document in it


function (subject) {
    var kb = UI.store
    var ns = UI.ns
    var t = kb.findTypeURIs(subject)
    if (t[ns.ldp('Resource').uri]) return 'Sharing' // @@ be more sophisticated?
    if (t[ns.ldp('Container').uri]) return 'Sharing' // @@ be more sophisticated?
    if (t[ns.ldp('BasicContainer').uri]) return 'Sharing' // @@ be more sophisticated?
    // check being allowed to see/change shgaring?
    return null // No under other circumstances
  }

Does the subject deserve an contact pane?


function (kb, x, contentTypes) {
      var cts = kb.fetcher.getHeader(x, 'content-type')
      if (cts) {
        for (var j = 0; j < cts.length; j++) {
          for (var k = 0; k < contentTypes.length; k++) {
            if (cts[j].indexOf(contentTypes[k]) >= 0) {
              return true
            }
          }
        }
      }
      return false
    }

function ( kb , x , contentTypes ) { var cts = kb . fetcher . getHeader ( x , 'content-type' ) if ( cts ) { for ( var j = 0 ; j < cts . length ; j ++ ) { for ( var k = 0 ; k < contentTypes . length ; k ++ ) { if ( cts [ j ] . indexOf ( contentTypes [ k ] ) >= 0 ) { return true } } } } return false }

See also the source pane, which has lower precedence.

See also the source pane which has lower precedence .


function () {
        var query = new $rdf.Query('IRC log entries')
        var v = []
        var vv = ['chan', 'msg', 'date', 'list', 'pred', 'creator', 'content']
        vv.map(function (x) {
          query.vars.push(v[x] = $rdf.variable(x))
        })
        query.pat.add(v['chan'], ns.foaf('chatEventList'), v['list']) // chatEventList
        query.pat.add(v['list'], v['pred'], v['msg']) //
        query.pat.add(v['msg'], ns.dc('date'), v['date'])
        query.pat.add(v['msg'], ns.dc('creator'), v['creator'])
        query.pat.add(v['msg'], ns.dc('description'), v['content'])
        return query
      }

function
(
)
{
var
query
=
new
$rdf
.
Query
(
'IRC log entries'
)
var
v
=
[
]
var
vv
=
[
'chan'
,
'msg'
,
'date'
,
'list'
,
'pred'
,
'creator'
,
'content'
]
vv
.
map
(
function
(
x
)
{
query
.
vars
.
push
(
v
[
x
]
=
$rdf
.
variable
(
x
)
)
}
)
query
.
pat
.
add
(
v
[
'chan'
]
,
ns
.
foaf
(
'chatEventList'
)
,
v
[
'list'
]
)
// chatEventList
query
.
pat
.
add
(
v
[
'list'
]
,
v
[
'pred'
]
,
v
[
'msg'
]
)
//
query
.
pat
.
add
(
v
[
'msg'
]
,
ns
.
dc
(
'date'
)
,
v
[
'date'
]
)
query
.
pat
.
add
(
v
[
'msg'
]
,
ns
.
dc
(
'creator'
)
,
v
[
'creator'
]
)
query
.
pat
.
add
(
v
[
'msg'
]
,
ns
.
dc
(
'description'
)
,
v
[
'content'
]
)
return
query
}


function Click (e) {
      var target = UI.utils.getTarget(e)
      if (UI.utils.getTerm(target).termType !== 'Literal') return
      this.literalModification(target)
        // this prevents the generated inputbox to be clicked again
      e.preventDefault()
      e.stopPropagation()
    }

Called when a selected cell is clicked again


function removefromview () {
        var trIterator
        for (trIterator = removedTr;
             trIterator.childNodes.length === 1;
             trIterator = trIterator.previousSibling);
        if (trIterator === removedTr) {
          var theNext = trIterator.nextSibling
          if (theNext.nextSibling && theNext.childNodes.length === 1) {
            var predicateTd = trIterator.firstChild
            predicateTd.setAttribute('rowspan', parseInt(predicateTd.getAttribute('rowspan')) - 1)
            theNext.insertBefore(trIterator.firstChild, theNext.firstChild)
          }
          removedTr.parentNode.removeChild(removedTr)
        } else { // !DisplayOptions["display:block on"].enabled){
          predicateTd = trIterator.firstChild
          predicateTd.setAttribute('rowspan', parseInt(predicateTd.getAttribute('rowspan')) - 1)
          removedTr.parentNode.removeChild(removedTr)
        }
      }


function WildCardButtons () {
      var menuDiv = myDocument.getElementById(outline.UserInput.menuID)
      var div = menuDiv.insertBefore(myDocument.createElement('div'), menuDiv.firstChild)
      var input1 = div.appendChild(myDocument.createElement('input'))
      var input2 = div.appendChild(myDocument.createElement('input'))
      input1.type = 'button'; input1.value = 'New...'
      input2.type = 'button'; input2.value = 'Know its URI'

      function highlightInput (e) { // same as the one in newMenu()
        var menu = myDocument.getElementById(outline.UserInput.menuID)
        if (menu.lastHighlight) menu.lastHighlight.className = ''
        menu.lastHighlight = UI.utils.ancestor(UI.utils.getTarget(e), 'INPUT')
        if (!menu.lastHighlight) return // mouseover <TABLE>
        menu.lastHighlight.className = 'activeItem'
      }
      div.addEventListener('mouseover', highlightInput, false)
      input1.addEventListener('click', this.createNew, false)
      input2.addEventListener('click', this.inputURI, false)
    }

function
WildCardButtons
(
)
{
var
menuDiv
=
myDocument
.
getElementById
(
outline
.
UserInput
.
menuID
)
var
div
=
menuDiv
.
insertBefore
(
myDocument
.
createElement
(
'div'
)
,
menuDiv
.
firstChild
)
var
input1
=
div
.
appendChild
(
myDocument
.
createElement
(
'input'
)
)
var
input2
=
div
.
appendChild
(
myDocument
.
createElement
(
'input'
)
)
input1
.
type
=
'button'
;
input1
.
value
=
'New...'
input2
.
type
=
'button'
;
input2
.
value
=
'Know its URI'
function
highlightInput
(
e
)
{
// same as the one in newMenu()
var
menu
=
myDocument
.
getElementById
(
outline
.
UserInput
.
menuID
)
if
(
menu
.
lastHighlight
)
menu
.
lastHighlight
.
className
=
''
menu
.
lastHighlight
=
UI
.
utils
.
ancestor
(
UI
.
utils
.
getTarget
(
e
)
,
'INPUT'
)
if
(
!
menu
.
lastHighlight
)
return
// mouseover <TABLE>
menu
.
lastHighlight
.
className
=
'activeItem'
}
div
.
addEventListener
(
'mouseover'
,
highlightInput
,
false
)
input1
.
addEventListener
(
'click'
,
this
.
createNew
,
false
)
input2
.
addEventListener
(
'click'
,
this
.
inputURI
,
false
)
}

Add the buttons which allow the suer to craete a new object Or reference an exiting one with a URI.

Add the buttons which allow the suer to craete a new object Or reference an exiting one with a URI .


function (subject) {
    var target = kb.any(subject, ns.meeting('target')) || subject
    var count = kb.each(target, predicate).length
    if (count > 0) {
      return UI.utils.label(predicate) + ' ' + count
    }
    return null
  }

function
(
subject
)
{
var
target
=
kb
.
any
(
subject
,
ns
.
meeting
(
'target'
)
)
||
subject
var
count
=
kb
.
each
(
target
,
predicate
)
.
length
if
(
count
>
0
)
{
return
UI
.
utils
.
label
(
predicate
)
+
' '
+
count
}
return
}

Does the subject deserve a link list pane?


function (subject) {
    var kb = UI.store
    var t = kb.findTypeURIs(subject)
    var QU = $rdf.Namespace('http://www.w3.org/2000/10/swap/pim/qif#')
    var WF = $rdf.Namespace('http://www.w3.org/2005/01/wf/flow#')
    if (t['http://www.w3.org/ns/pim/trip#Trip'] || // If in any subclass
      subject.uri === 'http://www.w3.org/ns/pim/trip#Trip' ||
      t['http://www.w3.org/2005/01/wf/flow#Task'] ||
      t['http://www.w3.org/2000/10/swap/pim/qif#Transaction'] ||
      // subject.uri == 'http://www.w3.org/2000/10/swap/pim/qif#Transaction' ||
      QU('Transaction') in kb.findSuperClassesNT(subject) ||
      kb.holds(subject, WF('attachment'))) return 'attachments'
    return null
  }

Does the subject deserve an attachments pane?  In this case we will render any thing which is in any subclass of certain classes, or also the certain classes themselves, as a triage tool for correlating many attachees with attachments. We also offer the pane for anything of any class which just has an attachment already.

Does the subject deserve an attachments pane? In this case we will render any thing which is in any subclass of certain classes or also the certain classes themselves as a triage tool for correlating many attachees with attachments . We also offer the pane for anything of any class which just has an attachment already .


function (kb, subject) {
      if (kb.updater.editable(subject.doc(), kb)) return subject.doc()
      var store = kb.any(subject.doc(), QU('annotationStore'))
      return store
    }

function ( kb , subject ) { if ( kb . updater . editable ( subject . doc ( ) , kb ) ) return subject . doc ( ) var store = kb . any ( subject . doc ( ) , QU ( 'annotationStore' ) ) return store }

Where can we write about this thing?  Returns term for document or null


function (c) {
      var sortBy = kb.sym({
        'http://www.w3.org/2005/01/wf/flow#Task': 'http://purl.org/dc/elements/1.1/created',
        'http://www.w3.org/ns/pim/trip#Trip': // @@ put this into the ontologies
        'http://www.w3.org/2002/12/cal/ical#dtstart',
        'http://www.w3.org/2000/10/swap/pim/qif#Transaction': 'http://www.w3.org/2000/10/swap/pim/qif#date',
        'http://www.w3.org/2000/10/swap/pim/qif#SupportingDocument': 'http://purl.org/dc/elements/1.1/date'}[subject.uri])

      if (!sortBy) {
        sortBy = kb.any(subject, UI.ns.ui('sortBy'))
      }
      return sortBy
    }

Find all members of the class which we know about and sort them by an appropriate property.   @@ Move to library

Find all members of the class which we know about and sort them by an appropriate property .


function (x, event, selected) {
      if (selected) {
        currentSubject = x
      } else {
        currentSubject = null
        if (currentMode === 1) deselectObject()
      } // If all are displayed, refresh would just annoy:
      if (currentMode !== 0) showFiltered(currentMode) // Refresh the objects
    }

When you click on a subject, filter the objects connected to the subject in Mode 1

When you click on a subject filter the objects connected to the subject in Mode 1


function () {
        var id = mb.getUser(Post.creator).id
        var xupdateStatus = doc.getElementById('xupdateStatus')
        var xinReplyToContainer = doc.getElementById('xinReplyToContainer')
        var xupdateSubmit = doc.getElementById('xupdateSubmit')
        xupdateStatus.value = '@' + id + ' '
        xupdateStatus.focus()
        xinReplyToContainer.value = post.uri
        xupdateSubmit.value = 'Reply'
      }

function
(
)
{
var
id
=
mb
.
getUser
(
Post
.
creator
)
.
id
var
xupdateStatus
=
doc
.
getElementById
(
'xupdateStatus'
)
var
xinReplyToContainer
=
doc
.
getElementById
(
'xinReplyToContainer'
)
var
xupdateSubmit
=
doc
.
getElementById
(
'xupdateSubmit'
)
xupdateStatus
.
value
=
'@'
+
id
+
' '
xupdateStatus
.
focus
(
)
xinReplyToContainer
.
value
=
post
.
uri
xupdateSubmit
.
value
=
'Reply'
}

END LINK META DATA add the reply to and delete buttons to the interface


function (a, success) {
            if (success) {
              that.notify('Post deleted.')
              // update the ui to reflect model changes.
              var deleteThisNode = evt.target.parentNode
              deleteThisNode.parentNode.removeChild(deleteThisNode)
              kb.removeMany(deleteMe)
            } else {
              that.notify('Oops, there was a problem, please try again')
              evt.target.disabled = true
            }
          }


function (a, success) {
            if (success) {
              var deleteContainer = kb.statementsMatching(
                undefined, SIOC('container_of'), kb.sym(doc.getElementById(
                  'post_' + evt.target.parentNode.id).getAttribute('content')))
              sparqlUpdater.batch_delete_statement(deleteContainer, mbconfirmDeletePost)
            } else {
              that.notify('Oops, there was a problem, please try again')
              evt.target.disabled = false
            }
          }


function displayFormsForRelation (pred, allowCreation) {
          var sts = kb.statementsMatching(subject, pred)
          const outliner = panes.getOutliner(dom)
          if (sts.length) {
            for (var i = 0; i < sts.length; i++) {
              outliner.appendPropertyTRs(box, [ sts[i] ])
              var form = sts[i].object
              var cell = dom.createElement('td')
              box.lastChild.appendChild(cell)
              if (allowCreation) {
                cell.appendChild(UI.widgets.newButton(
                  dom, kb, null, null, subject, form, store, function (ok, body) {
                    if (ok) {
                      // dom.outlineManager.GotoSubject(newThing@@, true, undefined, true, undefined);
                      // rerender(box);   // Deleted forms at the moment
                    } else complain('Sorry, failed to save your change:\n' + body)
                  }))
              }
              var formdef = kb.statementsMatching(form, ns.rdf('type'))
              if (!formdef.length) formdef = kb.statementsMatching(form)
              if (!formdef.length) complain('No data about form')
              else {
                UI.widgets.editFormButton(dom, box,
                form, formdef[0].why, complainIfBad)
              }
            }
            box.appendChild(dom.createElement('hr'))
          } else {
            mention('There are currently no known forms to make a ' +
              label + '.')
          }
        }

For each creation form, allow one to create a new object with it, and also to edit the form.

For each creation form allow one to create a new object with it and also to edit the form .


function (subject) {
    var kb = UI.store
    var n = kb.each(
      undefined, ns.rdf('type'), subject).length
    if (n > 0) return 'List (' + n + ')' // Show how many in hover text
    return null // Suppress pane otherwise
  }

function
(
subject
)
{
var
kb
=
UI
.
store
var
n
=
kb
.
each
(
undefined
,
ns
.
rdf
(
'type'
)
,
subject
)
.
length
if
(
n
>
0
)
return
'List ('
+
n
+
')'
// Show how many in hover text
return
// Suppress pane otherwise
}


function viewAndSaveQuery (outline, selection) {
  var qs = outline.qs
  UI.log.info('outline.doucment is now ' + outline.document.location)
  var q = saveQuery(selection, qs)
  /*
  if (tabulator.isExtension) {
    // tabulator.drawInBestView(q)
  } else
  */

  for (let i = 0; i < qs.listeners.length; i++) {
    qs.listeners[i].getActiveView().view.drawQuery(q)
    qs.listeners[i].updateQueryControls(qs.listeners[i].getActiveView())
  }
}

When the user asks for all list of all matching parts of the data


function (store, subject) {
      kb.fetcher.nowOrWhenFetched(store.uri, subject, function (ok, body) {
        if (!ok) return complain('Cannot load store ' + store.uri + ': ' + body)

        //              Render the forms

        var forms = UI.widgets.formsFor(subject)

        // complain('Form for editing this form:');
        for (var i = 0; i < forms.length; i++) {
          var form = forms[i]
          var heading = dom.createElement('h4')
          box.appendChild(heading)
          if (form.uri) {
            var formStore = $rdf.Util.uri.document(form)
            if (formStore.uri !== form.uri) { // The form is a hash-type URI
              var e = box.appendChild(UI.widgets.editFormButton(
                dom, box, form, formStore, complainIfBad))
              e.setAttribute('style', 'float: right;')
            }
          }
          var anchor = dom.createElement('a')
          anchor.setAttribute('href', form.uri)
          heading.appendChild(anchor)
          anchor.textContent = UI.utils.label(form, true)

          /*  Keep tis as a reminder to let a New one have its URI given by user
          mention("Where will this information be stored?")
          var ele = dom.createElement('input');
          box.appendChild(ele);
          ele.setAttribute('type', 'text');
          ele.setAttribute('size', '72');
          ele.setAttribute('maxlength', '1024');
          ele.setAttribute('style', 'font-size: 80%; color:#222;');
          ele.value = store.uri
          */

          UI.widgets.appendForm(dom, box, {}, subject, form, store, complainIfBad)
        }
      }) // end: when store loded
    }


function (kb, subject, path) {
      if (path.length === 0) return [ subject ]
      var oo = kb.each(subject, path[0])
      var res = []
      for (var i = 0; i < oo.length; i++) {
        res = res.concat(followeach(kb, oo[i], path.slice(1)))
      }
      return res
    }

function ( kb , subject , path ) { if ( path . length === 0 ) return [ subject ] var oo = kb . each ( subject , path [ 0 ] ) var res = [ ] for ( var i = 0 ; i < oo . length ; i ++ ) { res = res . concat ( followeach ( kb , oo [ i ] , path . slice ( 1 ) ) ) } return res }


function (subject, dom) {
    var outliner = panes.getOutliner(dom)
    var kb = UI.store
    var arg = UI.ns.arg

    subject = kb.canon(subject)
    // var types = kb.findTypeURIs(subject)

    var div = dom.createElement('div')
    div.setAttribute('class', 'argumentPane')

    // var title = kb.any(subject, UI.ns.dc('title'))

    var comment = kb.any(subject, UI.ns.rdfs('comment'))
    if (comment) {
      var para = dom.createElement('p')
      para.setAttribute('style', 'margin-left: 2em; font-style: italic;')
      div.appendChild(para)
      para.textContent = comment.value
    }

    div.appendChild(dom.createElement('hr'))

    var plist = kb.statementsMatching(subject, arg('support'))
    outliner.appendPropertyTRs(div, plist, false)

    div.appendChild(dom.createElement('hr'))

    plist = kb.statementsMatching(subject, arg('opposition'))
    outliner.appendPropertyTRs(div, plist, false)

    div.appendChild(dom.createElement('hr'))
    return div
  }

View the data in a file in user-friendly way

View the data in a file in user - friendly way


function propertyTree (subject) {
      // print('Proprty tree for '+subject)
      var rep = myDocument.createElement('table')
      var lastPred = null
      var sts = subjects[sz.toStr(subject)] // relevant statements
      if (!sts) { // No statements in tree
        rep.appendChild(myDocument.createTextNode('...')) // just empty bnode as object
        return rep
      }
      sts.sort()
      var same = 0
      var predicateTD // The cell which holds the predicate
      for (var i = 0; i < sts.length; i++) {
        var st = sts[i]
        var tr = myDocument.createElement('tr')
        if (st.predicate.uri !== lastPred) {
          if (lastPred && same > 1) predicateTD.setAttribute('rowspan', '' + same)
          predicateTD = myDocument.createElement('td')
          predicateTD.setAttribute('class', 'pred')
          var anchor = myDocument.createElement('a')
          anchor.setAttribute('href', st.predicate.uri)
          anchor.addEventListener('click', UI.widgets.openHrefInOutlineMode, true)
          anchor.appendChild(myDocument.createTextNode(UI.utils.predicateLabelForXML(st.predicate)))
          predicateTD.appendChild(anchor)
          tr.appendChild(predicateTD)
          lastPred = st.predicate.uri
          same = 0
        }
        same++
        var objectTD = myDocument.createElement('td')
        objectTD.appendChild(objectTree(st.object))
        tr.appendChild(objectTD)
        rep.appendChild(tr)
      }
      if (lastPred && same > 1) predicateTD.setAttribute('rowspan', '' + same)
      return rep
    }

function
propertyTree
(
subject
)
{
// print('Proprty tree for '+subject)
var
rep
=
myDocument
.
createElement
(
'table'
)
var
lastPred
=
var
sts
=
subjects
[
sz
.
toStr
(
subject
)
]
// relevant statements
if
(
!
sts
)
{
// No statements in tree
rep
.
appendChild
(
myDocument
.
createTextNode
(
'...'
)
)
// just empty bnode as object
return
rep
}
sts
.
sort
(
)
var
same
=
0
var
predicateTD
// The cell which holds the predicate
for
(
var
i
=
0
;
i
<
sts
.
length
;
i
++
)
{
var
st
=
sts
[
i
]
var
tr
=
myDocument
.
createElement
(
'tr'
)
if
(
st
.
predicate
.
uri
!==
lastPred
)
{
if
(
lastPred
&&
same
>
1
)
predicateTD
.
setAttribute
(
'rowspan'
,
''
+
same
)
predicateTD
=
myDocument
.
createElement
(
'td'
)
predicateTD
.
setAttribute
(
'class'
,
'pred'
)
var
anchor
=
myDocument
.
createElement
(
'a'
)
anchor
.
setAttribute
(
'href'
,
st
.
predicate
.
uri
)
anchor
.
addEventListener
(
'click'
,
UI
.
widgets
.
openHrefInOutlineMode
,
true
)
anchor
.
appendChild
(
myDocument
.
createTextNode
(
UI
.
utils
.
predicateLabelForXML
(
st
.
predicate
)
)
)
predicateTD
.
appendChild
(
anchor
)
tr
.
appendChild
(
predicateTD
)
lastPred
=
st
.
predicate
.
uri
same
=
0
}
same
++
var
objectTD
=
myDocument
.
createElement
(
'td'
)
objectTD
.
appendChild
(
objectTree
(
st
.
object
)
)
tr
.
appendChild
(
objectTD
)
rep
.
appendChild
(
tr
)
}
if
(
lastPred
&&
same
>
1
)
predicateTD
.
setAttribute
(
'rowspan'
,
''
+
same
)
return
rep
}

The property tree for a single subject or anonymous node


function objectTree (obj) {
      var res
      switch (obj.termType) {
        case 'NamedNode':
          let anchor = myDocument.createElement('a')
          anchor.setAttribute('href', obj.uri)
          anchor.addEventListener('click', UI.widgets.openHrefInOutlineMode, true)
          anchor.appendChild(myDocument.createTextNode(UI.utils.label(obj)))
          return anchor

        case 'Literal':

          if (!obj.datatype || !obj.datatype.uri) {
            res = myDocument.createElement('div')
            res.setAttribute('style', 'white-space: pre-wrap;')
            res.textContent = obj.value
            return res
          } else if (obj.datatype.uri === 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral') {
            res = myDocument.createElement('div')
            res.setAttribute('class', 'embeddedXHTML')
            res.innerHTML = obj.value // Try that  @@@ beware embedded dangerous code
            return res
          }
          return myDocument.createTextNode(obj.value) // placeholder - could be smarter,

        case 'BlankNode':
          if (obj.toNT() in doneBnodes) { // Break infinite recursion
            referencedBnodes[(obj.toNT())] = true
            let anchor = myDocument.createElement('a')
            anchor.setAttribute('href', '#' + obj.toNT().slice(2))
            anchor.setAttribute('class', 'bnodeRef')
            anchor.textContent = '*' + obj.toNT().slice(3)
            return anchor
          }
          doneBnodes[obj.toNT()] = true // Flag to prevent infinite recursion in propertyTree
          var newTable = propertyTree(obj)
          doneBnodes[obj.toNT()] = newTable // Track where we mentioned it first
          if (UI.utils.ancestor(newTable, 'TABLE') && UI.utils.ancestor(newTable, 'TABLE').style.backgroundColor === 'white') {
            newTable.style.backgroundColor = '#eee'
          } else {
            newTable.style.backgroundColor = 'white'
          }
          return newTable

        case 'Collection':
          res = myDocument.createElement('table')
          res.setAttribute('class', 'collectionAsTables')
          for (var i = 0; i < obj.elements.length; i++) {
            var tr = myDocument.createElement('tr')
            res.appendChild(tr)
            tr.appendChild(objectTree(obj.elements[i]))
          }
          return res
        case 'Graph':
          res = panes.dataContents.statementsAsTables(obj.statements, myDocument)
          res.setAttribute('class', 'nestedFormula')
          return res
        case 'Variable':
          res = myDocument.createTextNode('?' + obj.uri)
          return res
      }
      throw new Error('Unhandled node type: ' + obj.termType)
    }

Convert a set of statements into a nested tree of tables


function (subject, myDocument) {
    function alternativeRendering () {
      var sz = UI.rdf.Serializer(UI.store)
      var res = sz.rootSubjects(sts)
      var roots = res.roots
      var p = {}
      p.render = function (s2) {
        var div = myDocument.createElement('div')
        div.setAttribute('class', 'withinDocumentPane')
        var plist = kb.statementsMatching(s2, undefined, undefined, subject)
        outliner.appendPropertyTRs(div, plist, false, function (pred, inverse) { return true })
        return div
      }
      for (var i = 0; i < roots.length; i++) {
        var tr = myDocument.createElement('TR')
        var root = roots[i]
        tr.style.verticalAlign = 'top'
        var td = outliner.outlineObjectTD(root, undefined, tr)
        tr.appendChild(td)
        div.appendChild(tr)
        outliner.outlineExpand(td, root, {'pane': p})
      }
    }

    function mainRendering () {
      var initialRoots = [] // Ordering: start with stuff about this doc
      if (kb.holds(subject, undefined, undefined, subject)) initialRoots.push(subject)
      // Then about the primary topic of the document if any
      var ps = kb.any(subject, UI.ns.foaf('primaryTopic'), undefined, subject)
      if (ps) initialRoots.push(ps)
      div.appendChild(panes.dataContents.statementsAsTables(sts, myDocument, initialRoots))
    }

    var outliner = panes.getOutliner(myDocument)
    var kb = UI.store
    var div = myDocument.createElement('div')
    div.setAttribute('class', 'dataContentPane')
    // Because of smushing etc, this will not be a copy of the original source
    // We could instead either fetch and re-parse the source,
    // or we could keep all the pre-smushed triples.
    var sts = kb.statementsMatching(undefined, undefined, undefined, subject) // @@ slow with current store!

    if ($rdf.keepThisCodeForLaterButDisableFerossConstantConditionPolice) {
      alternativeRendering()
    } else {
      mainRendering()
    }
    return div
  }

statementsAsTables View the data in a file in user-friendly way

statementsAsTables View the data in a file in user - friendly way


function (subject) {
    var kb = UI.store
    var ns = UI.ns
    var t = kb.findTypeURIs(subject)
    if (t[ns.ldp('Container').uri] || t[ns.ldp('BasicContainer').uri]) {
      var contents = kb.each(subject, ns.ldp('contains'))
      var count = 0
      contents.map(function (file) {
        if (UI.widgets.isImage(file)) count++
      })
      return count > 0 ? 'Slideshow' : null
    }
    return null
  }

function ( subject ) { var kb = UI . store var ns = UI . ns var t = kb . findTypeURIs ( subject ) if ( t [ ns . ldp ( 'Container' ) . uri ] || t [ ns . ldp ( 'BasicContainer' ) . uri ] ) { var contents = kb . each ( subject , ns . ldp ( 'contains' ) ) var count = 0 contents . map ( function ( file ) { if ( UI . widgets . isImage ( file ) ) count ++ } ) return count > 0 ? 'Slideshow' : null } return null }

Does the subject deserve an slideshow pane?


function removeAndRefresh (d) {
    var table = d.parentNode
    var par = table.parentNode
    var placeholder = dom.createElement('table')
    placeholder.setAttribute('style', 'width: 100%;')
    par.replaceChild(placeholder, table)
    table.removeChild(d)
    par.replaceChild(table, placeholder) // Attempt to
  }

function
removeAndRefresh
(
d
)
{
var
table
=
d
.
parentNode
var
par
=
table
.
parentNode
var
placeholder
=
dom
.
createElement
(
'table'
)
placeholder
.
setAttribute
(
'style'
,
'width: 100%;'
)
par
.
replaceChild
(
placeholder
,
table
)
table
.
removeChild
(
d
)
par
.
replaceChild
(
table
,
placeholder
)
// Attempt to
}

Remove a node from the DOM so that Firefox refreshes the screen OK Just deleting it cause whitespace to accumulate.

Remove a node from the DOM so that Firefox refreshes the screen OK Just deleting it cause whitespace to accumulate .


function optOnIconMouseDownListener (e) { // outlineIcons.src.icon_opton  needed?
    var target = thisOutline.targetOf(e)
    var p = target.parentNode
    termWidget.replaceIcon(p.parentNode,
      outlineIcons.termWidgets.optOn,
      outlineIcons.termWidgets.optOff, optOffIconMouseDownListener)
    p.parentNode.parentNode.removeAttribute('optional')
  }

function
optOnIconMouseDownListener
(
e
)
{
// outlineIcons.src.icon_opton  needed?
var
target
=
thisOutline
.
targetOf
(
e
)
var
p
=
target
.
parentNode
termWidget
.
replaceIcon
(
p
.
parentNode
,
outlineIcons
.
termWidgets
.
optOn
,
outlineIcons
.
termWidgets
.
optOff
,
optOffIconMouseDownListener
)
p
.
parentNode
.
parentNode
.
removeAttribute
(
'optional'
)
}

These woulkd be simpler using closer variables below


function handleFileSelect(evt) {
        evt.stopPropagation();
        evt.preventDefault();

        // Get the FileList object that contains the list of files that were dropped
        var files = evt.dataTransfer.files;

        // this UI is only built for a single file so just dump the first one
        dumpFile(files[0]);
    }

this function gets called once the user drops the file onto the div


function sha1(buffer, offset, length) {
  offset = offset || 0;
  length = length || buffer.length;
  var subArray = dicomParser.sharedCopy(buffer, offset, length);
  var rusha = new Rusha();
  return rusha.digest(subArray);
}

function sha1 ( buffer , offset , length ) { offset = offset || 0 ; length = length || buffer . length ; var subArray = dicomParser . sharedCopy ( buffer , offset , length ) ; var rusha = new Rusha ( ) ; return rusha . digest ( subArray ) ; }

Function to calculate the SHA1 Hash for a buffer with a given offset and length


function getMarkdownToTextConverter() {
	const remark = require('remark')
	const strip = require('strip-markdown')

	const converter = remark().use(strip)

	return (md) => String(converter.processSync(md))
}

function getMarkdownToTextConverter ( ) { const remark = require ( 'remark' ) const strip = require ( 'strip-markdown' ) const converter = remark ( ) . use ( strip ) return ( md ) => String ( converter . processSync ( md ) ) }

Temporary solution to convert MD to plain text to show in hover
Todo@Pine: Redo this after adding Markdown support


function(password, count) {
    // Errors
    if(!password) throw new Error('Missing argument !');
    if(!count || count <= 0) throw new Error('Please provide a count number above 0');
    // Processing
    let data = password;
    console.time('sha3^n generation time');
    for (let i = 0; i < count; ++i) {
        data = CryptoJS.SHA3(data, {
            outputLength: 256
        });
    }
    console.timeEnd('sha3^n generation time');
    // Result
    return {
        'priv': CryptoJS.enc.Hex.stringify(data)
    };
}

function
(
password
,
count
)
{
// Errors
if
(
!
password
)
throw
new
Error
(
'Missing argument !'
)
;
if
(
!
count
||
count
<=
0
)
throw
new
Error
(
'Please provide a count number above 0'
)
;
// Processing
let
data
=
password
;
console
.
time
(
'sha3^n generation time'
)
;
for
(
let
i
=
0
;
i
<
count
;
++
i
)
{
data
=
CryptoJS
.
SHA3
(
data
,
{
outputLength
:
256
}
)
;
}
console
.
timeEnd
(
'sha3^n generation time'
)
;
// Result
return
{
'priv'
:
CryptoJS
.
enc
.
Hex
.
stringify
(
data
)
}
;
}

Derive a private key from a password using count iterations of SHA3-256

@param {string} password - A wallet password
@param {number} count - A number of iterations above 0

@return {object} - The derived private key

Derive a private key from a password using count iterations of SHA3 - 256


function(privateKey, password) {
    // Errors
    if (!privateKey || !password) throw new Error('Missing argument !');
    //if (!Helpers.isPrivateKeyValid(privateKey)) throw new Error('Private key is not valid !');
    // Processing
    let pass = derivePassSha(password, 20);
    let r = encrypt(privateKey, convert.hexToUint8(pass.priv));
    // Result
    return {
        ciphertext: CryptoJS.enc.Hex.stringify(r.ciphertext),
        iv: convert.uint8ToHex(r.iv)
    };
}

Encode a private key using a password

@param {string} privateKey - An hex private key
@param {string} password - A password

@return {object} - The encoded data


function(senderPriv, recipientPub, msg) {
    // Errors
    if (!senderPriv || !recipientPub || !msg) throw new Error('Missing argument !');
    //if (!Helpers.isPrivateKeyValid(senderPriv)) throw new Error('Private key is not valid !');
    //if (!Helpers.isPublicKeyValid(recipientPub)) throw new Error('Public key is not valid !');
    // Processing
    let iv = nacl.randomBytes(16)
    //console.log("IV:", convert.uint8ToHex(iv));
    let salt = nacl.randomBytes(32)
    let encoded = _encode(senderPriv, recipientPub, msg, iv, salt);
    // Result
    return encoded;
}

Encode a message

@param {string} senderPriv - A sender private key
@param {string} recipientPub - A recipient public key
@param {string} msg - A text message

@return {string} - The encoded message


function(recipientPrivate, senderPublic, _payload) {
    // Errorsp
    if(!recipientPrivate || !senderPublic || !_payload) throw new Error('Missing argument !');
    // Processing
    let binPayload = convert.hexToUint8(_payload);
    let salt = new Uint8Array(binPayload.buffer, 0, 32);
    let iv = new Uint8Array(binPayload.buffer, 32, 16);
    let payload = new Uint8Array(binPayload.buffer, 48);

    let keyPair = createKeyPairFromPrivateKeyString(recipientPrivate);
    let pk = convert.hexToUint8(senderPublic);
    let encKey = deriveSharedKey(keyPair, pk, salt);
    let encIv = {
        iv: ua2words(iv, 16)
    };
    let encrypted = {
        'ciphertext': ua2words(payload, payload.length)
    };
    let plain = CryptoJS.AES.decrypt(encrypted, encKey, encIv);
    // Result
    let hexplain = CryptoJS.enc.Hex.stringify(plain);
    return hexplain;
}

function
(
recipientPrivate
,
senderPublic
,
_payload
)
{
// Errorsp
if
(
!
recipientPrivate
||
!
senderPublic
||
!
_payload
)
throw
new
Error
(
'Missing argument !'
)
;
// Processing
let
binPayload
=
convert
.
hexToUint8
(
_payload
)
;
let
salt
=
new
Uint8Array
(
binPayload
.
buffer
,
0
,
32
)
;
let
iv
=
new
Uint8Array
(
binPayload
.
buffer
,
32
,
16
)
;
let
payload
=
new
Uint8Array
(
binPayload
.
buffer
,
48
)
;
let
keyPair
=
createKeyPairFromPrivateKeyString
(
recipientPrivate
)
;
let
pk
=
convert
.
hexToUint8
(
senderPublic
)
;
let
encKey
=
deriveSharedKey
(
keyPair
,
pk
,
salt
)
;
let
encIv
=
{
iv
:
ua2words
(
iv
,
16
)
}
;
let
encrypted
=
{
'ciphertext'
:
ua2words
(
payload
,
payload
.
length
)
}
;
let
plain
=
CryptoJS
.
AES
.
decrypt
(
encrypted
,
encKey
,
encIv
)
;
// Result
let
hexplain
=
CryptoJS
.
enc
.
Hex
.
stringify
(
plain
)
;
return
hexplain
;
}

Decode an encrypted message payload

@param {string} recipientPrivate - A recipient private key
@param {string} senderPublic - A sender public key
@param {string} _payload - An encrypted message payload

@return {string} - The decoded payload as hex


function(ua, uaLength) {
    let temp = [];
    for (let i = 0; i < uaLength; i += 4) {
        let x = ua[i] * 0x1000000 + (ua[i + 1] || 0) * 0x10000 + (ua[i + 2] || 0) * 0x100 + (ua[i + 3] || 0);
        temp.push((x > 0x7fffffff) ? x - 0x100000000 : x);
    }
    return CryptoJS.lib.WordArray.create(temp, uaLength);
}

function ( ua , uaLength ) { let temp = [ ] ; for ( let i = 0 ; i < uaLength ; i += 4 ) { let x = ua [ i ] * 0x1000000 + ( ua [ i + 1 ] || 0 ) * 0x10000 + ( ua [ i + 2 ] || 0 ) * 0x100 + ( ua [ i + 3 ] || 0 ) ; temp . push ( ( x > 0x7fffffff ) ? x - 0x100000000 : x ) ; } return CryptoJS . lib . WordArray . create ( temp , uaLength ) ; }

Convert an Uint8Array to WordArray

@param {Uint8Array} ua - An Uint8Array
@param {number} uaLength - The Uint8Array length

@return {WordArray}


function(destUa, cryptowords) {
    for (let i = 0; i < destUa.length; i += 4) {
        let v = cryptowords.words[i / 4];
        if (v < 0) v += 0x100000000;
        destUa[i] = (v >>> 24);
        destUa[i + 1] = (v >>> 16) & 0xff;
        destUa[i + 2] = (v >>> 8) & 0xff;
        destUa[i + 3] = v & 0xff;
    }
    return destUa;
}

function ( destUa , cryptowords ) { for ( let i = 0 ; i < destUa . length ; i += 4 ) { let v = cryptowords . words [ i / 4 ] ; if ( v < 0 ) v += 0x100000000 ; destUa [ i ] = ( v >>> 24 ) ; destUa [ i + 1 ] = ( v >>> 16 ) & 0xff ; destUa [ i + 2 ] = ( v >>> 8 ) & 0xff ; destUa [ i + 3 ] = v & 0xff ; } return destUa ; }

Convert a wordArray to Uint8Array

@param {Uint8Array} destUa - A destination Uint8Array
@param {WordArray} cryptowords - A wordArray

@return {Uint8Array}


function(p) {
        var dx = p.x - this.x,
            dy = p.y - this.y;
        return dx * dx + dy * dy;
    }

function ( p ) { var dx = p . x - this . x , dy = p . y - this . y ; return dx * dx + dy * dy ; }

Calculate the distance from this point to another point,
without the square root step. Useful if you're comparing
relative distances.
@param {Point} p the other point
@return {Number} distance

Calculate the distance from this point to another point without the square root step . Useful if you re comparing relative distances .


function(e) {
		var self = this;

		// necessary for mobile webkit devices (manual focus triggering
		// is ignored unless invoked within a click event)
    // also necessary to reopen a dropdown that has been closed by
    // closeAfterSelect
		if (!self.isFocused || !self.isOpen) {
			self.focus();
			e.preventDefault();
		}
	}

Triggered when the main control element
has a click event.

@param {object} e
@return {boolean}

Triggered when the main control element has a click event .


function(data) {
		var key = hash_key(data[this.settings.valueField]);
		if (typeof key === 'undefined' || key === null || this.options.hasOwnProperty(key)) return false;
		data.$order = data.$order || ++this.order;
		this.options[key] = data;
		return key;
	}

function ( data ) { var key = hash_key ( data [ this . settings . valueField ] ) ; if ( typeof key === 'undefined' || key === null || this . options . hasOwnProperty ( key ) ) return false ; data . $order = data . $order || ++ this . order ; this . options [ key ] = data ; return key ; }

Registers an option to the pool of options.

@param {object} data
@return {boolean|string}

Registers an option to the pool of options .


function() {
		var self = this;

		self.loadedSearches = {};
		self.userOptions = {};
		self.renderCache = {};
		var options = self.options;
		$.each(self.options, function(key, value) {
			if(self.items.indexOf(key) == -1) {
				delete options[key];
			}
		});
		self.options = self.sifter.items = options;
		self.lastQuery = null;
		self.trigger('option_clear');
	}

function ( ) { var self = this ; self . loadedSearches = { } ; self . userOptions = { } ; self . renderCache = { } ; var options = self . options ; $ . each ( self . options , function ( key , value ) { if ( self . items . indexOf ( key ) == - 1 ) { delete options [ key ] ; } } ) ; self . options = self . sifter . items = options ; self . lastQuery = null ; self . trigger ( 'option_clear' ) ; }


function(values, silent) {
		this.buffer = document.createDocumentFragment();

		var childNodes = this.$control[0].childNodes;
		for (var i = 0; i < childNodes.length; i++) {
			this.buffer.appendChild(childNodes[i]);
		}

		var items = $.isArray(values) ? values : [values];
		for (var i = 0, n = items.length; i < n; i++) {
			this.isPending = (i < n - 1);
			this.addItem(items[i], silent);
		}

		var control = this.$control[0];
		control.insertBefore(this.buffer, control.firstChild);

		this.buffer = null;
	}

function ( values , silent ) { this . buffer = document . createDocumentFragment ( ) ; var childNodes = this . $control [ 0 ] . childNodes ; for ( var i = 0 ; i < childNodes . length ; i ++ ) { this . buffer . appendChild ( childNodes [ i ] ) ; } var items = $ . isArray ( values ) ? values : [ values ] ; for ( var i = 0 , n = items . length ; i < n ; i ++ ) { this . isPending = ( i < n - 1 ) ; this . addItem ( items [ i ] , silent ) ; } var control = this . $control [ 0 ] ; control . insertBefore ( this . buffer , control . firstChild ) ; this . buffer = null ; }

"Selects" multiple items at once. Adds them to the list
at the current caret position.

@param {string} value
@param {boolean} silent

Selects multiple items at once . Adds them to the list at the current caret position .


function(value, silent) {
		var self = this;
		var $item, i, idx;

		$item = (value instanceof $) ? value : self.getItem(value);
		value = hash_key($item.attr('data-value'));
		i = self.items.indexOf(value);

		if (i !== -1) {
			$item.remove();
			if ($item.hasClass('active')) {
				idx = self.$activeItems.indexOf($item[0]);
				self.$activeItems.splice(idx, 1);
			}

			self.items.splice(i, 1);
			self.lastQuery = null;
			if (!self.settings.persist && self.userOptions.hasOwnProperty(value)) {
				self.removeOption(value, silent);
			}

			if (i < self.caretPos) {
				self.setCaret(self.caretPos - 1);
			}

			self.refreshState();
			self.updatePlaceholder();
			self.updateOriginalInput({silent: silent});
			self.positionDropdown();
			self.trigger('item_remove', value, $item);
		}
	}

function ( value , silent ) { var self = this ; var $item , i , idx ; $item = ( value instanceof $ ) ? value : self . getItem ( value ) ; value = hash_key ( $item . attr ( 'data-value' ) ) ; i = self . items . indexOf ( value ) ; if ( i !== - 1 ) { $item . remove ( ) ; if ( $item . hasClass ( 'active' ) ) { idx = self . $activeItems . indexOf ( $item [ 0 ] ) ; self . $activeItems . splice ( idx , 1 ) ; } self . items . splice ( i , 1 ) ; self . lastQuery = null ; if ( ! self . settings . persist && self . userOptions . hasOwnProperty ( value ) ) { self . removeOption ( value , silent ) ; } if ( i < self . caretPos ) { self . setCaret ( self . caretPos - 1 ) ; } self . refreshState ( ) ; self . updatePlaceholder ( ) ; self . updateOriginalInput ( { silent : silent } ) ; self . positionDropdown ( ) ; self . trigger ( 'item_remove' , value , $item ) ; } }

Removes the selected item matching
the provided value.

@param {string} value

Removes the selected item matching the provided value .


function() {
		if (!this.isRequired) return false;

		var invalid = !this.items.length;

		this.isInvalid = invalid;
		this.$control_input.prop('required', invalid);
		this.$input.prop('required', !invalid);
	}

function ( ) { if ( ! this . isRequired ) return false ; var invalid = ! this . items . length ; this . isInvalid = invalid ; this . $control_input . prop ( 'required' , invalid ) ; this . $input . prop ( 'required' , ! invalid ) ; }

Update the `required` attribute of both input and control input.

The `required` property needs to be activated on the control input
for the error to be displayed at the right place. `required` also
needs to be temporarily deactivated on the input since the input is
hidden and can't show errors.

Update the required attribute of both input and control input .


function() {
		var self = this;
		var trigger = self.isOpen;

		if (self.settings.mode === 'single' && self.items.length) {
			self.hideInput();

			// Do not trigger blur while inside a blur event,
			// this fixes some weird tabbing behavior in FF and IE.
			// See #1164
			if (!self.isBlurring) {
				self.$control_input.blur(); // close keyboard on iOS
			}
		}

		self.isOpen = false;
		self.$dropdown.hide();
		self.setActiveOption(null);
		self.refreshState();

		if (trigger) self.trigger('dropdown_close', self.$dropdown);
	}


function($el) {
		var caret = Math.min(this.caretPos, this.items.length);
		var el = $el[0];
		var target = this.buffer || this.$control[0];

		if (caret === 0) {
			target.insertBefore(el, target.firstChild);
		} else {
			target.insertBefore(el, target.childNodes[caret]);
		}

		this.setCaret(caret + 1);
	}

function ( $el ) { var caret = Math . min ( this . caretPos , this . items . length ) ; var el = $el [ 0 ] ; var target = this . buffer || this . $control [ 0 ] ; if ( caret === 0 ) { target . insertBefore ( el , target . firstChild ) ; } else { target . insertBefore ( el , target . childNodes [ caret ] ) ; } this . setCaret ( caret + 1 ) ; }

A helper method for inserting an element
at the current caret position.

@param {object} $el

A helper method for inserting an element at the current caret position .


function(templateName, data) {
		var value, id, label;
		var html = '';
		var cache = false;
		var self = this;
		var regex_tag = /^[\t \r\n]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;

		if (templateName === 'option' || templateName === 'item') {
			value = hash_key(data[self.settings.valueField]);
			cache = !!value;
		}

		// pull markup from cache if it exists
		if (cache) {
			if (!isset(self.renderCache[templateName])) {
				self.renderCache[templateName] = {};
			}
			if (self.renderCache[templateName].hasOwnProperty(value)) {
				return self.renderCache[templateName][value];
			}
		}

		// render markup
		html = $(self.settings.render[templateName].apply(this, [data, escape_html]));

		// add mandatory attributes
		if (templateName === 'option' || templateName === 'option_create') {
			if (!data[self.settings.disabledField]) {
				html.attr('data-selectable', '');
			}
		}
		else if (templateName === 'optgroup') {
			id = data[self.settings.optgroupValueField] || '';
			html.attr('data-group', id);
			if(data[self.settings.disabledField]) {
				html.attr('data-disabled', '');
			}
		}
		if (templateName === 'option' || templateName === 'item') {
			html.attr('data-value', value || '');
		}

		// update cache
		if (cache) {
			self.renderCache[templateName][value] = html[0];
		}

		return html[0];
	}

A helper method for rendering "item" and
"option" templates, given the data.

@param {string} templateName
@param {object} data
@returns {string}

A helper method for rendering item and option templates given the data .


function updateMetrics() {

		isVwDirty = false;
		DPR = window.devicePixelRatio;
		cssCache = {};
		sizeLengthCache = {};

		pf.DPR = DPR || 1;

		units.width = Math.max(window.innerWidth || 0, docElem.clientWidth);
		units.height = Math.max(window.innerHeight || 0, docElem.clientHeight);

		units.vw = units.width / 100;
		units.vh = units.height / 100;

		evalId = [ units.height, units.width, DPR ].join("-");

		units.em = pf.getEmValue();
		units.rem = units.em;
	}

function updateMetrics ( ) { isVwDirty = false ; DPR = window . devicePixelRatio ; cssCache = { } ; sizeLengthCache = { } ; pf . DPR = DPR || 1 ; units . width = Math . max ( window . innerWidth || 0 , docElem . clientWidth ) ; units . height = Math . max ( window . innerHeight || 0 , docElem . clientHeight ) ; units . vw = units . width / 100 ; units . vh = units . height / 100 ; evalId = [ units . height , units . width , DPR ] . join ( "-" ) ; units . em = pf . getEmValue ( ) ; units . rem = units . em ; }

updates the internal vW property with the current viewport width in px


function parseDescriptors() {

			// 9. Descriptor parser: Let error be no.
			var pError = false,

			// 10. Let width be absent.
			// 11. Let density be absent.
			// 12. Let future-compat-h be absent. (We're implementing it now as h)
			    w, d, h, i,
			    candidate = {},
			    desc, lastChar, value, intVal, floatVal;

			// 13. For each descriptor in descriptors, run the appropriate set of steps
			// from the following list:
			for (i = 0 ; i < descriptors.length; i++) {
				desc = descriptors[ i ];

				lastChar = desc[ desc.length - 1 ];
				value = desc.substring(0, desc.length - 1);
				intVal = parseInt(value, 10);
				floatVal = parseFloat(value);

				// If the descriptor consists of a valid non-negative integer followed by
				// a U+0077 LATIN SMALL LETTER W character
				if (regexNonNegativeInteger.test(value) && (lastChar === "w")) {

					// If width and density are not both absent, then let error be yes.
					if (w || d) {pError = true;}

					// Apply the rules for parsing non-negative integers to the descriptor.
					// If the result is zero, let error be yes.
					// Otherwise, let width be the result.
					if (intVal === 0) {pError = true;} else {w = intVal;}

				// If the descriptor consists of a valid floating-point number followed by
				// a U+0078 LATIN SMALL LETTER X character
				} else if (regexFloatingPoint.test(value) && (lastChar === "x")) {

					// If width, density and future-compat-h are not all absent, then let error
					// be yes.
					if (w || d || h) {pError = true;}

					// Apply the rules for parsing floating-point number values to the descriptor.
					// If the result is less than zero, let error be yes. Otherwise, let density
					// be the result.
					if (floatVal < 0) {pError = true;} else {d = floatVal;}

				// If the descriptor consists of a valid non-negative integer followed by
				// a U+0068 LATIN SMALL LETTER H character
				} else if (regexNonNegativeInteger.test(value) && (lastChar === "h")) {

					// If height and density are not both absent, then let error be yes.
					if (h || d) {pError = true;}

					// Apply the rules for parsing non-negative integers to the descriptor.
					// If the result is zero, let error be yes. Otherwise, let future-compat-h
					// be the result.
					if (intVal === 0) {pError = true;} else {h = intVal;}

				// Anything else, Let error be yes.
				} else {pError = true;}
			} // (close step 13 for loop)

			// 15. If error is still no, then append a new image source to candidates whose
			// URL is url, associated with a width width if not absent and a pixel
			// density density if not absent. Otherwise, there is a parse error.
			if (!pError) {
				candidate.url = url;

				if (w) { candidate.w = w;}
				if (d) { candidate.d = d;}
				if (h) { candidate.h = h;}
				if (!h && !d && !w) {candidate.d = 1;}
				if (candidate.d === 1) {set.has1x = true;}
				candidate.set = set;

				candidates.push(candidate);
			}
		}

Adds descriptor properties to a candidate, pushes to the candidates array
@return undefined
 (Declared outside of the while loop so that it's only created once. (This fn is defined before it is used, in order to pass JSHINT. Unfortunately this breaks the sequencing of the spec comments. :/ )

Adds descriptor properties to a candidate pushes to the candidates array


function extend(style, rule, sheet, newStyle = {}) {
  mergeExtend(style, rule, sheet, newStyle)
  mergeRest(style, rule, sheet, newStyle)
  return newStyle
}

function extend ( style , rule , sheet , newStyle = { } ) { mergeExtend ( style , rule , sheet , newStyle ) mergeRest ( style , rule , sheet , newStyle ) return newStyle }


function convertCase(style) {
  const converted = {}

  for (const prop in style) {
    const key = prop.indexOf('--') === 0 ? prop : hyphenate(prop)

    converted[key] = style[prop]
  }

  if (style.fallbacks) {
    if (Array.isArray(style.fallbacks)) converted.fallbacks = style.fallbacks.map(convertCase)
    else converted.fallbacks = convertCase(style.fallbacks)
  }

  return converted
}

function convertCase ( style ) { const converted = { } for ( const prop in style ) { const key = prop . indexOf ( '--' ) === 0 ? prop : hyphenate ( prop ) converted [ key ] = style [ prop ] } if ( style . fallbacks ) { if ( Array . isArray ( style . fallbacks ) ) converted . fallbacks = style . fallbacks . map ( convertCase ) else converted . fallbacks = convertCase ( style . fallbacks ) } return converted }

Convert camel cased property names to dash separated.

@param {Object} style
@return {Object}

Convert camel cased property names to dash separated .


function ResourceNamespace(stripe, resources) {
  for (var name in resources) {
    var camelCaseName = name[0].toLowerCase() + name.substring(1);

    var resource = new resources[name](stripe);

    this[camelCaseName] = resource;
  }
}

function ResourceNamespace ( stripe , resources ) { for ( var name in resources ) { var camelCaseName = name [ 0 ] . toLowerCase ( ) + name . substring ( 1 ) ; var resource = new resources [ name ] ( stripe ) ; this [ camelCaseName ] = resource ; } }

ResourceNamespace allows you to create nested resources, i.e. `stripe.issuing.cards`. It also works recursively, so you could do i.e. `stripe.billing.invoicing.pay`.

ResourceNamespace allows you to create nested resources i . e . stripe . issuing . cards . It also works recursively so you could do i . e . stripe . billing . invoicing . pay .


function(args) {
    if (args.length < 1 || !isPlainObject(args[0])) {
      return {};
    }

    if (!utils.isOptionsHash(args[0])) {
      return args.shift();
    }

    var argKeys = Object.keys(args[0]);

    var optionKeysInArgs = argKeys.filter(function(key) {
      return OPTIONS_KEYS.indexOf(key) > -1;
    });

    // In some cases options may be the provided as the first argument.
    // Here we're detecting a case where there are two distinct arguments
    // (the first being args and the second options) and with known
    // option keys in the first so that we can warn the user about it.
    if (optionKeysInArgs.length > 0 && optionKeysInArgs.length !== argKeys.length) {
      emitWarning(
        'Options found in arguments (' + optionKeysInArgs.join(', ') + '). Did you mean to pass an options ' +
        'object? See https://github.com/stripe/stripe-node/wiki/Passing-Options.'
      );
    }

    return {};
  }

Return the data argument from a list of arguments