d2c96c7aa1
Versuch über https://perchance.org/yz31uwjhue eine eingeschränkten AI Generator etwa für schulen zugänglich zu machen ```script image = {import:text-to-image-plugin} title Jesus Christus character Jesus Christus item a bag with coins a long staff a sword a red line fire bread and fishes bread and wine good smelling oil adjective compassionate serene resolute sorrowful pack bag sack none place Jerusalem Golgatha the Temple in the sky a garden in Hades the Last Supper time night day prompt detailed medieval painting of [character], [adjective], in [place] at [time], holding [item]. In the style of Caravaggio, Piero della Francesca, Michelangelo, Leonardo da Vinci, Rembrandt, or Lukas Cranach. Intricate brushwork, rich colors, dramatic lighting, classical style, oil on canvas, realism, fine details, high resolution, depth of field resolution = 512x768 output [image(prompt)]
4811 lines
557 KiB
Plaintext
4811 lines
557 KiB
Plaintext
<!DOCTYPE html> <html> <meta charset="utf-8"> <title>Perchance</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <base href="https://perchance.org/" target="_parent"> <meta name="referrer" content="no-referrer"> <style> html{ font-family:sans-serif; -ms-text-size-adjust:100%; -webkit-text-size-adjust:100%; } body{ margin:0;} article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section{ display:block;} audio, canvas, progress, video{ display:inline-block; vertical-align:baseline; } audio:not([controls]){ display:none;height:0;} [hidden], template{ display:none;} a{ background-color:transparent;} a:active, a:hover{ outline:0;} abbr[title]{ border-bottom:1px dotted;} b, strong{ font-weight:bold;} dfn{ font-style:italic;} h1{ font-size:2em;margin:0.67em 0;} mark{ background:#ff0;color:#000;} small{ font-size:80%;} sub, sup{ font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{ top:-0.5em;}sub{ bottom:-0.25em;} img{ border:0;} svg:not(:root){ overflow:hidden;} figure{ margin:1em 40px;} hr{ box-sizing:content-box;height:0;} pre{ overflow:auto;} code, kbd, pre, samp{ font-family:monospace, monospace;font-size:1em;} button:not([disabled]), input:not([disabled]), optgroup:not([disabled]), select:not([disabled]), textarea:not([disabled]){ color:inherit; }button, input, optgroup, select, textarea{ font:inherit; margin:0; } button{ overflow:visible;} button, select{ text-transform:none;} button, html input[type="button"], input[type="reset"], input[type="submit"]{ -webkit-appearance:button; cursor:pointer; } button[disabled], html input[disabled]{ cursor:default;} button::-moz-focus-inner, input::-moz-focus-inner{ border:0;padding:0;} input{ line-height:normal;} input[type="checkbox"], input[type="radio"]{ box-sizing:border-box; padding:0; } input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button{ height:auto;} input[type="search"]{ -webkit-appearance:textfield; box-sizing:content-box; } input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration{ -webkit-appearance:none;} fieldset{ border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;} legend{ border:0; padding:0; } textarea{ overflow:auto;} optgroup{ font-weight:bold;} table{ border-collapse:collapse;border-spacing:0;}td, th{ padding:0;}</style> <script>try{window.localStorage.testIfWeCanReadLocalStorageWithoutDOMError}catch(err){console.log("localStorage is disallowed. Adding a 'dummy' polyfill.");Object.defineProperty(window,"localStorage",{value:new Proxy({},{set:(t,k,v)=>t[k]=String(v)})})}</script> <script>let __localToken = "LOCAL"; // downloader changes this to "LOCAL"
|
||
function __inIframe () {
|
||
try {
|
||
return window.self !== window.top;
|
||
} catch (e) {
|
||
return true;
|
||
}
|
||
}
|
||
// to prevent *direct* null.perchance.org / <publicId>.perchance.org access (but let it run however if it's a local copy):
|
||
if(!__inIframe() && __localToken !== "LOCAL"){window.location.href="https://perchance.org/yz31uwjhue";} // not to self: don't change this without changing generator downloader script</script> <script>// POLYFILLS:
|
||
if(!Array.prototype.at) { // For Safari 14
|
||
Array.prototype.at = function(relativeIndex) {
|
||
let i = relativeIndex >= 0 ? relativeIndex : this.length + relativeIndex;
|
||
return this[i];
|
||
};
|
||
}</script> <script>window.__ignorePerchanceErrors=!1,window.generatorName="yz31uwjhue",window.generatorPublicId="e8a155a6f0e16d976bc0608fcb333ac7",window.generatorLastEditTime=Number("1717599511371"),window.__parentWindow=window.parent;</script> <style> html{ margin:0;padding:0;width:100%;height:100%;box-sizing:border-box;}*, *:before, *:after{ box-sizing:inherit;}body, #output-container{ margin:0;padding:0;text-align:center;}#output-container{ height:100%;}hidden{ position:fixed;top:-14000px;left:-14000px;} #output-container ul{ text-align:left;}</style> </head> <body> <script id="preloaded-generator-data" type="notjs">%7B%22name%22:%22yz31uwjhue%22,%22modelText%22:%22image%20=%20%7Bimport:text-to-image-plugin%7D%5Cn%5Cntitle%20%5Cn%20%20Jesus%20Christus%5Cn%5Cncharacter%5Cn%20%20Jesus%20Christus%5Cn%5Cnitem%5Cn%20%20a%20bag%20with%20coins%5Cn%20%20a%20long%20staff%5Cn%20%20a%20sword%5Cn%20%20a%20red%20line%5Cn%20%20fire%5Cn%20%20bread%20and%20fishes%5Cn%20%20bread%20and%20wine%5Cn%20%20good%20smelling%20oil%5Cn%5Cnadjective%5Cn%20%20compassionate%5Cn%20%20serene%5Cn%20%20resolute%5Cn%20%20sorrowful%5Cn%5Cnpack%5Cn%20%20bag%5Cn%20%20sack%5Cn%20%20none%5Cn%5Cnplace%5Cn%20%20Jerusalem%5Cn%20%20Golgatha%5Cn%20%20the%20Temple%5Cn%20%20in%20the%20sky%5Cn%20%20a%20garden%5Cn%20%20in%20Hades%5Cn%20%20the%20Last%20Supper%5Cn%5Cntime%5Cn%20%20night%5Cn%20%20day%5Cn%5Cnprompt%5Cn%20%20detailed%20medieval%20painting%20of%20%5Bcharacter%5D,%20%5Badjective%5D,%20in%20%5Bplace%5D%20at%20%5Btime%5D,%20holding%20%5Bitem%5D.%20%5Cn%20%20In%20the%20style%20of%20Caravaggio,%20Piero%20della%20Francesca,%20Michelangelo,%20Leonardo%20da%20Vinci,%20Rembrandt,%20or%20Lukas%20Cranach.%20%5Cn%20%20Intricate%20brushwork,%20rich%20colors,%20dramatic%20lighting,%20classical%20style,%20oil%20on%20canvas,%20realism,%20fine%20details,%20high%20resolution,%20depth%20of%20field%5Cn%20%20resolution%20=%20512x768%5Cn%5Cnoutput%5Cn%20%20%5Bimage(prompt)%5D%5Cn%22,%22outputTemplate%22:%22%3Ch1%3E%5Btitle%5D%3C/h1%3E%5Cn%3Cp%20style=%5C%22margin:1em%20auto;%20padding:0%201em;%20max-width:768px;%5C%22%3E%5Boutput%5D%3C/p%3E%5Cn%3Cinput%20oninput=%5C%22attribute%20=%20this.value%5C%22%20placeholder=%5C%22Gib%20ein%20zus%C3%A4tzliches%20Attribut%20an%5C%22%20onChange=%5C%22update()%5C%22/%3E%5Cn%3Cbutton%20onclick=%5C%22update()%5C%22%3EGeneriere%3C/button%3E%5Cn%5Cn%3Cbr%3E%5Cn%3C!--%20Learn%20HTML%20here:%20%20%20https://www.khanacademy.org/computing/computer-programming/html-css%20%20%20%20--%3E%5Cn%22,%22imports%22:%5B%22text-to-image-plugin%22%5D,%22canLink%22:false,%22isPrivate%22:false%7D</script> <script id="imported-generators" type="notjs">%5B%7B%22name%22:%22text-to-image-plugin%22,%22modelText%22:%22%5Cn//%20NOTE%20TO%20SELF:%20If%20you%20add%20more%20properties,%20make%20sure%20you%20add%20to%20the%20regex%20below,%20and%20the%20variable%20declarations%20in%20each%20'branch'%5Cn%5Cn$output(data)%20=%3E%5Cn%20%20if(data%20===%20undefined)%20return%20%5C%22(Error:%20you've%20input%20an%20empty%20value/variable%20into%20the%20text-to-image-plugin)%5C%22;%5Cn%20%20//%20if(options%20===%20undefined)%20options%20=%20%7B%7D;%5Cn%20%20%5Cn%20%20let%20serverOrigin%20=%20%5C%22https://image-generation.perchance.org%5C%22;%5Cn%20%20%5Cn%20%20let%20evaluatedInputs;%5Cn%5Cn%20%20////////////////////////////////////////////////%5Cn%20%20//%20%20%20%20%20%20%20set%20up%20handler%20for%20gallery%20%20%20%20%20%20%20%20%20%20%20//%5Cn%20%20////////////////////////////////////////////////%5Cn%5Cn%20%20if(!window.___addedTextToImagePluginFirstTimeCode98420274)%20%7B%5Cn%20%20%20%20window.addEventListener(%5C%22message%5C%22,%20function(e)%20%7B%5Cn%20%20%20%20%20%20let%20origin%20=%20e.origin%20%7C%7C%20e.originalEvent.origin;%20//%20For%20Chrome,%20the%20origin%20property%20is%20in%20the%20event.originalEvent%20object.%5Cn%20%20%20%20%20%20if(origin%20!==%20serverOrigin)%20%7B%5Cn%20%20%20%20%20%20%20%20return;%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20if(e.data.openGallerySignal)%20%7B%5Cn%20%20%20%20%20%20%20%20let%20ctn%20=%20document.createElement(%5C%22div%5C%22);%5Cn%20%20%20%20%20%20%20%20let%20subChannelName%20=%20e.data.subChannelName;%5Cn%20%20%20%20%20%20%20%20ctn.innerHTML%20=%20%60%3Cdiv%20onclick=%5C%22this.remove()%5C%22%20style=%5C%22backdrop-filter:brightness(0.3);position:fixed;top:0;left:0;right:0;bottom:0;z-index:999;%5C%22%3E%3Cdiv%20style=%5C%22position:fixed;top:5vh;bottom:5vh;left:5vh;right:5vh;background:white;border-radius:3px;%5C%22%3E%3Ciframe%20src=%5C%22$%7BserverOrigin%7D/gallery?channel=$%7Bwindow.generatorName%7D&subChannel=$%7BencodeURIComponent(subChannelName)%7D&sort=trending&timeRange=1-month&contentFilter=pg13%5C%22%20style=%5C%22border:0;width:100%25;height:100%25;%5C%22%3E%3C/iframe%3E%3C/div%3E%3C/div%3E%60;%5Cn%20%20%20%20%20%20%20%20document.body.appendChild(ctn.firstElementChild);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20if(e.data.savedImageToGallerySignal)%20%7B%5Cn%20%20%20%20%20%20%20%20document.querySelectorAll(%5C%22.text-to-image-plugin-gallery%5C%22).forEach(el%20=%3E%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20let%20targetOrigin%20=%20serverOrigin;%5Cn%20%20%20%20%20%20%20%20%20%20el.contentWindow.postMessage(%7BdoRefreshIfSortingByRecent:true%7D,%20targetOrigin);%5Cn%20%20%20%20%20%20%20%20%20%20%5Cn%20%20%20%20%20%20%20%20%20%20//%20the%20code%20below%20is%20commented%20out%20because%20it%20doesn't%20work%20for%20the%20case%20where%20the%20user%20has%20switched%20the%20sort%20to%20recent%20(since,%20counter-intuitively,%20iframe's%20window.location%20can%20change,%20while%20iframe.src%20stays%20as%20the%20original%20value%20-%20I'm%20assuming%20this%20is%20due%20to%20cross-origin%20security%20stuff)%5Cn%20%20%20%20%20%20%20%20%20%20//%20if(el.src.includes(%5C%22sort=recent%5C%22))%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20//%20%20%20//%20refresh%20galleries%20that%20are%20sorted%20by%20recent%20if%20the%20user%20makes%20a%20submission%5Cn%20%20%20%20%20%20%20%20%20%20//%20%20%20let%20url%20=%20new%20URL(el.src);%5Cn%20%20%20%20%20%20%20%20%20%20//%20%20%20url.searchParams.set(%5C%22cacheBust%5C%22,%20Math.random().toString());%5Cn%20%20%20%20%20%20%20%20%20%20//%20%20%20el.src%20=%20%5C%22%5C%22;%20//%20we%20do%20this%20instead%20of%20el.src=el.src%20because%20that%20doesn't%20work%20if%20the%20URL%20has%20a%20hash%20in%20it,%20and%20I%20might%20need%20to%20add%20data%20in%20the%20hash%20later%5Cn%20%20%20%20%20%20%20%20%20%20//%20%20%20setTimeout(()%20=%3Eel.src=url.href,%20700);%20//%20we%20need%20to%20wait%20a%20bit%20for%20the%20iframe%20to%20actually%20initiate%20a%20reload/refresh%20before%20setting%20the%20src%20again%5Cn%20%20%20%20%20%20%20%20%20%20//%20%7D%5Cn%20%20%20%20%20%20%20%20%7D);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20if(e.data.documentHeightChanged)%20%7B%5Cn%20%20%20%20%20%20%20%20document.querySelectorAll(%5C%22.text-to-image-plugin-gallery%5C%22).forEach(el%20=%3E%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20if(el.dataset.adaptiveHeight%20===%20%5C%22yes%5C%22)%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20el.style.height%20=%20(e.data.newHeight+1)+%5C%22px%5C%22;%5Cn%20%20%20%20%20%20%20%20%20%20%20%20console.log(%5C%22Updated%20gallery%20height%5C%22,%20e.data.newHeight);%5Cn%20%20%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%20%20%7D);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D);%5Cn%20%20%20%20window.___addedTextToImagePluginFirstTimeCode98420274%20=%20true;%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20if(data.gallery)%20%7B%5Cn%20%20%20%20//%20NOTE:%20this%20is%20a%20somewhat%20'breaking'%20change,%20but%20I'm%20no%20longer%20allowing%20unfiltered%20content%20to%20be%20shown%20by%20default.%5Cn%20%20%20%20//%20The%20user%20must%20specifically%20choose%20to%20switch%20the%20gallery%20to%20unfiltered%20mode.%5Cn%20%20%20%20data.contentFilter%20=%20%5C%22pg13%5C%22;%5Cn%20%20%5Cn%20%20%20%20let%20sort%20=%20data.sort%20?%20data.sort.evaluateItem%20:%20%5C%22recent%5C%22;%5Cn%20%20%20%20if(sort%20===%20%5C%22best%5C%22)%20sort%20=%20%5C%22top%5C%22;%20//%20alias%5Cn%20%20%20%20%5Cn%20%20%20%20let%20contentFilter%20=%20data.contentFilter%20?%20data.contentFilter.evaluateItem.toLowerCase()%20:%20%5C%22pg13%5C%22;%5Cn%20%20%20%20if(contentFilter%20===%20%5C%22pg-13%5C%22)%20contentFilter%20=%20%5C%22pg13%5C%22;%5Cn%20%20%20%20%5Cn%20%20%20%20let%20bannedUsers%20=%20data.bannedUsers%20?%20data.bannedUsers.selectAll.map(item%20=%3E%20item.toString())%20:%20%5B%5D;%5Cn%20%20%20%20let%20bannedPromptPhrases%20=%20data.bannedPromptPhrases%20?%20data.bannedPromptPhrases.selectAll.map(item%20=%3E%20item.getRawListText.replace(%5C%22/%5C%5C%5C%5C%5E%5C%22,%20%5C%22/%5E%5C%22))%20:%20%5B%5D;%5Cn%20%20%20%20let%20bannedNegativePromptPhrases%20=%20data.bannedNegativePromptPhrases%20?%20data.bannedNegativePromptPhrases.selectAll.map(item%20=%3E%20item.getRawListText.replace(%5C%22/%5C%5C%5C%5C%5E%5C%22,%20%5C%22/%5E%5C%22))%20:%20%5B%5D;%5Cn%20%20%20%20%5Cn%20%20%20%20let%20timeRange%20=%20data.timeRange%20?%20data.timeRange.evaluateItem%20:%20(sort%20===%20%5C%22recent%5C%22%20?%20%5C%22all-time%5C%22%20:%20%5C%221-month%5C%22);%5Cn%20%20%20%20let%20hideIfScoreIsBelow%20=%20data.hideIfScoreIsBelow%20!==%20undefined%20?%20Number(data.hideIfScoreIsBelow.evaluateItem)%20:%20-1000000000;%5Cn%20%20%20%20if(isNaN(hideIfScoreIsBelow))%20hideIfScoreIsBelow%20=%20-1000000000;%5Cn%20%20%20%20%5Cn%20%20%20%20let%20galleryOptions%20=%20%7Bsort,%20timeRange,%20hideIfScoreIsBelow,%20contentFilter,%20subChannel:%5C%22public%5C%22%7D;%20//%20this%20is%20also%20used%20for%20checking%20if%20gallery%20options%20have%20been%20udpated%20(see%20below)%5Cn%20%20%20%20if(data.forceColorScheme)%20galleryOptions.forceColorScheme%20=%20data.forceColorScheme;%5Cn%20%20%20%20%5Cn%20%20%20%20let%20hashData%20=%20%7BbannedUsers,%20bannedPromptPhrases,%20bannedNegativePromptPhrases,%20injectedStyles:%7B%7D%7D;%5Cn%20%20%20%20if(data.style)%20%7B%5Cn%20%20%20%20%20%20let%20style%20=%20data.style.evaluateItem.trim();%5Cn%20%20%20%20%20%20if(style.includes(%5C%22background:%5C%22))%20%7B%5Cn%20%20%20%20%20%20%20%20hashData.injectedStyles.background%20=%20(style.match(/(?:%5E%7C;)%20*background:(.+?)(?:;%7C$)/)%20%7C%7C%20%5B%5D)%5B1%5D;%5Cn%20%20%20%20%20%20%7D%20else%20if(style.includes(%5C%22background-color:%5C%22))%20%7B%5Cn%20%20%20%20%20%20%20%20hashData.injectedStyles.background%20=%20(style.match(/(?:%5E%7C;)%20*background-color:(.+?)(?:;%7C$)/)%20%7C%7C%20%5B%5D)%5B1%5D;%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%20%20%5Cn%20%20%20%20let%20otherUrlParams%20=%20%7Bchannel:window.generatorName%7D;%5Cn%20%20%20%20let%20iframeUrl%20=%20new%20URL(%60$%7BserverOrigin%7D/gallery%60);%5Cn%20%20%20%20Object.entries(galleryOptions).forEach((%5Bkey,%20value%5D)%20=%3E%20iframeUrl.searchParams.set(key,%20value));%5Cn%20%20%20%20Object.entries(otherUrlParams).forEach((%5Bkey,%20value%5D)%20=%3E%20iframeUrl.searchParams.set(key,%20value));%5Cn%20%20%20%20%5Cn%20%20%20%20%5Cn%20%20%20%20function%20makeGalleryIframeHtml()%20%7B%5Cn%20%20%20%20%20%20return%20%60%3Ciframe%20data-gallery-options=%5C%22$%7BencodeURIComponent(JSON.stringify(galleryOptions))%7D%5C%22%20data-adaptive-height=%5C%22$%7Bdata.adaptiveHeight%20?%20%5C%22yes%5C%22%20:%20%5C%22no%5C%22%7D%5C%22%20style=%5C%22width:100%25;%20height:70vh;%20border:none;%20$%7Bdata.style%20%7C%7C%20%5C%22%5C%22%7D%5C%22%20class=%5C%22text-to-image-plugin-gallery%5C%22%20src=%5C%22$%7BiframeUrl.href%7D#data=$%7BencodeURIComponent(JSON.stringify(hashData))%7D%5C%22%20allow=%5C%22clipboard-write%5C%22%3E%3C/iframe%3E%60;%5Cn%20%20%20%20%7D%5Cn%20%20%20%20%5Cn%20%20%20%20if(!document.querySelector(%5C%22.text-to-image-plugin-gallery%5C%22))%20%7B%5Cn%20%20%20%20%20%20setTimeout(()%20=%3E%20%7B%5Cn%20%20%20%20%20%20%20%20temporaryMarkerElForTextToImageGallery84738932.outerHTML%20=%20makeGalleryIframeHtml()%5Cn%20%20%20%20%20%20%7D,%2050);%5Cn%20%20%20%20%20%20return%20%60%3Cspan%20id=%5C%22temporaryMarkerElForTextToImageGallery84738932%5C%22%3E%3C/span%3E%60;%5Cn%20%20%20%20%7D%20else%20%7B%5Cn%20%20%20%20%20%20//%20update%20any%20gallery%20parameters%20if%20they%20have%20been%20changed:%5Cn%20%20%20%20%20%20let%20galleryIframe%20=%20document.querySelector(%5C%22.text-to-image-plugin-gallery%5C%22);%5Cn%20%20%20%20%20%20let%20newGalleryOptionsText%20=%20encodeURIComponent(JSON.stringify(galleryOptions));%5Cn%20%20%20%20%20%20if(galleryIframe.dataset.galleryOptions%20!==%20newGalleryOptionsText)%20%7B%5Cn%20%20%20%20%20%20%20%20galleryIframe.outerHTML%20=%20makeGalleryIframeHtml();%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20return%20%5C%22%5C%22;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20%5Cn%20%20%5Cn%20%20%5Cn%20%20%5Cn%20%20///////////////////////////////////////////////////////////////////////////////////////%5Cn%20%20//%20%20%20%20%20%20%20%20%20%20%20%20%20%20parse%20and%20evaluate%20prompt%20data/options%20from%20input%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%5Cn%20%20///////////////////////////////////////////////////////////////////////////////////////%5Cn%20%20const%20defaultGuidanceScale%20=%207;%5Cn%20%20%5Cn%20%20let%20d%20=%20%7B%7D;%20%5Cn%20%20//%20let%20dataInputWasNotAnOptionsObject%20=%20false;%5Cn%20%20%5Cn%20%20if(!data.prompt)%20%7B%5Cn%20%20%20%20d.prompt%20=%20data.evaluateItem;%20//%20they%20passed%20in%20some%20text%20directly%20like%20%5Bimage(%5C%22a%20carrot%5C%22)%5D%5Cn%20%20%7D%20else%20%7B%5Cn%20%20%20%20d.prompt%20=%20data.prompt.evaluateItem;%5Cn%20%20%7D%5Cn%20%20//%20Apply%20some%20covenience%20fixes%20to%20the%20prompt,%20even%20though%20the%20plugin%20user%20should%20ideally%20fix%20this%20on%20their%20end:%5Cn%20%20d.prompt%20=%20d.prompt.replace(/%3Cspan%20%5B%5E%3E%5D+______tippy-tooltip-%5B%5E%3E%5D+%3E(.+?)%3C%5C%5C/span%3E/,%20%5C%22$1%5C%22);%5Cn%20%20%5Cn%20%20//%20parse%20values%20from%20prompts%20like:%20%60this%20is%20the%20prompt%20text%20(size:::400)%20(resolution:::512x768)%20(guidanceScale:::10)%60%5Cn%20%20if(d.prompt.includes(%5C%22:::%5C%22))%20%7B%5Cn%20%20%20%20let%20matches%20=%20%5B...d.prompt.matchAll(/%5C%5C((seed%7Csize%7Cstyle%7Cresolution%7Cwidth%7Cheight%7CguidanceScale%7CsaveTitle%7CsaveDescription)%5C%5C:%5C%5C:%5C%5C:/g)%5D;%5Cn%20%20%20%20//%20console.log(%5C%22matches:%5C%22,%20matches);%5Cn%20%20%20%20const%20numericProps%20=%20%5B%5C%22seed%5C%22,%20%5C%22width%5C%22,%20%5C%22height%5C%22,%20%5C%22guidanceScale%5C%22,%20%5C%22width%5C%22,%20%5C%22height%5C%22,%20%5C%22size%5C%22%5D;%5Cn%20%20%20%20for(let%20match%20of%20matches)%20%7B%5Cn%20%20%20%20%20%20let%20re%20=%20new%20RegExp(%60%5C%5C%5C%5C($%7Bmatch%5B1%5D%7D%5C%5C%5C%5C:%5C%5C%5C%5C:%5C%5C%5C%5C:(.+?)%5C%5C%5C%5C).*?(?:%5C%5C%5C%5C:%5C%5C%5C%5C:%5C%5C%5C%5C:%7C$)%60);%5Cn%20%20%20%20%20%20let%20value%20=%20(d.prompt.match(re)%20%7C%7C%20%5B%5D)%5B1%5D%5Cn%20%20%20%20%20%20let%20key%20=%20match%5B1%5D;%5Cn%20%20%20%20%20%20if(value%20!==%20undefined)%20%7B%5Cn%20%20%20%20%20%20%20%20d%5Bkey%5D%20=%20numericProps.includes(key)%20?%20Number(value)%20:%20value;%5Cn%20%20%20%20%20%20%20%20d.prompt%20=%20d.prompt.replace(%60($%7Bkey%7D:::$%7Bvalue%7D)%60,%20%5C%22%5C%22);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%20%20d.prompt%20=%20d.prompt.trim();%5Cn%20%20%7D%5Cn%20%20if(!window.___t2i__parseNegativePrompt)%20%7B%5Cn%20%20%20%20window.___t2i__parseNegativePrompt%20=%20function(str)%20%7B%5Cn%20%20%20%20%20%20const%20prefix%20=%20'(negativePrompt:::';%5Cn%20%20%20%20%20%20const%20start%20=%20str.indexOf(prefix);%5Cn%20%20%20%20%20%20if%20(start%20===%20-1)%20return%20null;%5Cn%20%20%20%20%20%20let%20depth%20=%200;%5Cn%20%20%20%20%20%20let%20result%20=%20'';%5Cn%20%20%20%20%20%20for(let%20i%20=%20start%20+%20prefix.length;%20i%20%3C%20str.length;%20i++)%20%7B%5Cn%20%20%20%20%20%20%20%20if(str%5Bi%5D%20===%20'(')%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20depth++;%5Cn%20%20%20%20%20%20%20%20%7D%20else%20if%20(str%5Bi%5D%20===%20')')%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20if(depth%20===%200)%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20break;%5Cn%20%20%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%20%20%20%20depth--;%5Cn%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%20%20result%20+=%20str%5Bi%5D;%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20return%20result;%5Cn%20%20%20%20%7D;%5Cn%20%20%7D%5Cn%20%20if(d.prompt.includes(%5C%22(negativePrompt:::%5C%22))%20%7B%5Cn%20%20%20%20let%20result%20=%20window.___t2i__parseNegativePrompt(d.prompt);%5Cn%20%20%20%20if(result)%20%7B%5Cn%20%20%20%20%20%20d.negativePrompt%20=%20result;%5Cn%20%20%20%20%20%20d.prompt%20=%20d.prompt.replace(%60(negativePrompt:::$%7Bd.negativePrompt%7D)%60,%20%5C%22%5C%22);%5Cn%20%20%20%20%20%20d.prompt%20=%20d.prompt.replace(%60(negativePrompt:::$%7Bd.negativePrompt%7D%60,%20%5C%22%5C%22);%20//%20since%20if%20final%20bracket%20is%20missing,%20then%20all%20following%20text%20is%20considered%20the%20negative%20prompt%5Cn%20%20%20%20%7D%5Cn%20%20%20%20d.prompt%20=%20d.prompt.trim();%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20if(!data.prompt)%20%7B%20//%20they%20passed%20in%20some%20text%20directly%20like%20%5Bimage(%5C%22a%20carrot%5C%22)%5D,%20so%20add%20some%20defaults/fallbacks.%5Cn%20%20%20%20if(d.seed%20===%20undefined)%20d.seed%20=%20-1;%5Cn%20%20%20%20if(d.width%20===%20undefined)%20d.width%20=%20300;%5Cn%20%20%20%20if(d.height%20===%20undefined)%20d.height%20=%20300;%5Cn%20%20%20%20if(d.resolution%20===%20undefined)%20d.resolution%20=%20%5C%22512x512%5C%22;%20%20%20%5Cn%20%20%20%20if(d.guidanceScale%20===%20undefined)%20d.guidanceScale%20=%20defaultGuidanceScale;%5Cn%20%20%20%20if(d.negativePrompt%20===%20undefined)%20d.negativePrompt%20=%20%5C%22%5C%22;%5Cn%20%20%20%20if(d.style%20===%20undefined)%20d.style%20=%20%5C%22%5C%22;%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20%5Cn%20%20//%20EDIT:%20Not%20going%20ahead%20with%20this%20for%20now%20in%20favor%20of%20a%20setting%20a%20global%20variable%20which%20contains%20data%20on%20the%20last-used%20prompt.%5Cn%20%20//%20//%20NOTE:%20Originally%20%60data%60%20was%20the%20only%20param%20and%20it%20could%20be%20the%20prompt,%20or%20a%20promptOptions%20object/list.%5Cn%20%20//%20//%20But%20I%20realised%20that%20it's%20not%20very%20ergonomic%20(see%20e.g.%20reddit.com/r/perchance/comments/yta11r),%20so%20now,%20in%20a%20backwards-compatible%20way,%5Cn%20%20//%20//%20I'm%20allowing%20the%20user%20to%20pass%20the%20options%20as%20the%20second%20parameter%20instead.%20This%20just%20means%20that%20if%20data%20is%20a%20prompt%20(rather%20than%20a%5Cn%20%20//%20//%20promptOptions%20object),%20then%20we%20use%20the%20%60options%60%20parameter%20(which%20defaults%20to%20an%20empty%20object)%20for%20the%20generation%20options:%5Cn%20%20//%20if(dataInputWasNotAnOptionsObject)%20%7B%5Cn%20%20//%20%20%20data%20=%20options;%20//%20this%5Cn%20%20//%20%7D%5Cn%20%20%5Cn%20%20if(!d.seed)%20d.seed%20=%20data.seed%20?%20data.seed.evaluateItem%20:%20-1;%5Cn%20%20if(!d.resolution)%20d.resolution%20=%20data.resolution%20?%20data.resolution.evaluateItem%20:%20%5C%22512x512%5C%22;%5Cn%20%20if(!d.guidanceScale)%20d.guidanceScale%20=%20data.guidanceScale%20?%20data.guidanceScale.evaluateItem%20:%20defaultGuidanceScale;%5Cn%20%20if(!d.negativePrompt)%20d.negativePrompt%20=%20data.negativePrompt%20?%20data.negativePrompt.evaluateItem%20:%20%5C%22%5C%22;%5Cn%20%20if(!d.width)%20d.width%20=%20data.width%20?%20data.width.evaluateItem%20:%20undefined;%20%5Cn%20%20if(!d.height)%20d.height%20=%20data.height%20?%20data.height.evaluateItem%20:%20undefined;%20%5Cn%20%20if(!d.style)%20d.style%20=%20data.style%20?%20data.style.evaluateItem%20:%20%5C%22%5C%22;%5Cn%20%20if(!d.saveTitle)%20d.saveTitle%20=%20data.saveTitle%20?%20data.saveTitle.evaluateItem%20:%20%5C%22%5C%22;%5Cn%20%20if(!d.saveDescription)%20d.saveDescription%20=%20data.saveDescription%20?%20data.saveDescription.evaluateItem%20:%20%5C%22%5C%22;%5Cn%20%20%5Cn%20%20%5Cn%20%20//%20NOTE:%20This%20stuff%20is%20not%20longer%20needed%20because%20we%20do%20the%20parsing%20above%20regardless%20of%20whether%20they%20passed%20a%20plain%20string%20in,%20or%20a%20promptOptions%20object.%5Cn%20%20//%20//%20if%20seed%20is%20specified%20within%20the%20prompt%20with%20the%20(key:::value)%20format%20-%20i.e.%20they%20used%20promptOptions%20input%20but%20specified%20the%20seed%20within%20promptOptions.prompt,%20and%20so%20long%20as%20promptOptions.seed%20is%20not%20specified,%20then%20we%20set%20the%20seed%20to%20the%20one%20specified%20in%20the%20prompt:%5Cn%20%20//%20if(data.seed%20===%20undefined%20&&%20d.prompt.includes(%5C%22(seed:::%5C%22))%20%7B%5Cn%20%20//%20%20%20let%20seed%20=%20null;%5Cn%20%20//%20%20%20d.prompt%20=%20d.prompt.replace(/%5C%5C(seed:::(%5B0-9%5D+)%5C%5C)/g,%20(m,%20p1)%20=%3E%20%7B%20seed=Number(p1);%20return%20%5C%22%5C%22;%20%7D);%5Cn%20%20//%20%20%20if(seed)%20%7B%5Cn%20%20//%20%20%20%20%20d.seed%20=%20seed;%5Cn%20%20//%20%20%20%7D%5Cn%20%20//%20%7D%5Cn%20%20//%20//%20same%20for%20guidanceScale:%5Cn%20%20//%20if(data.guidanceScale%20===%20undefined%20&&%20d.prompt.includes(%5C%22(guidanceScale:::%5C%22))%20%7B%5Cn%20%20//%20%20%20let%20guidanceScale%20=%20null;%5Cn%20%20//%20%20%20d.prompt%20=%20d.prompt.replace(/%5C%5C(guidanceScale:::(%5B0-9%5D+)%5C%5C)/g,%20(m,%20p1)%20=%3E%20%7B%20guidanceScale=Number(p1);%20return%20%5C%22%5C%22;%20%7D);%5Cn%20%20//%20%20%20if(guidanceScale)%20%7B%5Cn%20%20//%20%20%20%20%20d.guidanceScale%20=%20guidanceScale;%5Cn%20%20//%20%20%20%7D%5Cn%20%20//%20%7D%5Cn%20%20//%20//%20same%20for%20width:%5Cn%20%20//%20if(data.guidanceScale%20===%20undefined%20&&%20d.prompt.includes(%5C%22(width:::%5C%22))%20%7B%5Cn%20%20//%20%20%20let%20width%20=%20null;%5Cn%20%20//%20%20%20d.prompt%20=%20d.prompt.replace(/%5C%5C(width:::(%5B0-9%5D+)%5C%5C)/g,%20(m,%20p1)%20=%3E%20%7B%20width=Number(p1);%20return%20%5C%22%5C%22;%20%7D);%5Cn%20%20//%20%20%20if(width)%20%7B%5Cn%20%20//%20%20%20%20%20d.width%20=%20width;%5Cn%20%20//%20%20%20%7D%5Cn%20%20//%20%7D%5Cn%20%20//%20//%20same%20for%20height:%5Cn%20%20//%20if(data.guidanceScale%20===%20undefined%20&&%20d.prompt.includes(%5C%22(height:::%5C%22))%20%7B%5Cn%20%20//%20%20%20let%20height%20=%20null;%5Cn%20%20//%20%20%20d.prompt%20=%20d.prompt.replace(/%5C%5C(height:::(%5B0-9%5D+)%5C%5C)/g,%20(m,%20p1)%20=%3E%20%7B%20height=Number(p1);%20return%20%5C%22%5C%22;%20%7D);%5Cn%20%20//%20%20%20if(height)%20%7B%5Cn%20%20//%20%20%20%20%20d.height%20=%20height;%5Cn%20%20//%20%20%20%7D%5Cn%20%20//%20%7D%5Cn%20%20//%20//%20same%20for%20size:%5Cn%20%20//%20if(data.guidanceScale%20===%20undefined%20&&%20d.prompt.includes(%5C%22(size:::%5C%22))%20%7B%5Cn%20%20//%20%20%20let%20size%20=%20null;%5Cn%20%20//%20%20%20d.prompt%20=%20d.prompt.replace(/%5C%5C(size:::(%5B0-9%5D+)%5C%5C)/g,%20(m,%20p1)%20=%3E%20%7B%20size=Number(p1);%20return%20%5C%22%5C%22;%20%7D);%5Cn%20%20//%20%20%20if(size)%20%7B%5Cn%20%20//%20%20%20%20%20d.size%20=%20size;%5Cn%20%20//%20%20%20%7D%5Cn%20%20//%20%7D%5Cn%20%20%5Cn%20%20%5Cn%20%20////////////////////////////////////////////////%5Cn%20%20//%20%20%20%20%20%20%20%20%20%20%20sanity%20checks%20on%20inputs%20%20%20%20%20%20%20%20%20%20//%5Cn%20%20////////////////////////////////////////////////%5Cn%20%20%5Cn%20%20if(d.size%20&&%20d.resolution%20&&%20d.resolution.split(%5C%22x%5C%22)%5B0%5D%20!==%20d.resolution.split(%5C%22x%5C%22)%5B1%5D)%20%7B%5Cn%20%20%20%20return%20%60(text-to-image-plugin:%20%3Cb%3Esize%3C/b%3E%20is%20only%20a%20valid%20parameter%20with%20square%20resolutions.%20use%20%3Cb%3Ewidth%3C/b%3E%20and%20%3Cb%3Eheight%3C/b%3E%20instead)%60;%5Cn%20%20%7D%5Cn%5Cn%20%20if(d.guidanceScale%20%3C%201%20%7C%7C%20Math.round(d.guidanceScale)%20!==%20d.guidanceScale)%20%7B%5Cn%20%20%20%20return%20%60(text-to-image-plugin:%20%3Cb%3EguidanceScale%3C/b%3E%20should%20be%20a%20whole%20number%20between%201%20and%2030,%20inclusive)%60;%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20if(!%5B%5C%22512x512%5C%22,%20%5C%22512x768%5C%22,%20%5C%22768x512%5C%22%5D.includes(d.resolution))%20%7B%5Cn%20%20%20%20return%20%5C%22(text-to-image-plugin:%20Currently,%20the%20only%20valid%20resolutions%20are%20512x512,%20512x768%20and%20768x512)%5C%22;%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20%5Cn%20%20%5Cn%20%20////////////////////////////////////////////////%5Cn%20%20//%20%20%20%20%20%20%20%20un-shortcut%20size/width/height%20%20%20%20%20%20%20//%5Cn%20%20////////////////////////////////////////////////%5Cn%20%20let%20resW%20=%20Number(d.resolution.split(%5C%22x%5C%22)%5B0%5D);%5Cn%20%20let%20resH%20=%20Number(d.resolution.split(%5C%22x%5C%22)%5B1%5D);%5Cn%20%20let%20widthHeightCss%20=%20%5C%22%5C%22;%5Cn%20%20if(d.size)%20%7B%5Cn%20%20%20%20let%20size%20=%20d.size.evaluateItem;%5Cn%20%20%20%20if(typeof%20size%20===%20%5C%22number%5C%22)%20size%20+=%20%5C%22px%5C%22;%5Cn%20%20%20%20widthHeightCss%20=%20%60width:$%7Bsize%7D%60;%5Cn%20%20%7D%20else%20%7B%5Cn%20%20%20%20if(d.width%20&&%20!d.height)%20%7B%5Cn%20%20%20%20%20%20d.width%20=%20d.width.evaluateItem;%5Cn%20%20%20%20%20%20if(typeof%20d.width%20===%20%5C%22number%5C%22)%20d.width%20+=%20%5C%22px%5C%22;%5Cn%20%20%20%20%20%20widthHeightCss%20=%20%60width:$%7Bd.width%7D%60;%5Cn%20%20%20%20%20%20//%20d.height%20=%20d.width%20*%20(resH/resW);%5Cn%20%20%20%20%7D%20else%20if(!d.width%20&&%20d.height)%20%7B%5Cn%20%20%20%20%20%20d.height%20=%20d.height.evaluateItem;%5Cn%20%20%20%20%20%20if(typeof%20d.height%20===%20%5C%22number%5C%22)%20d.height%20+=%20%5C%22px%5C%22;%5Cn%20%20%20%20%20%20widthHeightCss%20=%20%60height:$%7Bd.height%7D%60;%5Cn%20%20%20%20%20%20//%20d.width%20=%20d.height%20*%20(resW/resH);%5Cn%20%20%20%20%7D%20else%20if(!d.width%20&&%20!d.height)%20%7B%5Cn%20%20%20%20%20%20//%20make%20the%20smallest%20side%20300px%20by%20default:%5Cn%20%20%20%20%20%20if(resW%20%3E%20resH)%20%7B%5Cn%20%20%20%20%20%20%20%20d.height%20=%20300;%5Cn%20%20%20%20%20%20%20%20widthHeightCss%20=%20%60height:$%7Bd.height%7Dpx%60;%5Cn%20%20%20%20%20%20%20%20//%20d.width%20=%20d.height%20*%20(resW/resH);%5Cn%20%20%20%20%20%20%7D%20else%20%7B%5Cn%20%20%20%20%20%20%20%20d.width%20=%20300;%5Cn%20%20%20%20%20%20%20%20widthHeightCss%20=%20%60width:$%7Bd.width%7Dpx%60;%5Cn%20%20%20%20%20%20%20%20//%20d.height%20=%20d.width%20*%20(resH/resW);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%20else%20if(d.width%20&&%20d.height)%20%7B%5Cn%20%20%20%20%20%20if(typeof%20d.width%20===%20%5C%22number%5C%22)%20d.width%20+=%20%5C%22px%5C%22;%5Cn%20%20%20%20%20%20if(typeof%20d.height%20===%20%5C%22number%5C%22)%20d.height%20+=%20%5C%22px%5C%22;%5Cn%20%20%20%20%20%20widthHeightCss%20=%20%60width:$%7Bd.width%7D;%20height:$%7Bd.height%7D%60;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20if(d.style%20&&%20/%5B;%5C%5Cs%5D?(width%7Cheight):/.test(d.style))%20widthHeightCss%20=%20%5C%22%5C%22;%5Cn%20%20%5Cn%20%20if(!CSS.supports(%5C%22aspect-ratio%5C%22,%20%5C%221/2%5C%22))%20%7B%20//%20hackily%20help%20old%20browsers%20that%20don't%20support%20aspect-ratio%20if%20possible%5Cn%20%20%20%20let%20width%20=%20(widthHeightCss.match(/width:(%5B%5E;%5D+)px;?/)%20%7C%7C%20%5B%5D)%5B1%5D;%5Cn%20%20%20%20if(width%20&&%20!widthHeightCss.includes(%5C%22height%5C%22)%20&&%20!isNaN(Number(width)))%20%7B%5Cn%20%20%20%20%20%20widthHeightCss%20+=%20%60;%20height:$%7BNumber(width)%20*%20(resH/resW)%7Dpx;%60;%5Cn%20%20%20%20%7D%5Cn%20%20%20%20let%20height%20=%20(widthHeightCss.match(/height:(%5B%5E;%5D+)px;?/)%20%7C%7C%20%5B%5D)%5B1%5D;%5Cn%20%20%20%20if(height%20&&%20!widthHeightCss.includes(%5C%22width%5C%22)%20&&%20!isNaN(Number(height)))%20%7B%5Cn%20%20%20%20%20%20widthHeightCss%20+=%20%60;%20width:$%7BNumber(height)%20*%20(resW/resH)%7Dpx;%60;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20let%20requestId%20=%20Math.random().toString();%5Cn%20%20let%20privateIframeId%20=%20%5C%22id%5C%22%20+%20Math.random().toString().replace(%5C%22.%5C%22,%20%5C%22%5C%22);%5Cn%20%20%5Cn%20%20//%20let%20iframePromiseResolver;%5Cn%20%20//%20let%20iframePromise%20=%20new%20Promise(r%20=%3E%20iframePromiseResolver=r);%5Cn%20%20//%20let%20canvasPromiseResolver;%5Cn%20%20//%20let%20canvasPromise%20=%20new%20Promise(r%20=%3E%20canvasPromiseResolver=r);%5Cn%20%20//%20let%20dataUrlPromiseResolver;%5Cn%20%20//%20let%20dataUrlPromise%20=%20new%20Promise(r%20=%3E%20dataUrlPromiseResolver=r);%5Cn%20%20let%20onFinishPromiseResolver;%5Cn%20%20let%20onFinishPromise%20=%20new%20Promise(r%20=%3E%20onFinishPromiseResolver=r);%5Cn%20%20%5Cn%20%20window.addEventListener('message',%20async%20function(event)%20%7B%5Cn%20%20%20%20if(event.data.type%20===%20'finished'%20&&%20event.data.id%20===%20privateIframeId)%20%7B%5Cn%20%20%20%20%20%20%5Cn%20%20%20%20%20%20function%20drawDataURLToCanvas(dataURL)%20%7B%5Cn%20%20%20%20%20%20%20%20return%20new%20Promise((resolve,%20reject)%20=%3E%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20const%20canvas%20=%20document.createElement(%5C%22canvas%5C%22);%5Cn%20%20%20%20%20%20%20%20%20%20const%20ctx%20=%20canvas.getContext(%5C%222d%5C%22);%5Cn%20%20%20%20%20%20%20%20%20%20const%20img%20=%20new%20Image();%5Cn%20%20%20%20%20%20%20%20%20%20img.onload%20=%20()%20=%3E%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20canvas.width%20=%20img.width;%5Cn%20%20%20%20%20%20%20%20%20%20%20%20canvas.height%20=%20img.height;%5Cn%20%20%20%20%20%20%20%20%20%20%20%20ctx.drawImage(img,%200,%200);%5Cn%20%20%20%20%20%20%20%20%20%20%20%20resolve(canvas);%5Cn%20%20%20%20%20%20%20%20%20%20%7D;%5Cn%20%20%20%20%20%20%20%20%20%20img.src%20=%20dataURL;%5Cn%20%20%20%20%20%20%20%20%7D);%5Cn%20%20%20%20%20%20%7D%5Cn%5Cn%20%20%20%20%20%20let%20canvas%20=%20await%20drawDataURLToCanvas(event.data.dataUrl);%5Cn%20%20%20%20%20%20let%20iframe%20=%20document.querySelector(%60iframe.$%7BprivateIframeId%7D%60);%5Cn%20%20%20%20%20%20let%20dataUrl%20=%20event.data.dataUrl;%5Cn%20%20%20%20%20%20%5Cn%20%20%20%20%20%20let%20outputData%20=%20%7Bcanvas,%20iframe,%20dataUrl,%20inputs:evaluatedInputs%7D;%5Cn%20%20%20%20%20%20%5Cn%20%20%20%20%20%20iframe.textToImagePluginOutput%20=%20outputData;%5Cn%20%20%20%20%20%20%5Cn%20%20%20%20%20%20if(data.onFinish)%20%7B%5Cn%20%20%20%20%20%20%20%20data.onFinish(outputData);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20onFinishPromiseResolver(outputData);%5Cn%20%20%20%20%20%20%5Cn%20%20%20%20%20%20//%20dataUrlPromiseResolver(event.data.dataUrl);%5Cn%20%20%20%20%20%20//%20canvasPromiseResolver(canvas);%5Cn%20%20%20%20%20%20//%20iframePromiseResolver(document.querySelector(%60iframe.$%7BprivateIframeId%7D%60));%5Cn%20%20%20%20%7D%5Cn%20%20%7D);%5Cn%20%20%5Cn%20%20function%20blobToDataUrl(blob)%20%7B%5Cn%20%20%20%20return%20new%20Promise(r%20=%3E%20%7B%5Cn%20%20%20%20%20%20const%20reader%20=%20new%20FileReader();%5Cn%20%20%20%20%20%20reader.onload%20=%20()%20=%3E%20r(reader.result);%5Cn%20%20%20%20%20%20reader.readAsDataURL(blob);%5Cn%20%20%20%20%7D);%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20let%20referenceImage%20=%20null;%5Cn%20%20if(data.referenceImage)%20%7B%5Cn%20%20%20%20referenceImage%20=%20%7B%7D;%5Cn%20%20%20%20//%20url%20can%20actually%20be%20a%20blob%20or%20a%20blob%20URL,%20in%20which%20case%20we%20postMessage%20the%20data%20to%20the%20iframe%5Cn%20%20%20%20let%20isBlobby%20=%20data.referenceImage.url%20instanceof%20Blob;%20//%20blobby%20means%20Blob%20or%20blob%20URL%20string%5Cn%20%20%20%20let%20url,%20blobby;%5Cn%20%20%20%20%5Cn%20%20%20%20if(isBlobby)%20blobby%20=%20data.referenceImage.url;%5Cn%20%20%20%20else%20url%20=%20data.referenceImage.url.evaluateItem;%5Cn%20%20%20%20%5Cn%20%20%20%20if(url.startsWith(%5C%22blob:%5C%22))%20%7B%5Cn%20%20%20%20%20%20isBlobby%20=%20true;%5Cn%20%20%20%20%20%20blobby%20=%20url;%5Cn%20%20%20%20%20%20url%20=%20null;%5Cn%20%20%20%20%7D%5Cn%20%20%20%20%5Cn%20%20%20%20if(isBlobby)%20%7B%5Cn%20%20%20%20%20%20referenceImage.url%20=%20%5C%22%3Cdata-via-postmessage%3E%5C%22;%5Cn%20%20%20%20%20%20(async%20()%20=%3E%20%7B%5Cn%20%20%20%20%20%20%20%20let%20blob;%5Cn%20%20%20%20%20%20%20%20if(typeof%20blobby%20===%20%5C%22string%5C%22%20&&%20blobby.startsWith(%5C%22blob:%5C%22))%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20blob%20=%20await%20fetch(blobby).then(r%20=%3E%20r.blob());%5Cn%20%20%20%20%20%20%20%20%7D%20else%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20blob%20=%20blobby;%5Cn%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%20%20let%20dataUrl%20=%20await%20blobToDataUrl(blob);%5Cn%20%20%20%20%20%20%20%20window.addEventListener('message',%20function(event)%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20if(event.data.type%20===%20'readyForData'%20&&%20event.data.id%20===%20privateIframeId)%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20document.querySelector(%60iframe.$%7BprivateIframeId%7D%60).contentWindow.postMessage(%7Bid:privateIframeId,%20referenceImageDataUrl:dataUrl%7D,%20serverOrigin);%5Cn%20%20%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%20%20%7D);%5Cn%20%20%20%20%20%20%7D)();%5Cn%20%20%20%20%7D%20else%20%7B%5Cn%20%20%20%20%20%20referenceImage.url%20=%20url;%5Cn%20%20%20%20%7D%5Cn%20%20%20%20referenceImage.blur%20=%20data.referenceImage.blur.evaluateItem;%5Cn%20%20%20%20if(referenceImage.url%20%3E%201%20%7C%7C%20referenceImage.url%20%3C%200)%20return%20%60referenceImage.url%20must%20either%20be%20a%20'data%20URL'%20(starting%20with%20'data:')%20or%20a%20https://user-uploads.perchance.org%20URL%20-%20i.e.%20an%20image%20that%20has%20been%20uploaded%20to%20https://perchance.org/upload%20-%20the%20URL%20you've%20used%20is:%20'$%7BreferenceImage.url%20&&%20typeof%20referenceImage.url%20===%20%5C%22string%5C%22%20&&%20referenceImage.url.length%20%3E%2030%20?%20referenceImage.url.slice(0,%2030)+%5C%22...%5C%22%20:%20referenceImage.url%7D'.%60;%5Cn%20%20%20%20if(referenceImage.blur%20%3E%201%20%7C%7C%20referenceImage.blur%20%3C%200)%20return%20%60referenceImage.blur%20must%20be%20between%200%20and%201,%20but%20is%20instead%20'$%7BreferenceImage.blur%20%3E%201%7D'.%60%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20window.addEventListener('message',%20function(event)%20%7B%5Cn%20%20%20%20if(event.data.type%20===%20'readyForData'%20&&%20event.data.id%20===%20privateIframeId)%20%7B%5Cn%20%20%20%20%20%20document.querySelector(%60iframe.$%7BprivateIframeId%7D%60).contentWindow.postMessage(%7Btype:%5C%22originNotify%5C%22,%20frameId:privateIframeId%7D,%20serverOrigin);%5Cn%20%20%20%20%7D%5Cn%20%20%7D);%5Cn%20%20%5Cn%20%20let%20urlHashData%20=%20%7B%5Cn%20%20%20%20saveChannel:%20window.generatorName,%5Cn%20%20%20%20saveTitle:%20d.saveTitle,%5Cn%20%20%20%20saveDescription:%20d.saveDescription,%5Cn%20%20%20%20prompt:%20d.prompt,%5Cn%20%20%20%20seed:%20d.seed,%5Cn%20%20%20%20resolution:%20d.resolution,%5Cn%20%20%20%20guidanceScale:%20d.guidanceScale,%5Cn%20%20%20%20defaultGuidanceScale,%5Cn%20%20%20%20negativePrompt:%20d.negativePrompt,%5Cn%20%20%20%20requestId:%20requestId,%5Cn%20%20%20%20forceColorScheme:%20data.forceColorScheme,%5Cn%20%20%20%20verifyOnly:%20data.verifyOnly,%5Cn%20%20%20%20iframeId:%20privateIframeId,%5Cn%20%20%20%20referenceImage,%5Cn%20%20%7D;%5Cn%20%20%5Cn%20%20//%20clone%20input%20for%20onFinish%20data:%5Cn%20%20evaluatedInputs%20=%20JSON.parse(JSON.stringify(d));%5Cn%20%20%5Cn%20%20let%20iframeId%20=%20data.id%20?%20data.id.evaluateItem%20:%20%5C%22%5C%22;%5Cn%20%20if(iframeId)%20%7B%5Cn%20%20%20%20setTimeout(()%20=%3E%20%7B%5Cn%20%20%20%20%20%20document.querySelector(%5C%22#%5C%22+iframeId).reload%20=%20function()%20%7B%5Cn%20%20%20%20%20%20%20%20let%20src%20=%20this.src;%5Cn%20%20%20%20%20%20%20%20this.src%20=%20%5C%22%5C%22;%5Cn%20%20%20%20%20%20%20%20setTimeout(()%20=%3Ethis.src=src,%20700);%5Cn%20%20%20%20%20%20%7D;%5Cn%20%20%20%20%7D,%20500);%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20window.lastTextToImagePrompt%20=%20d.prompt;%5Cn%20%20if(data.prompt)%20%7B%20//%20%3C--%20i.e.%20if%20they%20passed%20a%20promptOptions%20object%5Cn%20%20%20%20data.lastUsedPrompt%20=%20d.prompt;%5Cn%20%20%20%20data.lastUsedNegativePrompt%20=%20d.negativePrompt;%5Cn%20%20%7D%5Cn%20%20%5Cn%20%20//%20VERY%20lazily%20load%20the%20iframe%20(only%20when%20screen%20actually%20intersects)%20because%20some%20people%20add%20a%20lot%20of%20images%20in%20subsections%20and%20in%20several%20different%20tabs%20of%20tabs-plugin,%20etc.%5Cn%20%20//%20This%20ensures%20they%20don't%20spam%20the%20server,%20and%20the%20visible%20ones%20get%20generated%20first.%5Cn%20%20setTimeout(async%20()%20=%3E%20%7B%5Cn%20%20%20%20//%20the%20dev%20may%20have%20generated%20the%20HTML,%20but%20not%20actually%20added%20it%20to%20the%20DOM%20for%20a%20while,%20so%20we%20wait%20up%20to%205%20mins%20for%20it%5Cn%20%20%20%20let%20waitedSeconds%20=%200;%5Cn%20%20%20%20while(%5B...document.querySelectorAll(%5C%22.text-to-image-plugin-image-iframe%5C%22)%5D.filter(el%20=%3E%20el.dataset.alreadyAddedIntersectionObserver%20===%20%5C%22no%5C%22).length%20===%200)%20%7B%5Cn%20%20%20%20%20%20await%20new%20Promise(r%20=%3E%20setTimeout(r,%20500));%5Cn%20%20%20%20%20%20waitedSeconds%20+=%200.5;%5Cn%20%20%20%20%20%20if(waitedSeconds%20%3E%2060*5)%20return;%5Cn%20%20%20%20%7D%5Cn%20%20%20%20for(let%20el%20of%20%5B...document.querySelectorAll(%5C%22.text-to-image-plugin-image-iframe%5C%22)%5D)%20%7B%5Cn%20%20%20%20%20%20if(el.dataset.alreadyAddedIntersectionObserver%20===%20%5C%22yes%5C%22)%20continue;%5Cn%20%20%20%20%20%20el.dataset.alreadyAddedIntersectionObserver%20=%20%5C%22yes%5C%22;%5Cn%20%20%20%20%20%20%5Cn%20%20%20%20%20%20let%20observer1,%20observer2;%5Cn%20%20%20%20%20%20%5Cn%20%20%20%20%20%20let%20rootMarginSize%20=%20Math.min(1000,%20(window.innerHeight*2));%5Cn%20%20%20%20%20%20if(window.innerWidth%20%3C%20600)%20%7B%5Cn%20%20%20%20%20%20%20%20rootMarginSize%20=%20Math.min(1500,%20(window.innerHeight*3));%20//%20larger%20on%20mobile%20because%20e.g.%20images%20that%20might%20otherwise%20be%20displayed%20side%20by%20side%20are%20instead%20displayed%20vertically%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%5Cn%20%20%20%20%20%20function%20handler(entries)%20%7B%5Cn%20%20%20%20%20%20%20%20if(entries%5B0%5D.isIntersecting)%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20//%20console.log(%5C%22t2i%20iframe:%20Visible%5C%22);%5Cn%20%20%20%20%20%20%20%20%20%20if(!el.src)%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20el.removeAttribute(%5C%22srcdoc%5C%22);%5Cn%20%20%20%20%20%20%20%20%20%20%20%20el.src%20=%20el.dataset.src;%5Cn%20%20%20%20%20%20%20%20%20%20%20%20observer1.disconnect();%5Cn%20%20%20%20%20%20%20%20%20%20%20%20observer2.disconnect();%20%5Cn%20%20%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%20%20%7D%20else%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20//%20console.log(%5C%22t2i%20iframe:%20NOT%20Visible%5C%22);%5Cn%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20observer1%20=%20new%20IntersectionObserver(handler,%20%7B%5Cn%20%20%20%20%20%20%20%20root:%20document.documentElement,%20//%20otherwise%20I%20think%20it%20uses%20the%20top-level%20viewport?%20either%20way,%20it%20doesn't%20seem%20to%20work%20without%20specifying%20this.%5Cn%20%20%20%20%20%20%20%20rootMargin:%20rootMarginSize+%5C%22px%5C%22,%20//%20it's%20important%20that%20this%20is%20quite%20big%20-%20so%20that%20e.g.%20mobile%20users%20don't%20have%20to%20scroll%20down%20to%20trigger%20stuff.%20we%20basically%20want%20to%20trigger%20~all%20visible%20elements%20anyway%20-%20just%20not%20stuff%20hidden%20within%20e.g.%20tabs%20plugin%20or%20whatever.%5Cn%20%20%20%20%20%20%7D);%5Cn%20%20%20%20%20%20observer1.observe(el);%5Cn%20%20%20%20%20%20//%20for%20some%20reason,%20in%20some%20situations,%20the%20above%20intersection%20observer%20was%20reporting%20the%20%60root%60%20and%20%60el%60%20bounding%20rects%20as%200x0x0x0.%20Adding%20a%20second%20observer%20using%20the%20viewport%20root%20fixes%20this:%5Cn%20%20%20%20%20%20observer2%20=%20new%20IntersectionObserver(handler,%20%7B%5Cn%20%20%20%20%20%20%20%20rootMargin:%20rootMarginSize+%5C%22px%5C%22,%5Cn%20%20%20%20%20%20%7D);%5Cn%20%20%20%20%20%20observer2.observe(el);%5Cn%20%20%20%20%7D%5Cn%20%20%7D,%20100);%20//%20CAUTION:%20do%20not%20remove/lower%20this%20delay.%20Some%20generators%20may%20create%20a%20large%20%5C%22feed%5C%22%20of%20images,%20and%20expect%20them%20to%20be%20lazy-loaded%20when%20scrolled%20to%20(e.g.%20AI%20chat%20feeds),%20so%20if%20you%20add%20the%20intersection%20observers%20~synchronously,%20they%20could%20be%20triggered%20during%20the%20process%20of%20actually%20generating%20the%20feed,%20which%20would%20cause%20them%20to%20all%20start%20generating%20during%20page%20load.%5Cn%20%20%5Cn%20%20let%20outputString%20=%20new%20String(%60%3Ciframe%20$%7BiframeId%20?%20%60id=%5C%22$%7BiframeId%7D%5C%22%60%20:%20%5C%22%5C%22%7D%20class=%5C%22text-to-image-plugin-image-iframe%20$%7BprivateIframeId%7D%5C%22%20data-already-added-intersection-observer=%5C%22no%5C%22%20data-src=%5C%22$%7BserverOrigin%7D/embed#$%7BencodeURIComponent(JSON.stringify(urlHashData))%7D%5C%22%20style=%5C%22border:0;%20background:transparent;%20$%7BwidthHeightCss%7D;%20aspect-ratio:$%7BresW%7D/$%7BresH%7D;%20$%7Bd.style%7D%5C%22%3E%3C/iframe%3E%60);%5Cn%20%20%5Cn%20%20//%20leaving%20these%20out%20for%20now%20in%20favor%20of%20'onFinish'%20in%20prompt%20options%5Cn%20%20//%20outputString.dataUrl%20=%20dataUrlPromise;%5Cn%20%20//%20outputString.canvas%20=%20canvasPromise;%5Cn%20%20outputString.onFinishPromise%20=%20onFinishPromise;%5Cn%20%20outputString.iframeHtml%20=%20outputString;%5Cn%20%20%5Cn%20%20return%20outputString;%5Cn%5Cn%5Cncharacter%5Cn%20%20a%20%7Bmech%7Cdemon%7Ccyberpunk%7D%20%7Bwarrior%7Cminion%7Csamurai%7D%5Cn%5Cnplace%5Cn%20%20soviet%20russia%5Cn%20%20a%20small%20village%5Cn%20%20a%20mountainous%20region%5Cn%20%20an%20underwater%20cavern%5Cn%5Cnseason%5Cn%20%20winter%5Cn%20%20summer%5Cn%20%20%5Cnprompt%5Cn%20%20detailed%20painting%20of%20%5Bcharacter%5D%20in%20%5Bplace%5D,%20%5Bseason%5D%5Cn%20%20%5Cn%20%20%5Cn%20%20%5Cn%22,%22imports%22:%5B%5D,%22lastEditTime%22:1716123496233,%22found%22:true%7D%5D</script> <script id="imported-generator-names" type="notjs">%5B%22text-to-image-plugin%22%5D</script> <script id="this-html-server-render-time" type="notjs">1717599525029</script> <script>/* compromise v11.12.4
|
||
github.com/nlp-compromise/compromise
|
||
MIT
|
||
*/
|
||
|
||
!function(t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).nlp=t()}(function(){return function i(o,s,u){function l(e,t){if(!s[e]){if(!o[e]){var r="function"==typeof require&&require;if(!t&&r)return r(e,!0);if(c)return c(e,!0);var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[e]={exports:{}};o[e][0].call(a.exports,function(t){return l(o[e][1][t]||t)},a,a.exports,i,o,s,u)}return s[e].exports}for(var c="function"==typeof require&&require,t=0;t<u.length;t++)l(u[t]);return l}({1:[function(h,r,n){(function(e){!function(t){"object"==typeof n&&void 0!==r?r.exports=t():("undefined"!=typeof window?window:void 0!==e?e:"undefined"!=typeof self?self:this).unpack=t()}(function(){return function i(o,s,u){function l(e,t){if(!s[e]){if(!o[e]){var r="function"==typeof h&&h;if(!t&&r)return r(e,!0);if(c)return c(e,!0);var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[e]={exports:{}};o[e][0].call(a.exports,function(t){return l(o[e][1][t]||t)},a,a.exports,i,o,s,u)}return s[e].exports}for(var c="function"==typeof h&&h,t=0;t<u.length;t++)l(u[t]);return l}({1:[function(t,e,r){"use strict";var s=36,i="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",u=i.split("").reduce(function(t,e,r){return t[e]=r,t},{});e.exports={toAlphaCode:function(t){if(void 0!==i[t])return i[t];for(var e=1,r=s,n="";r<=t;t-=r,e++,r*=s);for(;e--;){var a=t%s;n=String.fromCharCode((a<10?48:55)+a)+n,t=(t-a)/s}return n},fromAlphaCode:function(t){if(void 0!==u[t])return u[t];for(var e=0,r=1,n=s,a=1;r<t.length;e+=n,r++,n*=s);for(var i=t.length-1;0<=i;i--,a*=s){var o=t.charCodeAt(i)-48;10<o&&(o-=7),e+=o*a}return e}}},{}],2:[function(t,e,r){"use strict";var o=t("./unpack");e.exports=function(t){var a=t.split("|").reduce(function(t,e){var r=e.split("¦");return t[r[0]]=r[1],t},{}),i={};return Object.keys(a).forEach(function(t){var e=o(a[t]);"true"===t&&(t=!0);for(var r=0;r<e.length;r++){var n=e[r];!0===i.hasOwnProperty(n)?!1===Array.isArray(i[n])?i[n]=[i[n],t]:i[n].push(t):i[n]=t}}),i}},{"./unpack":4}],3:[function(t,e,r){"use strict";var a=t("../encoding");e.exports=function(t){for(var e=new RegExp("([0-9A-Z]+):([0-9A-Z]+)"),r=0;r<t.nodes.length;r++){var n=e.exec(t.nodes[r]);if(!n){t.symCount=r;break}t.syms[a.fromAlphaCode(n[1])]=a.fromAlphaCode(n[2])}t.nodes=t.nodes.slice(t.symCount,t.nodes.length)}},{"../encoding":1}],4:[function(t,e,r){"use strict";var n=t("./symbols"),p=t("../encoding");e.exports=function(t){var m,d,e={nodes:t.split(";"),syms:[],symCount:0};return t.match(":")&&n(e),m=e,d=[],function t(e,r){var n,a,i,o,s=m.nodes[e];"!"===s[0]&&(d.push(r),s=s.slice(1));for(var u=s.split(/([A-Z0-9,]+)/g),l=0;l<u.length;l+=2){var c=u[l],h=u[l+1];if(c){var f=r+c;","!==h&&void 0!==h?t((n=m,a=h,i=e,(o=p.fromAlphaCode(a))<n.symCount?n.syms[o]:i+o+1-n.symCount),f):d.push(f)}}}(0,""),d}},{"../encoding":1,"./symbols":3}]},{},[2])(2)}),function(t){"object"==typeof n&&void 0!==r?r.exports=t():("undefined"!=typeof window?window:void 0!==e?e:"undefined"!=typeof self?self:this).unpack=t()}(function(){return function i(o,s,u){function l(e,t){if(!s[e]){if(!o[e]){var r="function"==typeof h&&h;if(!t&&r)return r(e,!0);if(c)return c(e,!0);var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[e]={exports:{}};o[e][0].call(a.exports,function(t){return l(o[e][1][t]||t)},a,a.exports,i,o,s,u)}return s[e].exports}for(var c="function"==typeof h&&h,t=0;t<u.length;t++)l(u[t]);return l}({1:[function(t,e,r){"use strict";var i="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",s=i.split("").reduce(function(t,e,r){return t[e]=r,t},{});e.exports={toAlphaCode:function(t){if(void 0!==i[t])return i[t];for(var e=1,r=36,n="";r<=t;t-=r,e++,r*=36);for(;e--;){var a=t%36;n=String.fromCharCode((a<10?48:55)+a)+n,t=(t-a)/36}return n},fromAlphaCode:function(t){if(void 0!==s[t])return s[t];for(var e=0,r=1,n=36,a=1;r<t.length;e+=n,r++,n*=36);for(var i=t.length-1;0<=i;i--,a*=36){var o=t.charCodeAt(i)-48;10<o&&(o-=7),e+=o*a}return e}}},{}],2:[function(t,e,r){"use strict";var o=t("./unpack");e.exports=function(t){var a=t.split("|").reduce(function(t,e){var r=e.split("¦");return t[r[0]]=r[1],t},{}),i={};return Object.keys(a).forEach(function(t){var e=o(a[t]);"true"===t&&(t=!0);for(var r=0;r<e.length;r++){var n=e[r];!0===i.hasOwnProperty(n)?!1===Array.isArray(i[n])?i[n]=[i[n],t]:i[n].push(t):i[n]=t}}),i}},{"./unpack":4}],3:[function(t,e,r){"use strict";var a=t("../encoding");e.exports=function(t){for(var e=new RegExp("([0-9A-Z]+):([0-9A-Z]+)"),r=0;r<t.nodes.length;r++){var n=e.exec(t.nodes[r]);if(!n){t.symCount=r;break}t.syms[a.fromAlphaCode(n[1])]=a.fromAlphaCode(n[2])}t.nodes=t.nodes.slice(t.symCount,t.nodes.length)}},{"../encoding":1}],4:[function(t,e,r){"use strict";var n=t("./symbols"),p=t("../encoding");e.exports=function(t){var m,d,e={nodes:t.split(";"),syms:[],symCount:0};return t.match(":")&&n(e),m=e,d=[],function t(e,r){var n,a,i,o,s=m.nodes[e];"!"===s[0]&&(d.push(r),s=s.slice(1));for(var u=s.split(/([A-Z0-9,]+)/g),l=0;l<u.length;l+=2){var c=u[l],h=u[l+1];if(c){var f=r+c;","!==h&&void 0!==h?t((n=m,a=h,i=e,(o=p.fromAlphaCode(a))<n.symCount?n.syms[o]:i+o+1-n.symCount),f):d.push(f)}}}(0,""),d}},{"../encoding":1,"./symbols":3}]},{},[2])(2)}),function(t){"object"==typeof n&&void 0!==r?r.exports=t():("undefined"!=typeof window?window:void 0!==e?e:"undefined"!=typeof self?self:this).unpack=t()}(function(){return function i(o,s,u){function l(e,t){if(!s[e]){if(!o[e]){var r="function"==typeof h&&h;if(!t&&r)return r(e,!0);if(c)return c(e,!0);var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[e]={exports:{}};o[e][0].call(a.exports,function(t){return l(o[e][1][t]||t)},a,a.exports,i,o,s,u)}return s[e].exports}for(var c="function"==typeof h&&h,t=0;t<u.length;t++)l(u[t]);return l}({1:[function(t,e,r){"use strict";var i="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",s=i.split("").reduce(function(t,e,r){return t[e]=r,t},{});e.exports={toAlphaCode:function(t){if(void 0!==i[t])return i[t];for(var e=1,r=36,n="";r<=t;t-=r,e++,r*=36);for(;e--;){var a=t%36;n=String.fromCharCode((a<10?48:55)+a)+n,t=(t-a)/36}return n},fromAlphaCode:function(t){if(void 0!==s[t])return s[t];for(var e=0,r=1,n=36,a=1;r<t.length;e+=n,r++,n*=36);for(var i=t.length-1;0<=i;i--,a*=36){var o=t.charCodeAt(i)-48;10<o&&(o-=7),e+=o*a}return e}}},{}],2:[function(t,e,r){"use strict";var o=t("./unpack");e.exports=function(t){var a=t.split("|").reduce(function(t,e){var r=e.split("¦");return t[r[0]]=r[1],t},{}),i={};return Object.keys(a).forEach(function(t){var e=o(a[t]);"true"===t&&(t=!0);for(var r=0;r<e.length;r++){var n=e[r];!0===i.hasOwnProperty(n)?!1===Array.isArray(i[n])?i[n]=[i[n],t]:i[n].push(t):i[n]=t}}),i}},{"./unpack":4}],3:[function(t,e,r){"use strict";var a=t("../encoding");e.exports=function(t){for(var e=new RegExp("([0-9A-Z]+):([0-9A-Z]+)"),r=0;r<t.nodes.length;r++){var n=e.exec(t.nodes[r]);if(!n){t.symCount=r;break}t.syms[a.fromAlphaCode(n[1])]=a.fromAlphaCode(n[2])}t.nodes=t.nodes.slice(t.symCount,t.nodes.length)}},{"../encoding":1}],4:[function(t,e,r){"use strict";var n=t("./symbols"),p=t("../encoding");e.exports=function(t){var m,d,e={nodes:t.split(";"),syms:[],symCount:0};return t.match(":")&&n(e),m=e,d=[],function t(e,r){var n,a,i,o,s=m.nodes[e];"!"===s[0]&&(d.push(r),s=s.slice(1));for(var u=s.split(/([A-Z0-9,]+)/g),l=0;l<u.length;l+=2){var c=u[l],h=u[l+1];if(c){var f=r+c;","!==h&&void 0!==h?t((n=m,a=h,i=e,(o=p.fromAlphaCode(a))<n.symCount?n.syms[o]:i+o+1-n.symCount),f):d.push(f)}}}(0,""),d}},{"../encoding":1,"./symbols":3}]},{},[2])(2)}),function(t){"object"==typeof n&&void 0!==r?r.exports=t():("undefined"!=typeof window?window:void 0!==e?e:"undefined"!=typeof self?self:this).unpack=t()}(function(){return function i(o,s,u){function l(e,t){if(!s[e]){if(!o[e]){var r="function"==typeof h&&h;if(!t&&r)return r(e,!0);if(c)return c(e,!0);var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[e]={exports:{}};o[e][0].call(a.exports,function(t){return l(o[e][1][t]||t)},a,a.exports,i,o,s,u)}return s[e].exports}for(var c="function"==typeof h&&h,t=0;t<u.length;t++)l(u[t]);return l}({1:[function(t,e,r){"use strict";var i="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",s=i.split("").reduce(function(t,e,r){return t[e]=r,t},{});e.exports={toAlphaCode:function(t){if(void 0!==i[t])return i[t];for(var e=1,r=36,n="";r<=t;t-=r,e++,r*=36);for(;e--;){var a=t%36;n=String.fromCharCode((a<10?48:55)+a)+n,t=(t-a)/36}return n},fromAlphaCode:function(t){if(void 0!==s[t])return s[t];for(var e=0,r=1,n=36,a=1;r<t.length;e+=n,r++,n*=36);for(var i=t.length-1;0<=i;i--,a*=36){var o=t.charCodeAt(i)-48;10<o&&(o-=7),e+=o*a}return e}}},{}],2:[function(t,e,r){"use strict";var o=t("./unpack");e.exports=function(t){var a=t.split("|").reduce(function(t,e){var r=e.split("¦");return t[r[0]]=r[1],t},{}),i={};return Object.keys(a).forEach(function(t){var e=o(a[t]);"true"===t&&(t=!0);for(var r=0;r<e.length;r++){var n=e[r];!0===i.hasOwnProperty(n)?!1===Array.isArray(i[n])?i[n]=[i[n],t]:i[n].push(t):i[n]=t}}),i}},{"./unpack":4}],3:[function(t,e,r){"use strict";var a=t("../encoding");e.exports=function(t){for(var e=new RegExp("([0-9A-Z]+):([0-9A-Z]+)"),r=0;r<t.nodes.length;r++){var n=e.exec(t.nodes[r]);if(!n){t.symCount=r;break}t.syms[a.fromAlphaCode(n[1])]=a.fromAlphaCode(n[2])}t.nodes=t.nodes.slice(t.symCount,t.nodes.length)}},{"../encoding":1}],4:[function(t,e,r){"use strict";var n=t("./symbols"),p=t("../encoding");e.exports=function(t){var m,d,e={nodes:t.split(";"),syms:[],symCount:0};return t.match(":")&&n(e),m=e,d=[],function t(e,r){var n,a,i,o,s=m.nodes[e];"!"===s[0]&&(d.push(r),s=s.slice(1));for(var u=s.split(/([A-Z0-9,]+)/g),l=0;l<u.length;l+=2){var c=u[l],h=u[l+1];if(c){var f=r+c;","!==h&&void 0!==h?t((n=m,a=h,i=e,(o=p.fromAlphaCode(a))<n.symCount?n.syms[o]:i+o+1-n.symCount),f):d.push(f)}}}(0,""),d}},{"../encoding":1,"./symbols":3}]},{},[2])(2)}),function(t){"object"==typeof n&&void 0!==r?r.exports=t():("undefined"!=typeof window?window:void 0!==e?e:"undefined"!=typeof self?self:this).unpack=t()}(function(){return function i(o,s,u){function l(e,t){if(!s[e]){if(!o[e]){var r="function"==typeof h&&h;if(!t&&r)return r(e,!0);if(c)return c(e,!0);var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[e]={exports:{}};o[e][0].call(a.exports,function(t){return l(o[e][1][t]||t)},a,a.exports,i,o,s,u)}return s[e].exports}for(var c="function"==typeof h&&h,t=0;t<u.length;t++)l(u[t]);return l}({1:[function(t,e,r){"use strict";var i="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",s=i.split("").reduce(function(t,e,r){return t[e]=r,t},{});e.exports={toAlphaCode:function(t){if(void 0!==i[t])return i[t];for(var e=1,r=36,n="";r<=t;t-=r,e++,r*=36);for(;e--;){var a=t%36;n=String.fromCharCode((a<10?48:55)+a)+n,t=(t-a)/36}return n},fromAlphaCode:function(t){if(void 0!==s[t])return s[t];for(var e=0,r=1,n=36,a=1;r<t.length;e+=n,r++,n*=36);for(var i=t.length-1;0<=i;i--,a*=36){var o=t.charCodeAt(i)-48;10<o&&(o-=7),e+=o*a}return e}}},{}],2:[function(t,e,r){"use strict";var o=t("./unpack");e.exports=function(t){var a=t.split("|").reduce(function(t,e){var r=e.split("¦");return t[r[0]]=r[1],t},{}),i={};return Object.keys(a).forEach(function(t){var e=o(a[t]);"true"===t&&(t=!0);for(var r=0;r<e.length;r++){var n=e[r];!0===i.hasOwnProperty(n)?!1===Array.isArray(i[n])?i[n]=[i[n],t]:i[n].push(t):i[n]=t}}),i}},{"./unpack":4}],3:[function(t,e,r){"use strict";var a=t("../encoding");e.exports=function(t){for(var e=new RegExp("([0-9A-Z]+):([0-9A-Z]+)"),r=0;r<t.nodes.length;r++){var n=e.exec(t.nodes[r]);if(!n){t.symCount=r;break}t.syms[a.fromAlphaCode(n[1])]=a.fromAlphaCode(n[2])}t.nodes=t.nodes.slice(t.symCount,t.nodes.length)}},{"../encoding":1}],4:[function(t,e,r){"use strict";var n=t("./symbols"),p=t("../encoding");e.exports=function(t){var m,d,e={nodes:t.split(";"),syms:[],symCount:0};return t.match(":")&&n(e),m=e,d=[],function t(e,r){var n,a,i,o,s=m.nodes[e];"!"===s[0]&&(d.push(r),s=s.slice(1));for(var u=s.split(/([A-Z0-9,]+)/g),l=0;l<u.length;l+=2){var c=u[l],h=u[l+1];if(c){var f=r+c;","!==h&&void 0!==h?t((n=m,a=h,i=e,(o=p.fromAlphaCode(a))<n.symCount?n.syms[o]:i+o+1-n.symCount),f):d.push(f)}}}(0,""),d}},{"../encoding":1,"./symbols":3}]},{},[2])(2)}),function(t){"object"==typeof n&&void 0!==r?r.exports=t():("undefined"!=typeof window?window:void 0!==e?e:"undefined"!=typeof self?self:this).unpack=t()}(function(){return function i(o,s,u){function l(e,t){if(!s[e]){if(!o[e]){var r="function"==typeof h&&h;if(!t&&r)return r(e,!0);if(c)return c(e,!0);var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[e]={exports:{}};o[e][0].call(a.exports,function(t){return l(o[e][1][t]||t)},a,a.exports,i,o,s,u)}return s[e].exports}for(var c="function"==typeof h&&h,t=0;t<u.length;t++)l(u[t]);return l}({1:[function(t,e,r){"use strict";var i="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",s=i.split("").reduce(function(t,e,r){return t[e]=r,t},{});e.exports={toAlphaCode:function(t){if(void 0!==i[t])return i[t];for(var e=1,r=36,n="";r<=t;t-=r,e++,r*=36);for(;e--;){var a=t%36;n=String.fromCharCode((a<10?48:55)+a)+n,t=(t-a)/36}return n},fromAlphaCode:function(t){if(void 0!==s[t])return s[t];for(var e=0,r=1,n=36,a=1;r<t.length;e+=n,r++,n*=36);for(var i=t.length-1;0<=i;i--,a*=36){var o=t.charCodeAt(i)-48;10<o&&(o-=7),e+=o*a}return e}}},{}],2:[function(t,e,r){"use strict";var o=t("./unpack");e.exports=function(t){var a=t.split("|").reduce(function(t,e){var r=e.split("¦");return t[r[0]]=r[1],t},{}),i={};return Object.keys(a).forEach(function(t){var e=o(a[t]);"true"===t&&(t=!0);for(var r=0;r<e.length;r++){var n=e[r];!0===i.hasOwnProperty(n)?!1===Array.isArray(i[n])?i[n]=[i[n],t]:i[n].push(t):i[n]=t}}),i}},{"./unpack":4}],3:[function(t,e,r){"use strict";var a=t("../encoding");e.exports=function(t){for(var e=new RegExp("([0-9A-Z]+):([0-9A-Z]+)"),r=0;r<t.nodes.length;r++){var n=e.exec(t.nodes[r]);if(!n){t.symCount=r;break}t.syms[a.fromAlphaCode(n[1])]=a.fromAlphaCode(n[2])}t.nodes=t.nodes.slice(t.symCount,t.nodes.length)}},{"../encoding":1}],4:[function(t,e,r){"use strict";var n=t("./symbols"),p=t("../encoding");e.exports=function(t){var m,d,e={nodes:t.split(";"),syms:[],symCount:0};return t.match(":")&&n(e),m=e,d=[],function t(e,r){var n,a,i,o,s=m.nodes[e];"!"===s[0]&&(d.push(r),s=s.slice(1));for(var u=s.split(/([A-Z0-9,]+)/g),l=0;l<u.length;l+=2){var c=u[l],h=u[l+1];if(c){var f=r+c;","!==h&&void 0!==h?t((n=m,a=h,i=e,(o=p.fromAlphaCode(a))<n.symCount?n.syms[o]:i+o+1-n.symCount),f):d.push(f)}}}(0,""),d}},{"../encoding":1,"./symbols":3}]},{},[2])(2)})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],2:[function(t,e,r){e.exports={author:"Spencer Kelly <spencermountain@gmail.com> (http://spencermounta.in)",name:"compromise",description:"natural language processing in the browser",version:"11.12.4",main:"./builds/compromise.js",types:"./compromise.d.ts",repository:{type:"git",url:"git://github.com/nlp-compromise/compromise.git"},scripts:{test:'tape "./test/unit/**/*.test.js" | tap-dancer',"test:spec":'tape "./test/unit/**/*.test.js" | tap-spec',testb:'TESTENV=prod tape "./test/unit/**/*.test.js" | tap-spec',buildTest:"TESTENV=prod node ./scripts/test.js","test:types":"tsc --project test/types",browserTest:"node ./scripts/browserTest.js",benchmark:"node ./scripts/benchmark.js",build:"node ./scripts/build/index.js",pack:"node ./scripts/pack.js",prepublishOnly:"node ./scripts/prepublish",postpublish:"node ./scripts/postpublish",watch:"amble ./scratch.js",filesize:"node ./scripts/lib/filesize.js",coverage:"node ./scripts/postpublish/coverage.js",lint:"node ./scripts/prepublish/linter.js"},files:["builds/","docs/","compromise.d.ts"],dependencies:{"efrt-unpack":"2.0.3"},devDependencies:{"@babel/core":"7.2.0","@babel/preset-env":"7.2.0",amble:"0.0.7",babelify:"10.0.0",babili:"0.1.4",browserify:"16.2.3",chalk:"2.4.1",codecov:"3.1.0","compromise-plugin":"0.0.8",derequire:"2.0.6",eslint:"5.9.0",nyc:"13.1.0",shelljs:"0.8.3","tap-dancer":"0.1.2","tap-spec":"5.0.0",tape:"4.9.1","uglify-js":"3.4.9"},license:"MIT"}},{}],3:[function(t,e,a){"use strict";function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var i=t("./tags"),o={reset:"[0m",red:"[31m",green:"[32m",yellow:"[33m",blue:"[34m",magenta:"[35m",cyan:"[36m",black:"[30m"};void 0===e&&Object.keys(o).forEach(function(t){o[t]=""}),a.ensureString=function(t){return"string"==typeof t?t:"number"==typeof t?String(t):""},a.ensureObject=function(t){return"object"!==r(t)?{}:null===t||t instanceof Array?{}:t},a.titleCase=function(t){return t.charAt(0).toUpperCase()+t.substr(1)},a.copy=function(e){var r={};return e=a.ensureObject(e),Object.keys(e).forEach(function(t){r[t]=e[t]}),r},a.extend=function(t,e){t=a.copy(t);for(var r=Object.keys(e),n=0;n<r.length;n++)t[r[n]]=e[r[n]];return t},a.green=function(t){return o.green+t+o.reset},a.red=function(t){return o.red+t+o.reset},a.blue=function(t){return o.blue+t+o.reset},a.magenta=function(t){return o.magenta+t+o.reset},a.cyan=function(t){return o.cyan+t+o.reset},a.yellow=function(t){return o.yellow+t+o.reset},a.black=function(t){return o.black+t+o.reset},a.printTag=function(t){if(i[t]){var e=i[t].color||"blue";return a[e](t)}return t},a.printTerm=function(t){for(var e=Object.keys(t.tags),r=0;r<e.length;r++)if(i[e[r]]){var n=i[e[r]].color||"black";return a[n](t.out("text"))}return o.reset+t.plaintext+o.reset},a.leftPad=function(t,e,r){for(r=r||" ",t=t.toString();t.length<e;)t+=r;return t},a.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)},a.isObject=function(t){return t===Object(t)}},{"./tags":137}],4:[function(u,l,t){(function(t){"use strict";var a=u("./text/build"),e=u("../package.json"),r=u("./log"),n=u("./world/unpack"),i=u("./world"),o=i.w,s=function(t,e){e&&o.plugin({words:e});var r=a(t,o);return r.tagger(),r};s.unpack=function(t){return n(t)},s.version=e.version,s.verbose=function(t){r.enable(t)},s.tokenize=function(t){return a(t)},s.plugin=function(t){o.plugin(t)},s.addWords=function(t){o.plugin({words:t})},s.addTags=function(t){o.plugin({tags:t})},s.addRegex=function(t){o.plugin({regex:t})},s.addPatterns=function(t){o.plugin({patterns:t})},s.addPlurals=function(t){o.plugin({plurals:t})},s.addConjugations=function(t){o.plugin({conjugations:t})},s.clone=function(){var n=i.reBuild(),t=function(t,e){e&&n.plugin({words:e});var r=a(t,n);return r.tagger(),r};return t.tokenize=s.tokenize,t.verbose=s.verbose,t.version=s.version,["Words","Tags","Regex","Patterns","Plurals","Conjugations"].forEach(function(e){t["add"+e]=function(t){n["add"+e](t)}}),t},"undefined"!=typeof self?self.nlp=s:"undefined"!=typeof window?window.nlp=s:void 0!==t&&(t.nlp=s),void 0!==l&&(l.exports=s)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../package.json":2,"./log":6,"./text/build":190,"./world":215,"./world/unpack":223}],5:[function(t,e,r){"use strict";var a=t("../fns");e.exports={tag:function(t,e,r){var n=t.normal||"["+t.silent_term+"]";n=a.leftPad("'"+n+"'",12),n+=" -> "+e,n+=a.leftPad(r||"",15),console.log("%c"+n," color: #a2c99c")},untag:function(t,e,r){var n=t.normal||"["+t.silent_term+"]";n=a.leftPad("'"+n+"'",12),n+=" ~* "+e,n+=" "+(r||""),console.log("%c"+n," color: #b66a6a")}}},{"../fns":3}],6:[function(t,e,r){"use strict";var n=t("./client"),a=t("./server"),i=!1;e.exports={enable:function(t){void 0===t&&(t=!0),i=t},tag:function(t,e,r){!0!==i&&"tagger"!==i||("undefined"!=typeof window?n.tag(t,e,r):a.tag(t,e,r))},unTag:function(t,e,r){!0!==i&&"tagger"!==i||("undefined"!=typeof window?n.untag(t,e,r):a.untag(t,e,r))}}},{"./client":5,"./server":7}],7:[function(t,e,r){"use strict";var a=t("../fns");e.exports={tag:function(t,e,r){var n=t.normal||"["+t.silent_term+"]";n=a.yellow(n),n=a.leftPad("'"+n+"'",20),n+=" -> "+a.printTag(e),n=a.leftPad(n,54),console.log(" "+n+"("+a.cyan(r||"")+")")},untag:function(t,e,r){var n="-"+t.normal+"-";n=a.red(n),n=a.leftPad(n,20),n+=" ~* "+a.red(e),n=a.leftPad(n,54),console.log(" "+n+"("+a.red(r||"")+")")}}},{"../fns":3}],8:[function(t,e,r){"use strict";e.exports={fns:t("./fns"),Terms:t("./terms")}},{"./fns":3,"./terms":165}],9:[function(t,e,r){"use strict";var n=t("../../text");e.exports=n.makeSubset({stripPeriods:function(){return this.list.forEach(function(t){t.terms.forEach(function(t){var e=t._text.split(".");2<e.length&&(t.text=e.join(""))})}),this},addPeriods:function(){return this.list.forEach(function(t){t.terms.forEach(function(t){if(2<t._text.split(".").length){var e=t._text.replace(/\./g,"");t.text=e.split("").join(".")+"."}})}),this},data:function(){return this.terms().list.map(function(t){var e=t.terms[0],r=e.text.toUpperCase().replace(/\./g,"").split("");return{periods:r.join("."),normal:r.join(""),text:e.text}})}},function(t,e){return t=t.match("#Acronym"),"number"==typeof e&&(t=t.get(e)),t})},{"../../text":192}],10:[function(t,e,r){"use strict";var n=t("../../text"),o=t("./methods"),a={data:function(){var i=this;return this.list.map(function(t){var e,r,n=t.out("normal"),a={normal:n,text:i.out("text"),comparative:"more "+n,superlative:"most "+n,adverbForm:null,nounForm:null};return 1==(e=n,r=i.world().words,!(!e||e.length<=3)&&("Comparable"===r[e]||"Adjective"!==r[e]&&-1===e.indexOf(" ")))&&(a.comparative=o.toComparative(n)||a.comparative,a.superlative=o.toSuperlative(n)||a.superlative,a.adverbForm=o.toAdverb(n),a.nounForm=o.toNoun(n)),a})}};e.exports=n.makeSubset(a,function(t,e){return t=t.match("#Adjective"),"number"==typeof e&&(t=t.get(e)),t})},{"../../text":192,"./methods":11}],11:[function(t,e,r){"use strict";e.exports={toNoun:t("./toNoun"),toSuperlative:t("./toSuperlative"),toComparative:t("./toComparative"),toAdverb:t("./toAdverb"),toVerb:t("./toVerb")}},{"./toAdverb":12,"./toComparative":13,"./toNoun":14,"./toSuperlative":15,"./toVerb":16}],12:[function(t,e,r){"use strict";var n=[/airs$/,/ll$/,/ee.$/,/ile$/,/y$/],a=t("../../../world/more-data/irregularAdjectives").toAdverb,i=[{reg:/al$/i,repl:"ally"},{reg:/ly$/i,repl:"ly"},{reg:/(.{3})y$/i,repl:"$1ily"},{reg:/que$/i,repl:"quely"},{reg:/ue$/i,repl:"uly"},{reg:/ic$/i,repl:"ically"},{reg:/ble$/i,repl:"bly"},{reg:/l$/i,repl:"ly"}];e.exports=function(t){if(!0===a.hasOwnProperty(t))return a[t];for(var e=0;e<n.length;e++)if(!0===n[e].test(t))return null;for(var r=0;r<i.length;r++)if(!0===i[r].reg.test(t))return t.replace(i[r].reg,i[r].repl);return t+"ly"}},{"../../../world/more-data/irregularAdjectives":218}],13:[function(t,e,r){"use strict";var a=[/ght$/,/nge$/,/ough$/,/ain$/,/uel$/,/[au]ll$/,/ow$/,/old$/,/oud$/,/e[ae]p$/],i=[/ary$/,/ous$/],o=t("../../../world/more-data/irregularAdjectives").toComparative,s=[{reg:/y$/i,repl:"ier"},{reg:/([aeiou])t$/i,repl:"$1tter"},{reg:/([aeou])de$/i,repl:"$1der"},{reg:/nge$/i,repl:"nger"}];e.exports=function(t){if(o.hasOwnProperty(t))return o[t];for(var e=0;e<s.length;e++)if(!0===s[e].reg.test(t))return t.replace(s[e].reg,s[e].repl);for(var r=0;r<i.length;r++)if(!0===i[r].test(t))return null;for(var n=0;n<a.length;n++)if(!0===a[n].test(t))return t+"er";return!0===/e$/.test(t)?t+"r":t+"er"}},{"../../../world/more-data/irregularAdjectives":218}],14:[function(t,e,r){"use strict";var n={clean:"cleanliness",naivety:"naivety",hurt:"hurt"},a=[{reg:/y$/,repl:"iness"},{reg:/le$/,repl:"ility"},{reg:/ial$/,repl:"y"},{reg:/al$/,repl:"ality"},{reg:/ting$/,repl:"ting"},{reg:/ring$/,repl:"ring"},{reg:/bing$/,repl:"bingness"},{reg:/sing$/,repl:"se"},{reg:/ing$/,repl:"ment"},{reg:/ess$/,repl:"essness"},{reg:/ous$/,repl:"ousness"}];e.exports=function(t){if(n.hasOwnProperty(t))return n[t];var e=t.charAt(t.length-1);if("w"===e||"s"===e)return null;for(var r=0;r<a.length;r++)if(!0===a[r].reg.test(t))return t.replace(a[r].reg,a[r].repl);return t+"ness"}},{}],15:[function(t,e,r){"use strict";var a=[/ght$/,/nge$/,/ough$/,/ain$/,/uel$/,/[au]ll$/,/ow$/,/oud$/,/...p$/],i=[/ary$/],o=t("../../../world/more-data/irregularAdjectives").toSuperlative,s=[{reg:/y$/i,repl:"iest"},{reg:/([aeiou])t$/i,repl:"$1ttest"},{reg:/([aeou])de$/i,repl:"$1dest"},{reg:/nge$/i,repl:"ngest"},{reg:/([aeiou])te$/i,repl:"$1test"}];e.exports=function(t){if(o.hasOwnProperty(t))return o[t];for(var e=0;e<s.length;e++)if(s[e].reg.test(t))return t.replace(s[e].reg,s[e].repl);for(var r=0;r<i.length;r++)if(!0===i[r].test(t))return null;for(var n=0;n<a.length;n++)if(!0===a[n].test(t))return"e"===t.charAt(t.length-1)?t+"st":t+"est";return t+"est"}},{"../../../world/more-data/irregularAdjectives":218}],16:[function(t,e,r){"use strict";var n={red:"redden",sad:"sadden",fat:"fatten"};e.exports=function(t){return!0===n.hasOwnProperty(t)?n[t]:!0===/e$/.test(t)?t+"n":t+"en"}},{}],17:[function(t,e,r){"use strict";var n=t("../../text"),a=t("./toAdjective"),i={data:function(){return this.terms().list.map(function(t){var e=t.terms[0];return{adjectiveForm:a(e.normal),normal:e.normal,text:e.text}})}};e.exports=n.makeSubset(i,function(t,e){return t=(t=t.splitAfter("#Comma")).match("#Adverb+"),"number"==typeof e&&(t=t.get(e)),t})},{"../../text":192,"./toAdjective":18}],18:[function(t,e,r){"use strict";var n={idly:"idle",sporadically:"sporadic",basically:"basic",grammatically:"grammatical",alphabetically:"alphabetical",economically:"economical",conically:"conical",politically:"political",vertically:"vertical",practically:"practical",theoretically:"theoretical",critically:"critical",fantastically:"fantastic",mystically:"mystical",pornographically:"pornographic",fully:"full",jolly:"jolly",wholly:"whole"},a=[{reg:/bly$/i,repl:"ble"},{reg:/gically$/i,repl:"gical"},{reg:/([rsdh])ically$/i,repl:"$1ical"},{reg:/ically$/i,repl:"ic"},{reg:/uly$/i,repl:"ue"},{reg:/ily$/i,repl:"y"},{reg:/(.{3})ly$/i,repl:"$1"}];e.exports=function(t){if(n.hasOwnProperty(t))return n[t];for(var e=0;e<a.length;e++)if(!0===a[e].reg.test(t))return t.replace(a[e].reg,a[e].repl);return t}},{}],19:[function(t,e,r){"use strict";var n=function(t,e){e.whitespace.after=t.whitespace.after,t.whitespace.after="",e.whitespace.before="",t.silent_term=t.text,e.silent_term=e.text,e.text="",t.tag("Contraction","new-contraction"),e.tag("Contraction","new-contraction")},a={can:"can't",will:"won't"};e.exports=function(t){return!1===t.expanded||t.match("#Contraction").found||(t.match("(#Noun|#QuestionWord) is").list.forEach(function(t){n(t.terms[0],t.terms[1]),t.terms[0].text+="'s",t.contracted=!0}),t.match("#PronNoun did").list.forEach(function(t){n(t.terms[0],t.terms[1]),t.terms[0].text+="'d",t.contracted=!0}),t.match("#QuestionWord (did|do)").list.forEach(function(t){n(t.terms[0],t.terms[1]),t.terms[0].text+="'d",t.contracted=!0}),t.match("#Noun (could|would)").list.forEach(function(t){n(t.terms[0],t.terms[1]),t.terms[0].text+="'d",t.contracted=!0}),t.match("(they|we|you) are").list.forEach(function(t){n(t.terms[0],t.terms[1]),t.terms[0].text+="'re",t.contracted=!0}),t.match("i am").list.forEach(function(t){n(t.terms[0],t.terms[1]),t.terms[0].text+="'m",t.contracted=!0}),t.match("(#Noun|#QuestionWord) will").list.forEach(function(t){n(t.terms[0],t.terms[1]),t.terms[0].text+="'ll",t.contracted=!0}),t.match("(they|we|you|i) have").list.forEach(function(t){n(t.terms[0],t.terms[1]),t.terms[0].text+="'ve",t.contracted=!0}),t.match("(#Copula|#Modal|do|does|have|has|can|will) not").list.forEach(function(t){n(t.terms[0],t.terms[1]),!0===a.hasOwnProperty(t.terms[0].text)?t.terms[0].text=a[t.terms[0].text]:t.terms[0].text+="n't",t.contracted=!0})),t}},{}],20:[function(t,e,r){"use strict";var n=t("../../paths").Terms,a=t("./contract"),i=t("./expand"),o=function(t,e,r){n.call(this,t,e,r)};(o.prototype=Object.create(n.prototype)).data=function(){var t=i(this.clone()),e=a(this.clone());return{text:this.out("text"),normal:this.out("normal"),expanded:{normal:t.out("normal"),text:t.out("text")},contracted:{normal:e.out("normal"),text:e.out("text")},isContracted:Boolean(this.contracted)}},o.prototype.expand=function(){return i(this)},o.prototype.contract=function(){return a(this)},e.exports=o},{"../../paths":8,"./contract":19,"./expand":21}],21:[function(t,e,r){"use strict";e.exports=function(t){return!1===t.contracted||t.terms.forEach(function(t){t.silent_term&&(t.text||(t.whitespace.before=" "),t._text=t.silent_term,t.tags.TitleCase&&t.toTitleCase(),t.normalize(),t.silent_term=null,t.unTag("Contraction","expanded"))}),t}},{}],22:[function(t,e,r){"use strict";e.exports=function(t){var e=t.not("#Contraction"),r=e.match("(#Noun|#QuestionWord) (#Copula|did|do|have|had|could|would|will)");return r.concat(e.match("(they|we|you|i) have")),r.concat(e.match("i am")),r.concat(e.match("(#Copula|#Modal|do|does|have|has|can|will) not")),r.list.forEach(function(t){t.expanded=!0}),r}},{}],23:[function(t,e,r){"use strict";var n=t("../../text"),a=t("./contraction"),i=t("./findPossible");e.exports=n.makeSubset({contract:function(){return this.list.forEach(function(t){return t.contract()}),this},expand:function(){return this.list.forEach(function(t){return t.expand()}),this},contracted:function(){return this.list=this.list.filter(function(t){return t.contracted}),this},expanded:function(){return this.list=this.list.filter(function(t){return!t.contracted}),this}},function(t,e){var r=t.match("#Contraction #Contraction #Contraction?");return r.list=r.list.map(function(t){var e=new a(t.terms,t.world,t.refText,t.refTerms);return e.contracted=!0,e}),i(t).list.forEach(function(t){var e=new a(t.terms,t.world,t.refText,t.refTerms);e.contracted=!1,r.list.push(e)}),r.sort("chronological"),"number"==typeof e&&(r=r.get(e)),r})},{"../../text":192,"./contraction":20,"./findPossible":22}],24:[function(t,e,r){"use strict";var n=t("../../paths").Terms,a=t("./parseDate"),i=function(t,e,r){n.call(this,t,e,r),this.month=this.match("#Month")};(i.prototype=Object.create(n.prototype)).data=function(){return{text:this.out("text"),normal:this.out("normal"),date:a(this)}},e.exports=i},{"../../paths":8,"./parseDate":28}],25:[function(t,e,r){"use strict";var n=t("../../text"),a=t("./date"),i=t("./weekday"),o=t("./month"),s={toShortForm:function(){return this.match("#Month").terms().list.forEach(function(t){var e=t.terms[0];o.toShortForm(e)}),this.match("#WeekDay").terms().list.forEach(function(t){var e=t.terms[0];i.toShortForm(e)}),this},toLongForm:function(){return this.match("#Month").terms().list.forEach(function(t){var e=t.terms[0];o.toLongForm(e)}),this.match("#WeekDay").terms().list.forEach(function(t){var e=t.terms[0];i.toLongForm(e)}),this}};e.exports=n.makeSubset(s,function(t,e){var r=t.match("#Date+");return"number"==typeof e&&(r=r.get(e)),r.list=r.list.map(function(t){return new a(t.terms,t.world,t.refText,t.refTerms)}),r})},{"../../text":192,"./date":24,"./month":27,"./weekday":31}],26:[function(t,e,r){"use strict";r.longMonths={january:0,february:1,march:2,april:3,may:4,june:5,july:6,august:7,september:8,october:9,november:10,december:11},r.shortMonths={jan:0,feb:1,mar:2,apr:3,may:4,jun:5,jul:6,aug:7,sep:8,oct:9,nov:10,dec:11,febr:1,sept:8}},{}],27:[function(t,e,r){"use strict";var n=t("./data"),a=n.shortMonths,i=n.longMonths,o=function(t){return t.charAt(0).toUpperCase()+t.substr(1)};e.exports={index:function(t){if(t.tags.Month){if(void 0!==i[t.normal])return i[t.normal];if(void 0!==a[t.normal])return a[t.normal]}return null},toShortForm:function(t){if(void 0!==t.tags.Month&&void 0!==i[t.normal]){var e=Object.keys(a),r=t.getPunctuation()||"";t.text=e[i[t.normal]]+r,t.tags.TitleCase&&(t.text=o(t.text))}return t.dirty=!0,t},toLongForm:function(t){if(void 0!==t.tags.Month&&void 0!==a[t.normal]){var e=Object.keys(i),r=t.getPunctuation()||"";t.text=e[a[t.normal]]+r,t.tags.TitleCase&&(t.text=o(t.text))}return t.dirty=!0,t}}},{"./data":26}],28:[function(t,e,r){"use strict";var u=t("./parseTime"),l=t("./weekday"),c=t("./month"),h=function(t){return!!(t&&t<31&&0<t)},f=function(t){return!!(t&&1e3<t&&t<3e3)};e.exports=function(t){var e={month:null,date:null,weekday:null,year:null,named:null,time:null},r=t.match("(#Holiday|today|tomorrow|yesterday)");if(r.found&&(e.named=r.out("normal")),(r=t.match("#Month")).found&&(e.month=c.index(r.list[0].terms[0])),(r=t.match("#WeekDay")).found&&(e.weekday=l.index(r.list[0].terms[0])),(r=t.match("#Time")).found&&(e.time=u(t),t.not("#Time")),(r=t.match("#Month #Value #Year")).found){var n=r.values().numbers();h(n[0])&&(e.date=n[0]);var a=parseInt(t.match("#Year").out("normal"),10);f(a)&&(e.year=a)}if(!r.found){if((r=t.match("#Month #Value")).found){var i=r.values().numbers()[0];h(i)&&(e.date=i)}if((r=t.match("#Month #Year")).found){var o=parseInt(t.match("#Year").out("normal"),10);f(o)&&(e.year=o)}}if((r=t.match("#Value of #Month")).found){var s=r.values().numbers()[0];h(s)&&(e.date=s)}return e}},{"./month":27,"./parseTime":29,"./weekday":31}],29:[function(t,e,r){"use strict";var i=/([12]?[0-9]) ?(am|pm)/i,o=/([12]?[0-9]):([0-9][0-9]) ?(am|pm)?/i,s=function(t){return!!(t&&0<t&&t<25)};e.exports=function(t){var a={logic:null,hour:null,minute:null,second:null,timezone:null},e=t.match("(by|before|for|during|at|until|after) #Time").firstTerm();return e.found&&(a.logic=e.out("normal")),t.match("#Time").terms().list.forEach(function(t){var e,r=t.terms[0],n=r.text.match(i);null!==n&&(a.hour=parseInt(n[1],10),"pm"===n[2]&&(a.hour+=12),!1===s(a.hour)&&(a.hour=null)),null!==(n=r.text.match(o))&&(a.hour=parseInt(n[1],10),a.minute=parseInt(n[2],10),(e=a.minute)&&0<e&&e<60||(a.minute=null),"pm"===n[3]&&(a.hour+=12),!1===s(a.hour)&&(a.hour=null))}),a}},{}],30:[function(t,e,r){"use strict";r.longDays={sunday:0,monday:1,tuesday:2,wednesday:3,thursday:4,friday:5,saturday:6},r.shortDays={sun:0,mon:1,tues:2,wed:3,weds:3,thurs:4,fri:5,sat:6}},{}],31:[function(t,e,r){"use strict";var n=t("./data"),a=n.shortDays,i=n.longDays;e.exports={index:function(t){if(t.tags.WeekDay){if(void 0!==i[t.normal])return i[t.normal];if(void 0!==a[t.normal])return a[t.normal]}return null},toShortForm:function(t){if(t.tags.WeekDay&&void 0!==i[t.normal]){var e=Object.keys(a);t.text=e[i[t.normal]]}return t},toLongForm:function(t){if(t.tags.WeekDay&&void 0!==a[t.normal]){var e=Object.keys(i);t.text=e[a[t.normal]]}return t}}},{"./data":30}],32:[function(t,e,r){"use strict";var n=t("./index"),i=t("./getGrams"),o=function(t,e,r){n.call(this,t,e,r)};o.prototype=Object.create(n.prototype),o.find=function(t,e,r){var n={size:[1,2,3,4],edge:"end"};r&&(n.size=[r]);var a=i(t,n);return(t=new o(a)).sort(),"number"==typeof e&&(t=t.get(e)),t},e.exports=o},{"./getGrams":33,"./index":35}],33:[function(t,e,r){"use strict";var u=t("./gram"),l=function(t){return t.terms.filter(function(t){return""!==t._text})};e.exports=function(t,i){(i=i||{}).size=i.size||[1,2,3],"number"==typeof i.size&&(i.size=[i.size]);var s={};return i.size.forEach(function(a){t.list.forEach(function(o){var t,e,r,n;("start"===i.edge?(r=a,(n=l(o)).length<r?[]:[new u(n.slice(0,r))]):"end"===i.edge?(t=a,(e=l(o)).length<t?[]:[new u(e.slice(e.length-t,e.length))]):function(t,e){var r=l(o);if(r.length<e)return[];for(var n=[],a=0;a<r.length-e+1;a++){var i=new u(r.slice(a,a+e));n.push(i)}return n}(0,a)).forEach(function(t){s.hasOwnProperty(t.key)?s[t.key].inc():s[t.key]=t})})}),Object.keys(s).map(function(t){return s[t]})}},{"./gram":34}],34:[function(t,e,r){"use strict";var n=t("../../paths").Terms,a=function(t,e,r){n.call(this,t,e,r),this.key=this.out("normal"),this.size=t.length,this.count=1};(a.prototype=Object.create(n.prototype)).inc=function(){this.count+=1},e.exports=a},{"../../paths":8}],35:[function(t,e,r){"use strict";var o=t("../../text"),s=t("./getGrams"),u=function(t){return t.list=t.list.sort(function(t,e){return t.count>e.count?-1:t.count===e.count&&(t.size>e.size||t.key.length>e.key.length)?-1:1}),t},n={data:function(){return this.list.map(function(t){return{normal:t.out("normal"),count:t.count,size:t.size}})},unigrams:function(){return this.list=this.list.filter(function(t){return 1===t.size}),this},bigrams:function(){return this.list=this.list.filter(function(t){return 2===t.size}),this},trigrams:function(){return this.list=this.list.filter(function(t){return 3===t.size}),this},sort:function(){return u(this)}};e.exports=o.makeSubset(n,function(t,e){var r=[];"number"==typeof e&&(e={n:e});for(var n=(e=e||{}).max||4,a=1;a<=n;a++)r.push(a);e.size&&(r=[e.size]);var i=s(t,{size:r});return t=new o(i),t=u(t),void 0!==e.n&&(t=t.get(e.n)),t})},{"../../text":192,"./getGrams":33}],36:[function(t,e,r){"use strict";var n=t("./index"),i=t("./getGrams"),o=function(t,e,r){n.call(this,t,e,r)};o.prototype=Object.create(n.prototype),o.find=function(t,e,r){var n={size:[1,2,3,4],edge:"start"};r&&(n.size=[r]);var a=i(t,n);return(t=new o(a)).sort(),"number"==typeof e&&(t=t.get(e)),t},e.exports=o},{"./getGrams":33,"./index":35}],37:[function(t,e,r){"use strict";e.exports=function(t){if(!t.tags.Noun)return!1;if(t.tags.Plural)return!0;for(var e=["Pronoun","Place","Value","Person","Month","WeekDay","RelativeDay","Holiday"],r=0;r<e.length;r++)if(t.tags[e[r]])return!1;return!0!==t.tags.Uncountable}},{}],38:[function(t,e,r){"use strict";var n=t("../../text"),a=t("./noun");e.exports=n.makeSubset({isPlural:function(){return this.list=this.list.filter(function(t){return t.isPlural()}),this},hasPlural:function(){return this.list.map(function(t){return t.hasPlural()})},toPlural:function(){return this.list.forEach(function(t){return t.toPlural()}),this},toSingular:function(e){return this.list.forEach(function(t){return t.toSingular(e)}),this},toPossessive:function(e){return this.list.forEach(function(t){return t.toPossessive(e)}),this},articles:function(){return this.list.map(function(t){return{text:t.out("text"),normal:t.out("normal"),article:t.article()}})}},function(t,e){return t=(t=(t=(t=(t=(t=(t=t.clauses()).match("#Noun+ (of|by)? the? #Noun+?")).not("#Pronoun")).not("(there|these)")).not("(#Month|#WeekDay)")).not("(my|our|your|their|her|his)")).not("(of|for|by|the)$"),"number"==typeof e&&(t=t.get(e)),t.list=t.list.map(function(t){return new a(t.terms,t.world,t.refText,t.refTerms)}),t})},{"../../text":192,"./noun":46}],39:[function(t,e,r){"use strict";var o=t("./methods/data/indicators"),s=/([a-z]*) (of|in|by|for) [a-z]/,u=t("./hasPlural"),l={i:!1,he:!1,she:!1,we:!0,they:!0},c=["Place","Value","Person","Month","WeekDay","RelativeDay","Holiday","Possessive"];e.exports=function(t,e){if(t.tags.Plural)return!0;if(t.tags.Singular)return!1;var r=t.normal;if(!0===l.hasOwnProperty(r))return l[r];if(e.plurals&&!0===e.plurals.hasOwnProperty(r))return!1;if(e.cache.toSingular&&!0===e.cache.toSingular.hasOwnProperty(r))return!0;if(!1===function(t){if(!1===u(t))return!1;for(var e=0;e<c.length;e++)if(t.tags[c[e]])return!1;return!0}(t))return null;var n=r.match(s);null!==n&&(r=n[1]);for(var a=0;a<o.plural_indicators.length;a++)if(!0===o.plural_indicators[a].test(r))return!0;for(var i=0;i<o.singular_indicators.length;i++)if(!0===o.singular_indicators[i].test(r))return!1;return!0===/s$/.test(r)&&!1===/ss$/.test(r)&&3<r.length}},{"./hasPlural":37,"./methods/data/indicators":41}],40:[function(t,e,r){"use strict";var a={hour:"an",heir:"an",heirloom:"an",honest:"an",honour:"an",honor:"an",uber:"an"},i={a:!0,e:!0,f:!0,h:!0,i:!0,l:!0,m:!0,n:!0,o:!0,r:!0,s:!0,x:!0},o=[/^onc?e/i,/^u[bcfhjkqrstn][aeiou]/i,/^eul/i];e.exports=function(t){var e=t.normal;if(t.tags.Person)return"";if(t.tags.Plural)return"the";if(a.hasOwnProperty(e))return a[e];var r=e.substr(0,1);if(t.isAcronym()&&i.hasOwnProperty(r))return"an";for(var n=0;n<o.length;n++)if(o[n].test(e))return"a";return/^[aeiou]/i.test(e)?"an":"a"}},{}],41:[function(t,e,r){"use strict";e.exports={singular_indicators:[/(ax|test)is$/i,/(octop|vir|radi|nucle|fung|cact|stimul)us$/i,/(octop|vir)i$/i,/(rl)f$/i,/(alias|status)$/i,/(bu)s$/i,/(al|ad|at|er|et|ed|ad)o$/i,/(ti)um$/i,/(ti)a$/i,/sis$/i,/(?:(^f)fe|(lr)f)$/i,/hive$/i,/(^aeiouy|qu)y$/i,/(x|ch|ss|sh|z)$/i,/(matr|vert|ind|cort)(ix|ex)$/i,/(m|l)ouse$/i,/(m|l)ice$/i,/(antenn|formul|nebul|vertebr|vit)a$/i,/.sis$/i,/^(?!talis|.*hu)(.*)man$/i],plural_indicators:[/(^v)ies$/i,/ises$/i,/ives$/i,/(antenn|formul|nebul|vertebr|vit)ae$/i,/(octop|vir|radi|nucle|fung|cact|stimul)i$/i,/(buffal|tomat|tornad)oes$/i,/(analy|ba|diagno|parenthe|progno|synop|the)ses$/i,/(vert|ind|cort)ices$/i,/(matr|append)ices$/i,/(x|ch|ss|sh|s|z|o)es$/i,/men$/i,/news$/i,/.tia$/i,/(^f)ves$/i,/(lr)ves$/i,/(^aeiouy|qu)ies$/i,/(m|l)ice$/i,/(cris|ax|test)es$/i,/(alias|status)es$/i,/ics$/i]}},{}],42:[function(t,e,r){"use strict";e.exports=[[/(ax|test)is$/i,"$1es"],[/(octop|vir|radi|nucle|fung|cact|stimul)us$/i,"$1i"],[/(octop|vir)i$/i,"$1i"],[/(kn|l|w)ife$/i,"$1ives"],[/^((?:ca|e|ha|(?:our|them|your)?se|she|wo)l|lea|loa|shea|thie)f$/i,"$1ves"],[/^(dwar|handkerchie|hoo|scar|whar)f$/i,"$1ves"],[/(alias|status)$/i,"$1es"],[/(bu)s$/i,"$1ses"],[/(al|ad|at|er|et|ed|ad)o$/i,"$1oes"],[/([ti])um$/i,"$1a"],[/([ti])a$/i,"$1a"],[/sis$/i,"ses"],[/(hive)$/i,"$1s"],[/([^aeiouy]|qu)y$/i,"$1ies"],[/(x|ch|ss|sh|s|z)$/i,"$1es"],[/(matr|vert|ind|cort)(ix|ex)$/i,"$1ices"],[/([m|l])ouse$/i,"$1ice"],[/([m|l])ice$/i,"$1ice"],[/^(ox)$/i,"$1en"],[/^(oxen)$/i,"$1"],[/(quiz)$/i,"$1zes"],[/(antenn|formul|nebul|vertebr|vit)a$/i,"$1ae"],[/(sis)$/i,"ses"],[/^(?!talis|.*hu)(.*)man$/i,"$1men"],[/(.*)/i,"$1s"]].map(function(t){return{reg:t[0],repl:t[1]}})},{}],43:[function(t,e,r){"use strict";e.exports=[[/([^v])ies$/i,"$1y"],[/ises$/i,"isis"],[/(kn|[^o]l|w)ives$/i,"$1ife"],[/^((?:ca|e|ha|(?:our|them|your)?se|she|wo)l|lea|loa|shea|thie)ves$/i,"$1f"],[/^(dwar|handkerchie|hoo|scar|whar)ves$/i,"$1f"],[/(antenn|formul|nebul|vertebr|vit)ae$/i,"$1a"],[/(octop|vir|radi|nucle|fung|cact|stimul)(i)$/i,"$1us"],[/(buffal|tomat|tornad)(oes)$/i,"$1o"],[/(..[aeiou]s)es$/i,"$1"],[/(vert|ind|cort)(ices)$/i,"$1ex"],[/(matr|append)(ices)$/i,"$1ix"],[/(x|ch|ss|sh|z|o)es$/i,"$1"],[/men$/i,"man"],[/(n)ews$/i,"$1ews"],[/([ti])a$/i,"$1um"],[/([^aeiouy]|qu)ies$/i,"$1y"],[/(s)eries$/i,"$1eries"],[/(m)ovies$/i,"$1ovie"],[/([m|l])ice$/i,"$1ouse"],[/(cris|ax|test)es$/i,"$1is"],[/(alias|status)es$/i,"$1"],[/(ss)$/i,"$1"],[/(ics)$/i,"$1"],[/s$/i,""]].map(function(t){return{reg:t[0],repl:t[1]}})},{}],44:[function(t,e,r){"use strict";var a=t("./data/pluralRules");e.exports=function(t,e){var r=e.plurals||{};if(!0===r.hasOwnProperty(t))return r[t];for(var n=0;n<a.length;n++)if(!0===a[n].reg.test(t))return t.replace(a[n].reg,a[n].repl);return null}},{"./data/pluralRules":42}],45:[function(t,e,r){"use strict";var u=t("./data/singleRules");e.exports=function t(e,r){var n=r.cache.toSingular||{};if(!0===n.hasOwnProperty(e))return n[e];if(r&&r.plurals)for(var a=Object.keys(r.plurals),i=0;i<a.length;i++)if(r.plurals[a[i]]===e)return a[i];if(!0===/([a-z]*) (of|in|by|for) [a-z]/.test(e)){var o=(e.match(/^([a-z]*) (of|in|by|for) [a-z]/)||[])[1];if(o)return t(o)+e.replace(o,"")}for(var s=0;s<u.length;s++)if(!0===u[s].reg.test(e))return e.replace(u[s].reg,u[s].repl);return null}},{"./data/singleRules":43}],46:[function(t,e,r){"use strict";var n=t("../../paths").Terms,a=t("./hasPlural"),i=t("./isPlural"),o=t("./toPossessive"),s=t("./makeArticle"),u=t("./methods/pluralize"),l=t("./methods/singularize"),c={article:function(){return s(this.main)},isPlural:function(){return i(this.main,this.world)},hasPlural:function(){return a(this.main)},toPlural:function(t){var e=this.main;return a(e)&&!i(e,this.world)&&(e.text=u(e.normal,this.world,t)||e.text,e.unTag("Singular","toPlural"),e.tag("Plural","toPlural")),this},toSingular:function(t){var e=this.main;return i(e,this.world)&&(e.text=l(e.normal,this.world,t)||e.text,e.unTag("Plural","toSingular"),e.tag("Singular","toSingular")),this},toPossessive:function(){var t=this.main;return t.tags.Possessive||(t=o(t)),this},data:function(){var t=this.main,e=t.text;i(t,this.world)&&(e=l(t.normal,this.world)||t.text);var r=t.text;a(t)&&!i(t,this.world)&&(r=u(t.normal,this.world)||t.text);var n="";return this.qualifier&&(e+=" "+(n=this.qualifier.out("normal")),r+=" "+n),{text:this.out("text"),normal:this.out("normal"),article:this.article(),main:t.normal,qualifier:n,singular:e,plural:r}}},h=function(t,e,r){n.call(this,t,e,r),this.main=this.match("[#Noun+] (of|by|for)"),this.main.found?this.main=this.main.list[0].terms[0]:this.main=this.terms[this.terms.length-1],this.qualifier=this.match(this.main.normal+" [.+]").list[0]};h.prototype=Object.create(n.prototype),Object.keys(c).forEach(function(t){h.prototype[t]=c[t]}),e.exports=h},{"../../paths":8,"./hasPlural":37,"./isPlural":39,"./makeArticle":40,"./methods/pluralize":44,"./methods/singularize":45,"./toPossessive":47}],47:[function(t,e,r){"use strict";var n={he:"his",she:"hers",they:"theirs",we:"ours",i:"mine",you:"yours",her:"hers",their:"theirs",our:"ours",my:"mine",your:"yours"};e.exports=function(t){return t.tag("Possessive","toPossessive"),n.hasOwnProperty(t.normal)?t.text=n[t.normal]:/s$/.test(t.normal)?t.text+="'":t.text+="'s",t}},{}],48:[function(t,e,r){"use strict";e.exports=function(t){return t?!0===/.(i|ee|[a|e]y|a)$/.test(t)?"Female":!0===/[ou]$/.test(t)?"Male":!0===/(nn|ll|tt)/.test(t)?"Female":null:null}},{}],49:[function(t,e,r){"use strict";var n=t("../../text"),a=t("./person");e.exports=n.makeSubset({pronoun:function(){return this.list.map(function(t){return t.pronoun()})},firstNames:function(){return this.match("#FirstName")},lastNames:function(){return this.match("#LastName")}},function(t,e){var r=t.clauses();return r=r.match("#Person+"),"number"==typeof e&&(r=r.get(e)),r.list=r.list.map(function(t){return new a(t.terms,t.world,t.refText,t.refTerms)}),r})},{"../../text":192,"./person":50}],50:[function(t,e,r){"use strict";var i=t("../../paths").Terms,n=t("./guessGender"),a=function(t,e,r,n){if(i.call(this,t,e,r,n),this.firstName=this.match("#FirstName+"),this.middleName=this.match("#Acronym+"),this.nickName=this.match("#NickName+"),this.honorifics=this.match("#Honorific"),this.lastName=this.match("#LastName+"),!this.firstName.found&&1<this.length){var a=this.not("(#Acronym|#Honorific)");this.firstName=a.first(),this.lastName=a.last()}return this};a.prototype=Object.create(i.prototype);var o={data:function(){return{text:this.out("text"),normal:this.out("normal"),firstName:this.firstName.out("normal"),middleName:this.middleName.out("normal"),nickName:this.nickName.out("normal"),lastName:this.lastName.out("normal"),genderGuess:this.guessGender(),pronoun:this.pronoun(),honorifics:this.honorifics.out("array")}},guessGender:function(){if(this.honorifics.match("(mr|mister|sr|sir|jr)").found)return"Male";if(this.honorifics.match("(mrs|miss|ms|misses|mme|mlle)").found)return"Female";if(this.firstName.match("#MaleName").found)return"Male";if(this.firstName.match("#FemaleName").found)return"Female";var t=this.firstName.out("normal");return n(t)},pronoun:function(){var t=this.firstName.out("normal"),e=this.guessGender(t);return"Male"===e?"he":"Female"===e?"she":"they"},root:function(){var t=this.firstName.out("root"),e=this.lastName.out("root");return t&&e?t+" "+e:e||t||this.out("root")}};Object.keys(o).forEach(function(t){a.prototype[t]=o[t]}),e.exports=a},{"../../paths":8,"./guessGender":48}],51:[function(t,e,r){"use strict";var n=t("../../text");e.exports=n.makeSubset({strip:function(){return this.list.forEach(function(t){var e=t.terms[t.terms.length-1];e.text=e.text.replace(/'s$/,""),e.unTag("Possessive",".strip()")}),this}},function(t,e){return t=(t=t.match("#Possessive+")).splitAfter("#Comma"),"number"==typeof e&&(t=t.get(e)),t})},{"../../text":192}],52:[function(t,e,r){"use strict";var n=t("../../text"),a=t("./sentence"),i={toPastTense:function(){return this.list=this.list.map(function(t){return t=t.toPastTense(),new a(t.terms,t.world,t.refText,t.refTerms)}),this},toPresentTense:function(){return this.list=this.list.map(function(t){return t=t.toPresentTense(),new a(t.terms,t.world,t.refText,t.refTerms)}),this},toFutureTense:function(){return this.list=this.list.map(function(t){return t=t.toFutureTense(),new a(t.terms,t.world,t.refText,t.refTerms)}),this},toContinuous:function(){return this.list=this.list.map(function(t){return t=t.toContinuous(),new a(t.terms,t.world,t.refText,t.refTerms)}),this},toNegative:function(){return this.list=this.list.map(function(t){return t=t.toNegative(),new a(t.terms,t.world,t.refText,t.refTerms)}),this},toPositive:function(){return this.list=this.list.map(function(t){return t=t.toPositive(),new a(t.terms,t.world,t.refText,t.refTerms)}),this},isPassive:function(){return this.list=this.list.filter(function(t){return t.isPassive()}),this},isQuestion:function(){return this.questions()},prepend:function(e){return this.list=this.list.map(function(t){return t.prepend(e)}),this},append:function(e){return this.list=this.list.map(function(t){return t.append(e)}),this},toExclamation:function(){return this.list.forEach(function(t){t.setPunctuation("!")}),this},toQuestion:function(){return this.list.forEach(function(t){t.setPunctuation("?")}),this},toStatement:function(){return this.list.forEach(function(t){t.setPunctuation(".")}),this}};e.exports=n.makeSubset(i,function(t,e){return t=t.all(),"number"==typeof e&&(t=t.get(e)),t.list=t.list.map(function(t){return new a(t.terms,t.world,t.refText,t.refTerms)}),t})},{"../../text":192,"./sentence":54}],53:[function(t,e,r){"use strict";e.exports=function(t){var e=t.getPunctuation(),r=t.match("*").splitAfter("#Comma");return!(!0!==/\?/.test(e)&&(/\.\.$/.test(t.out("text"))||t.has("^#QuestionWord")&&t.has("#Comma")||!t.has("^#QuestionWord")&&!t.has("^(do|does|did|is|was|can|could|will|would|may) #Noun")&&!t.has("^(have|must) you")&&!r.has("^#QuestionWord")&&!r.has("(do|does|is|was) #Noun+ #Adverb? (#Adjective|#Infinitive)$")))}},{}],54:[function(t,e,r){"use strict";var a=t("../../paths").Terms,n=t("./toNegative"),i=t("./toPositive"),s=t("../verbs/verb"),o=t("./smartInsert"),u=function(t){var e=t.match("#Condition"),r=t.not("#Condition"),n=r.match("#VerbPhrase+").first(),a=n.out("normal"),i=r.match("#Determiner? #Adjective+? #Noun "+a).first().not("#VerbPhrase"),o=r.match(a+" #Preposition? #Determiner? #Noun").first().not("#VerbPhrase");return t.conditions=e,t.subject=i,t.verb=n,t.object=o,t.verb.found&&(t.verb=new s(t.verb.list[0].terms,t.world,t.refText,t.refTerms)),t},l=function(t){t.found&&t.contractions().expand()},c={toSingular:function(){return this.match("#Noun").match("!#Pronoun").firstTerm().things().toSingular(),this},toPlural:function(){return this.match("#Noun").match("!#Pronoun").firstTerm().things().toPlural(),this},mainVerb:function(){return u(this),this.verb.found?this.verb:null},toPastTense:function(){var t=this.mainVerb();if(t){var e=t.out("root");t.toPastTense();var r=this.match("#Contraction "+e);l(r);var n=t.out("root");return this.parentTerms.replace(e,n)}return this},toPresentTense:function(){var t,e=this.mainVerb();if(e){var r=e.out("normal");if(1==!(!this.subject.found||!this.subject.has("(i|we)")))this.has("(am|will|did) "+r)&&((t=this).terms=t.terms.filter(function(t){if(t.silent_term){if("am"===t.silent_term||"will"===t.silent_term||"did"===t.silent_term)return!1;t.text=t.silent_term,t.silent_term=null,t.unTag("Contraction"),!0===t.tags.TitleCase&&t.toTitleCase()}return!0})),e.toInfinitive();else{e.toPresentTense();var n=this.match("#Contraction "+r);l(n)}var a=e.out("normal");return this.parentTerms.replace(r,a)}return this},toFutureTense:function(){var t=this.mainVerb();if(t){var e=t.clone();t.toFutureTense();var r=this.match("#Contraction "+e.out("normal"));l(r);var n=t.out("normal");return this.parentTerms.replace(e,n)}return this},toContinuous:function(){var t=this.mainVerb();if(t){var e=t.clone();t.toGerund();var r=this.match("#Contraction "+e.out("normal"));l(r);var n=t.out("normal");return this.parentTerms.replace(e,n)}return this},isNegative:function(){return 1===this.match("#Negative").list.length},toNegative:function(){return this.isNegative()?this:n(this)},toPositive:function(){return this.isNegative()?i(this):this},append:function(t){return o.append(this,t)},prepend:function(t){return o.prepend(this,t)},isPassive:function(){return this.match("was #Adverb? #PastTense #Adverb? by").found}},h=function(t,e,r,n){a.call(this,t,e,r,n),u(this)};h.prototype=Object.create(a.prototype),Object.keys(c).forEach(function(t){h.prototype[t]=c[t]}),e.exports=h},{"../../paths":8,"../verbs/verb":94,"./smartInsert":55,"./toNegative":56,"./toPositive":57}],55:[function(t,e,r){"use strict";var n=/^[A-Z]/;e.exports={append:function(t,e){var r=t.terms[t.terms.length-1],n=t.getPunctuation();n&&r.killPunctuation(),t.insertAt(t.terms.length,e);var a=t.terms[t.terms.length-1];return n&&(a.text+=n),r.whitespace.after&&(a.whitespace.after=r.whitespace.after,r.whitespace.after=""),t},prepend:function(t,e){var r=t.terms[0];return t.insertAt(0,e),n.test(r.text)&&(!1===r.needsTitleCase()&&r.toLowerCase(),t.terms[0].toTitleCase()),t}}},{}],56:[function(t,e,r){"use strict";var a={everyone:"no one",everybody:"nobody",someone:"no one",somebody:"nobody",always:"never"};e.exports=function(t){var e=t.match("(everyone|everybody|someone|somebody|always)").first();if(e.found&&a[e.out("normal")]){var r=e.out("normal");return(t=t.match(r).replaceWith(a[r]).list[0]).parentTerms}var n=t.mainVerb();return n&&n.toNegative(),t}},{}],57:[function(t,e,r){"use strict";var n={never:"always",nothing:"everything"};e.exports=function(t){var e=t.match("(never|nothing)").first();if(e.found){var r=e.out("normal");if(n[r])return(t=t.match(r).replaceWith(n[r],!0).list[0]).parentTerms}return t.delete("#Negative"),t}},{}],58:[function(t,e,r){"use strict";var a=t("../../text"),i=t("../../paths").Terms,n={data:function(){return this.list.map(function(t){var e=t.terms[0];return{spaceBefore:e.whitespace.before,text:e.text,spaceAfter:e.whitespace.after,normal:e.normal,implicit:e.silent_term,bestTag:e.bestTag(),tags:Object.keys(e.tags)}})}};e.exports=a.makeSubset(n,function(r,t){var n=[];return r.list.forEach(function(e){e.terms.forEach(function(t){n.push(new i([t],e.world,r))})}),r=new a(n,r.world,r.parent),"number"==typeof t&&(r=r.get(t)),r})},{"../../paths":8,"../../text":192}],59:[function(t,e,r){"use strict";var n=t("./numOrdinal"),a=t("./textOrdinal"),i=t("./textCardinal"),o=t("./niceNumber"),s={nice:function(t){return o(t)},ordinal:function(t){return n(t)},cardinal:function(t){return String(t)},niceOrdinal:function(t){return t=n(t),o(t)},text:function(t){return i(t).join(" ")},textOrdinal:function(t){return a(t)}};e.exports=s},{"./niceNumber":60,"./numOrdinal":61,"./textCardinal":62,"./textOrdinal":63}],60:[function(t,e,r){"use strict";e.exports=function(t){if(!t&&0!==t)return null;for(var e=(t=String(t)).split("."),r=e[0],n=1<e.length?"."+e[1]:"",a=/(\d+)(\d{3})/;a.test(r);)r=r.replace(a,"$1,$2");return r+n}},{}],61:[function(t,e,r){"use strict";var i=t("./toString");e.exports=function(t){if(!t&&0!==t)return null;var e=t%100;if(10<e&&e<20)return String(t)+"th";var r={0:"th",1:"st",2:"nd",3:"rd"},n=i(t),a=n.slice(n.length-1,n.length);return n+(r[a]?r[a]:"th")}},{"./toString":64}],62:[function(t,e,r){"use strict";var u=t("./toString"),n=[["ninety",90],["eighty",80],["seventy",70],["sixty",60],["fifty",50],["forty",40],["thirty",30],["twenty",20]],a=["","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"],l=[[1e24,"septillion"],[1e21,"sextillion"],[1e18,"quintillion"],[1e15,"quadrillion"],[1e12,"trillion"],[1e9,"billion"],[1e8,"hundred million"],[1e6,"million"],[1e5,"hundred thousand"],[1e3,"thousand"],[100,"hundred"],[1,"one"]],c=function(t){var e=[];if(100<t)return e;for(var r=0;r<n.length;r++)t>=n[r][1]&&(t-=n[r][1],e.push(n[r][0]));return a[t]&&e.push(a[t]),e};e.exports=function(o){if(1e21<o)return[String(o)];var t=[];o<0&&(t.push("negative"),o=Math.abs(o));for(var r,n,a,e=(n=r=o,a=[],l.forEach(function(t){if(r>=t[0]){var e=Math.floor(n/t[0]);n-=e*t[0],e&&a.push({unit:t[1],count:e})}}),a),i=0;i<e.length;i++){var s=e[i].unit;"one"===s&&(s="",1<t.length&&t.push("and")),(t=t.concat(c(e[i].count))).push(s)}return 0===(t=(t=t.concat(function(t){var e=["zero","one","two","three","four","five","six","seven","eight","nine"],r=[],n=u(o).match(/\.([0-9]+)/);if(!n||!n[0])return r;r.push("point");for(var a=n[0].split(""),i=0;i<a.length;i++)r.push(e[a[i]]);return r}())).filter(function(t){return t})).length&&(t[0]=""),t}},{"./toString":64}],63:[function(t,e,r){"use strict";var n=t("./textCardinal"),a=t("../../../world/more-data/numbers").toOrdinal;e.exports=function(t){var e=n(t),r=e[e.length-1];return e[e.length-1]=a[r]||r,e.join(" ")}},{"../../../world/more-data/numbers":220,"./textCardinal":62}],64:[function(t,e,r){"use strict";e.exports=function(t){if(t<1e6)return String(t);var e=t.toFixed(0);return-1===e.indexOf("e+")?e:e.replace(".","").split("e+").reduce(function(t,e){return t+Array(e-t.length+2).join(0)})}},{}],65:[function(t,e,r){"use strict";var n=t("../../text"),i=t("./value"),a=t("./parse"),o={noDates:function(){return this.not("#Date")},noUnits:function(){return this.not("#Unit")},units:function(){return this.match("#Unit+")},numbers:function(){return this.list.map(function(t){return t.number()})},toNumber:function(){return this.list=this.list.map(function(t){return t.toNumber()}),this},toText:function(){return this.list=this.list.map(function(t){return t.toText()}),this},toCardinal:function(){return this.list=this.list.map(function(t){return t.toCardinal()}),this},toOrdinal:function(){return this.list=this.list.map(function(t){return t.toOrdinal()}),this},toNice:function(){return this.list=this.list.map(function(t){return t.toNice()}),this},isEqual:function(e){return e=a(e),this.list=this.list.filter(function(t){return null!==e&&t.number()===e}),this},greaterThan:function(e){return e=a(e),this.list=this.list.filter(function(t){return null!==e&&t.number()>e}),this},lessThan:function(e){return e=a(e),this.list=this.list.filter(function(t){return null!==e&&t.number()<e}),this},between:function(r,n){return void 0===r||void 0===n||(r=a(r),n=a(n),this.list=this.list.filter(function(t){var e=t.number();return r<e&&e<n})),this},add:function(e){return this.list=this.list.map(function(t){return t.add(e)}),this},subtract:function(e){return this.list=this.list.map(function(t){return t.subtract(e)}),this},increment:function(){return this.list=this.list.map(function(t){return t.add(1)}),this},decrement:function(){return this.list=this.list.map(function(t){return t.subtract(1)}),this}};e.exports=n.makeSubset(o,function(t,e){var r="twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety|fourty";if((t=t.match("#Value+ #Unit?")).has("#NumericValue #NumericValue")&&(t.has("#Value #Comma #Value")?t.splitAfter("#Comma"):t.splitAfter("#NumericValue")),t.has("#Value #Value #Value")&&!t.has("#Multiple")&&t.has("("+r+") #Cardinal #Cardinal")&&t.splitAfter("("+r+") #Cardinal"),t.has("#Value #Value")){t.has("#NumericValue #NumericValue")&&t.splitOn("#Year"),t.has("("+r+") (eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen)")&&t.splitAfter("("+r+")");var n=t.match("#Cardinal #Cardinal");n.found&&!t.has("(point|decimal)")&&(n.has("#Cardinal (#Multiple|point|decimal)")||n.has("("+r+") #Cardinal")||n.has("#Multiple #Value")||t.splitAfter(n.terms(0).out("normal"))),t.match("#Ordinal #Ordinal").match("#TextValue").found&&!t.has("#Multiple")&&(t.has("("+r+") #Ordinal")||t.splitAfter("#Ordinal")),t.has("#Ordinal #Cardinal")&&t.splitBefore("#Cardinal+"),t.has("#TextValue #NumericValue")&&!t.has("("+r+"|#Multiple)")&&t.splitBefore("#NumericValue+")}t.has("#NumberRange")&&t.splitAfter("#NumberRange"),"number"==typeof e&&(t=t.get(e));var a=t.world();return t.list=t.list.map(function(t){return new i(t.terms,a,t.refText,t.refTerms)}),t})},{"../../text":192,"./parse":66,"./value":74}],66:[function(t,e,r){"use strict";var n=t("./parseText"),a=/^-?(\$|€|¥|£)?\.?[0-9]+[0-9,\.]*(st|nd|rd|th|rth|%)?$/,i=function(t){if(!0===a.test(t)){t=(t=(t=(t=t.replace(/,/g,"")).replace(/^[\$|€|¥|£]/g,"")).replace(/%$/,"")).replace(/(st|nd|rd|th|rth)$/g,"");var e=parseFloat(t);if(e||0===e)return e}return n(t)};e.exports=function(t){if(null==t||"number"==typeof t)return t;if("string"==typeof t)return i(t);if(1!==t.terms.length||!0===t.terms[0].tags.TextValue)return n(t.out("normal"));var e=t.terms[0].normal;return i(e)}},{"./parseText":69}],67:[function(t,e,r){"use strict";var n=t("../../../world/more-data/numbers"),a=t("../paths").fns,i=a.extend(n.ordinal.ones,n.cardinal.ones),o=a.extend(n.ordinal.teens,n.cardinal.teens),s=a.extend(n.ordinal.tens,n.cardinal.tens),u=a.extend(n.ordinal.multiples,n.cardinal.multiples);u.grand=1e3,e.exports={ones:i,teens:o,tens:s,multiples:u}},{"../../../world/more-data/numbers":220,"../paths":73}],68:[function(t,e,r){"use strict";e.exports=function(t){for(var e=[{reg:/^(minus|negative)[\s\-]/i,mult:-1},{reg:/^(a\s)?half[\s\-](of\s)?/i,mult:.5}],r=0;r<e.length;r++)if(!0===e[r].reg.test(t))return{amount:e[r].mult,str:t.replace(e[r].reg,"")};return{amount:1,str:t}}},{}],69:[function(t,e,r){"use strict";var d=t("./findModifiers"),p=t("./data"),g=t("./validate"),v=t("./parseDecimals"),y=t("./parseNumeric"),b=/^([0-9,\. ]+)\/([0-9,\. ]+)$/,D={"a couple":2,"a dozen":12,"two dozen":24,zero:0},w=function(r){return Object.keys(r).reduce(function(t,e){return t+r[e]},0)};e.exports=function(t){if(!0===D.hasOwnProperty(t))return D[t];if("a"===t||"an"===t)return 1;for(var e=d(t),r=null,n={},a=0,i=!1,o=(t=e.str).split(/[ -]/),s=0;s<o.length;s++){var u=o[s];if((u=y(u))&&"and"!==u)if("-"!==u&&"negative"!==u){if("-"===u.charAt(0)&&(i=!0,u=u.substr(1)),"point"===u)return a+=w(n),(a+=v(o.slice(s+1,o.length)))*e.amount;var l=u.match(b);if(l){var c=parseFloat(l[1].replace(/[, ]/g,"")),h=parseFloat(l[2].replace(/[, ]/g,""));h&&(a+=c/h||0)}else{if(!1===g(u,n))return null;if(/^[0-9\.]+$/.test(u))n.ones=parseFloat(u);else if(!0===p.ones.hasOwnProperty(u))n.ones=p.ones[u];else if(!0===p.teens.hasOwnProperty(u))n.teens=p.teens[u];else if(!0===p.tens.hasOwnProperty(u))n.tens=p.tens[u];else if(!0===p.multiples.hasOwnProperty(u)){var f=p.multiples[u];if(f===r)return null;if(100===f&&void 0!==o[s+1]){var m=o[s+1];p.multiples[m]&&(f*=p.multiples[m],s+=1)}null===r||f<r?(a+=(w(n)||1)*f,r=f):a=((a+=w(n))||1)*(r=f),n={}}}}else i=!0}return a+=w(n),a*=e.amount,0==(a*=i?-1:1)&&0===Object.keys(n).length?null:a}},{"./data":67,"./findModifiers":68,"./parseDecimals":70,"./parseNumeric":71,"./validate":72}],70:[function(t,e,r){"use strict";var a=t("./data");e.exports=function(t){for(var e="0.",r=0;r<t.length;r++){var n=t[r];if(!0===a.ones.hasOwnProperty(n))e+=a.ones[n];else if(!0===a.teens.hasOwnProperty(n))e+=a.teens[n];else if(!0===a.tens.hasOwnProperty(n))e+=a.tens[n];else{if(!0!==/^[0-9]$/.test(n))return 0;e+=n}}return parseFloat(e)}},{"./data":67}],71:[function(t,e,r){"use strict";e.exports=function(t){return(t=(t=(t=(t=(t=(t=(t=t.replace(/1st$/,"1")).replace(/2nd$/,"2")).replace(/3rd$/,"3")).replace(/([4567890])r?th$/,"$1")).replace(/^[$€¥£¢]/,"")).replace(/[%$€¥£¢]$/,"")).replace(/,/g,"")).replace(/([0-9])([a-z]{1,2})$/,"$1")}},{}],72:[function(t,e,r){"use strict";var n=t("./data");e.exports=function(t,e){if(n.ones.hasOwnProperty(t)){if(e.ones||e.teens)return!1}else if(n.teens.hasOwnProperty(t)){if(e.ones||e.teens||e.tens)return!1}else if(n.tens.hasOwnProperty(t)&&(e.ones||e.teens||e.tens))return!1;return!0}},{"./data":67}],73:[function(t,e,r){"use strict";e.exports=t("../../paths")},{"../../paths":8}],74:[function(t,e,r){"use strict";var a=t("../../paths").Terms,n=t("./parse"),i=t("./format"),o=function(t){return t.val=t.match("#Value+"),t.val=t.val.list[0],t.unit=t.match("#Unit+"),t.unit.found&&(t.unit=t.unit.list[0]),t},s=function(t,e){return!(!t.has("#Percent")&&!e.has("#Percent"))||"percent"===e.out("normal")||null!==t.out("normal").match(/%$/)},u=function(t,e){var r=t.val.out();return r=t.has("#Ordinal")?t.has("#TextValue")?i.textOrdinal(e):i.ordinal(e):t.has("#TextValue")?i.text(e):t.has("#NiceNumber")?i.nice(e):i.cardinal(e),t.unit.found&&(r+=t.unit.out("text")),t=t.replaceWith(r,!0),o(t)},l=function(t,e,r,n){a.call(this,t,e,r,n),o(this)};l.prototype=Object.create(a.prototype);var c={data:function(){var t=n(this.val);return{number:t,nice:i.nice(t),ordinal:i.ordinal(t),niceOrdinal:i.niceOrdinal(t),text:i.text(t),textOrdinal:i.textOrdinal(t),unit:this.unit.out("normal")}},number:function(){return n(this.val)},toNumber:function(){var t=n(this.val);if(t||0===t){var e="";this.val.has("#Ordinal")?e=i.ordinal(t):(e=String(t),s(this.val,this.unit)&&(e+="%",this.unit.delete())),this.unit.found&&(e+=this.unit.out("text")),this.replaceWith(e,!0).tag("NumericValue"),this.unit.found&&this.match(this.unit.out("normal")).tag("Unit")}return this},toText:function(){var t=n(this.val);if(t||0===t){var e="";this.val.has("#Ordinal")?e=i.textOrdinal(t):(e=i.text(t),s(this.val,this.unit)&&(e+=" percent")),this.unit.found&&(e+=this.unit.out("text")),this.replaceWith(e,!0).tag("TextValue"),this.unit.found&&this.match(this.unit.out("normal")).tag("Unit")}return this},toCardinal:function(){var t=n(this.val);if(t||0===t){var e="";e=this.val.has("#TextValue")?i.text(t):t,this.unit.found&&(e+=this.unit.out("text")),this.replaceWith(e,!0).tag("Cardinal"),this.unit.found&&this.match(this.unit.out("normal")).tag("Unit")}return this},toOrdinal:function(){var t=n(this.val);if(t||0===t){var e="";e=this.val.has("#TextValue")?i.textOrdinal(t):i.ordinal(t),this.unit.found&&(e+=this.unit.out("text")),this.replaceWith(e,!0).tag("Ordinal"),this.unit.found&&this.match(this.unit.out("normal")).tag("Unit")}return this},toNice:function(){var t=n(this.val);if(t||0===t){var e="";e=this.val.has("#Ordinal")?i.niceOrdinal(t):i.nice(t),this.unit.found&&(e+=this.unit.out("text")),this.replaceWith(e,!0).tag("NumericValue"),this.unit.found&&this.match(this.unit.out("normal")).tag("Unit")}return this},add:function(t){if(!t)return this;var e=n(this.val)||0;return u(this,e+=t)},subtract:function(t){if(!t)return this;var e=n(this.val)||0;return u(this,e-=t)},increment:function(){return this.add(1)},decrement:function(){return this.subtract(1)}};Object.keys(c).forEach(function(t){l.prototype[t]=c[t]}),e.exports=l},{"../../paths":8,"./format":59,"./parse":66}],75:[function(t,e,r){"use strict";var n=t("../../text"),a=t("./verb"),i={conjugation:function(e){return this.list.map(function(t){return t.conjugation(e)})},conjugate:function(t,e){return null!==t&&"number"==typeof t&&this.list[t]?this.list[t].conjugate(e):this.list.map(function(t){return t.conjugate(e)})},isPlural:function(){return this.list=this.list.filter(function(t){return t.isPlural()}),this},isSingular:function(){return this.list=this.list.filter(function(t){return!t.isPlural()}),this},isNegative:function(){return this.list=this.list.filter(function(t){return t.isNegative()}),this},isPositive:function(){return this.list=this.list.filter(function(t){return!t.isNegative()}),this},toNegative:function(){return this.list=this.list.map(function(t){return t.toNegative()}),this},toPositive:function(){return this.list.forEach(function(t){t.toPositive()}),this},toPastTense:function(){return this.list.forEach(function(t){t.toPastTense()}),this},toPresentTense:function(){return this.list.forEach(function(t){t.toPresentTense()}),this},toFutureTense:function(){return this.list.forEach(function(t){t.toFutureTense()}),this},toInfinitive:function(){return this.list.forEach(function(t){t.toInfinitive()}),this},toGerund:function(){return this.list.forEach(function(t){t.toGerund()}),this},asAdjective:function(){return this.list.map(function(t){return t.asAdjective()})}};i.toContinuous=i.toGerund,e.exports=n.makeSubset(i,function(t,e){return t=(t=(t=t.match("(#Adverb|#Auxiliary|#Verb|#Negative|#Particle)+")).splitAfter("#Comma")).if("#Verb"),"number"==typeof e&&(t=t.get(e)),t.list=t.list.map(function(t){return new a(t.terms,t.world,t.refText,t.refTerms)}),new n(t.list,this.world,this.parent)})},{"../../text":192,"./verb":94}],76:[function(t,e,r){"use strict";var s=t("./methods/predict"),u=t("./methods/isPlural");e.exports=function(t){var e,r,n,a,i,o;return{negative:2!==(e=t.match("#Negative").list).length&&1===e.length,continuous:(o=t,o.match("#Gerund").found),passive:(i=t,!!i.match("is being #PastTense").found||!!i.match("(had|has) been #PastTense").found||!!i.match("will have been #PastTense").found),perfect:(a=t,!!a.match("^(had|have) #PastTense")),plural:u(t),modal:(r=t,n=r.match("#Modal"),n.found?n.out("normal"):null),tense:function(t){if(t.auxiliary.found){if(t.match("will have #PastTense").found)return"Past";if(t.auxiliary.match("will").found)return"Future";if(t.auxiliary.match("was").found)return"Past"}return t.verb&&{PastTense:"Past",FutureTense:"Future",FuturePerfect:"Future"}[s(t.verb)]||"Present"}(t)}}},{"./methods/isPlural":86,"./methods/predict":87}],77:[function(t,e,r){"use strict";var s=t("./irregulars"),u=t("./suffixes"),l=t("./toActor"),c=t("./generic"),h=t("../predict"),f=t("../toInfinitive"),m=t("./toBe");e.exports=function(t,e){if("is"===t.normal||"was"===t.normal||"will"===t.normal)return m();t.tags.Contraction&&(t.text=t.silent_term);var r={PastTense:null,PresentTense:null,Infinitive:null,Gerund:null,Actor:null},n=h(t);n&&(r[n]=t.normal),"Infinitive"!==n&&(r.Infinitive=f(t,e)||"");var a=s(r.Infinitive,e)||{};Object.keys(a).forEach(function(t){a[t]&&!r[t]&&(r[t]=a[t])});var i=r.Infinitive||t.normal,o=u(i);return Object.keys(o).forEach(function(t){o[t]&&!r[t]&&(r[t]=o[t])}),r.Actor||(r.Actor=l(i)),Object.keys(r).forEach(function(t){!r[t]&&c[t]&&(r[t]=c[t](r))}),r}},{"../predict":87,"../toInfinitive":90,"./generic":80,"./irregulars":82,"./suffixes":83,"./toActor":84,"./toBe":85}],78:[function(t,e,r){"use strict";e.exports=[{reg:/(eave)$/i,repl:{pr:"$1s",pa:"$1d",gr:"eaving",ar:"$1r"}},{reg:/(ink)$/i,repl:{pr:"$1s",pa:"unk",gr:"$1ing",ar:"$1er"}},{reg:/([aeiou]k)in$/i,repl:{pr:"$1s",pa:"$1ed",gr:"$1ing",ar:"$1er"}},{reg:/(end)$/i,repl:{pr:"$1s",pa:"ent",gr:"$1ing",ar:"$1er"}},{reg:/(ide)$/i,repl:{pr:"$1s",pa:"ode",gr:"iding",ar:"ider"}},{reg:/(ake)$/i,repl:{pr:"$1s",pa:"ook",gr:"aking",ar:"$1r"}},{reg:/(eed)$/i,repl:{pr:"$1s",pa:"$1ed",gr:"$1ing",ar:"$1er"}},{reg:/(e)(ep)$/i,repl:{pr:"$1$2s",pa:"$1pt",gr:"$1$2ing",ar:"$1$2er"}},{reg:/(a[tg]|i[zn]|ur|nc|gl|is)e$/i,repl:{pr:"$1es",pa:"$1ed",gr:"$1ing",prt:"$1en"}},{reg:/([i|f|rr])y$/i,repl:{pr:"$1ies",pa:"$1ied",gr:"$1ying"}},{reg:/([td]er)$/i,repl:{pr:"$1s",pa:"$1ed",gr:"$1ing"}},{reg:/([bd]l)e$/i,repl:{pr:"$1es",pa:"$1ed",gr:"$1ing"}},{reg:/(ish|tch|ess)$/i,repl:{pr:"$1es",pa:"$1ed",gr:"$1ing"}},{reg:/(ion|end|e[nc]t)$/i,repl:{pr:"$1s",pa:"$1ed",gr:"$1ing"}},{reg:/(om)e$/i,repl:{pr:"$1es",pa:"ame",gr:"$1ing"}},{reg:/(.eat)$/i,repl:{pr:"$1s",pa:"$1ed",gr:"$1ing"}},{reg:/([aeiu])([pt])$/i,repl:{pr:"$1$2s",pa:"$1$2",gr:"$1$2$2ing"}},{reg:/(er)$/i,repl:{pr:"$1s",pa:"$1ed",gr:"$1ing"}},{reg:/(en)$/i,repl:{pr:"$1s",pa:"$1ed",gr:"$1ing"}},{reg:/(ed)$/i,repl:{pr:"$1s",pa:"$1ded",ar:"$1der",gr:"$1ding"}},{reg:/(..)(ow)$/i,repl:{pr:"$1$2s",pa:"$1ew",gr:"$1$2ing",prt:"$1$2n"}},{reg:/(..)([cs]h)$/i,repl:{pr:"$1$2es",pa:"$1$2ed",gr:"$1$2ing"}},{reg:/([^aeiou][ou])(g|d)$/i,repl:{pr:"$1$2s",pa:"$1$2$2ed",gr:"$1$2$2ing"}},{reg:/([^aeiou][aeiou])(b|t|p|m)$/i,repl:{pr:"$1$2s",pa:"$1$2$2ed",gr:"$1$2$2ing"}},{reg:/([aeiou]zz)$/i,repl:{pr:"$1es",pa:"$1ed",gr:"$1ing"}}]},{}],79:[function(t,e,r){"use strict";var o=t("./irregulars"),s=t("./suffixes"),u=t("./generic"),l=["Gerund","PastTense","PresentTense"];e.exports=function(t,e){var r={Infinitive:t};if(e&&e.conjugations){var n=o(r.Infinitive,e);null!==n&&Object.keys(n).forEach(function(t){n[t]&&!r[t]&&(r[t]=n[t])})}var a=s(t);Object.keys(a).forEach(function(t){a[t]&&!r[t]&&(r[t]=a[t])});for(var i=0;i<l.length;i++)void 0===r[l[i]]&&(r[l[i]]=u[l[i]](r));return r}},{"./generic":80,"./irregulars":82,"./suffixes":83}],80:[function(t,e,r){"use strict";var n=/[bcdfghjklmnpqrstvwxz]y$/,a={Gerund:function(t){var e=t.Infinitive;return"e"===e.charAt(e.length-1)?e.replace(/e$/,"ing"):e+"ing"},PresentTense:function(t){var e=t.Infinitive;return"s"===e.charAt(e.length-1)?e+"es":!0===n.test(e)?e.slice(0,-1)+"ies":e+"s"},PastTense:function(t){var e=t.Infinitive;return"e"===e.charAt(e.length-1)?e+"d":"ed"===e.substr(-2)?e:!0===n.test(e)?e.slice(0,-1)+"ied":e+"ed"}};e.exports=a},{}],81:[function(t,e,r){"use strict";var s=t("./conjugate"),u=t("./toBe"),l=function(e,r){if(r.adverbs.found){var n=r.first().match("#Adverb").found;Object.keys(e).forEach(function(t){e[t]=n?r.adverbs.out()+" "+e[t]:e[t]+r.adverbs.out()})}return e};e.exports=function(e,t){var r=e.negative.found,n=e.isPlural();if(e.verb.tags.Copula||"be"===e.verb.normal&&e.auxiliary.match("will").found){var a=!1;e.parent&&e.parent.has("i #Adverb? #Copula")&&(a=!0);var i=u(n,r,a);return l(i,e)}var o=s(e.verb,e.world,t);return e.particle.found&&Object.keys(o).forEach(function(t){o[t]=o[t]+e.particle.out()}),r&&(o.PastTense="did not "+o.Infinitive,o.PresentTense="does not "+o.Infinitive,o.Gerund="not "+o.Gerund),o.FutureTense||(o.FutureTense=r?"will not "+o.Infinitive:"will "+o.Infinitive),o=l(o,e)}},{"./conjugate":77,"./toBe":85}],82:[function(t,e,r){"use strict";var l=t("../../../../fns"),c=["Participle","Gerund","PastTense","PresentTense","FuturePerfect","PerfectTense","Actor"];e.exports=function(t,e){var r=e.conjugations,n=Object.keys(r);if(e&&e.conjugations&&!0===e.conjugations.hasOwnProperty(t))return e.conjugations[t];if(!0===r.hasOwnProperty(t)){var a=l.copy(r[t]);return a.Infinitive=t,a}for(var i=0;i<n.length;i++)for(var o=0;o<c.length;o++){var s=r[n[i]];if(s[c[o]]===t){var u=l.copy(s);return u.Infinitive=n[i],u}}return{}}},{"../../../../fns":3}],83:[function(t,e,r){"use strict";var i=t("./data/rules"),o={pr:"PresentTense",pa:"PastTense",gr:"Gerund",prt:"Participle",ar:"Actor"},s=Object.keys(o);e.exports=function(t){for(var e={},r=0;r<i.length;r++)if(!0===i[r].reg.test(t)){for(var n=i[r].repl,a=0;a<s.length;a++)!0===n.hasOwnProperty(s[a])&&(e[o[s[a]]]=t.replace(i[r].reg,n[s[a]]));return e}return e}},{"./data/rules":78}],84:[function(t,e,r){"use strict";var n={tie:"tier",dream:"dreamer",sail:"sailer",run:"runner",rub:"rubber",begin:"beginner",win:"winner",claim:"claimant",deal:"dealer",spin:"spinner"},a={aid:1,fail:1,appear:1,happen:1,seem:1,try:1,say:1,marry:1,be:1,forbid:1,understand:1,bet:1},i=[{reg:/e$/i,repl:"er"},{reg:/([aeiou])([mlgp])$/i,repl:"$1$2$2er"},{reg:/([rlf])y$/i,repl:"$1ier"},{reg:/^(.?.[aeiou])t$/i,repl:"$1tter"}];e.exports=function(t){if(a[t])return null;if(n.hasOwnProperty(t))return n[t];for(var e=0;e<i.length;e++)if(!0===i[e].reg.test(t))return t.replace(i[e].reg,i[e].repl);return t+"er"}},{}],85:[function(t,e,r){"use strict";e.exports=function(t,e,r){var n={PastTense:"was",PresentTense:"is",FutureTense:"will be",Infinitive:"is",Gerund:"being",Actor:"",PerfectTense:"been",Pluperfect:"been"};return!0===r&&(n.PresentTense="am",n.Infinitive="am"),t&&(n.PastTense="were",n.PresentTense="are",n.Infinitive="are"),e&&(n.PastTense+=" not",n.PresentTense+=" not",n.FutureTense="will not be",n.Infinitive+=" not",n.PerfectTense="not "+n.PerfectTense,n.Pluperfect="not "+n.Pluperfect,n.Gerund="not "+n.Gerund),n}},{}],86:[function(t,e,r){"use strict";e.exports=function(t){if(t.match("(are|were|does)").found)return!0;if(t.match("(is|am|do|was)").found)return!1;var e=t.getNoun();if(e&&e.found){if(e.match("#Plural").found)return!0;if(e.match("#Singular").found)return!1}return null}},{}],87:[function(t,e,r){"use strict";var i=t("./suffix_rules"),o={Infinitive:!0,Gerund:!0,PastTense:!0,PresentTense:!0,FutureTense:!0,PerfectTense:!0,Pluperfect:!0,FuturePerfect:!0,Participle:!0};e.exports=function(t){for(var e=Object.keys(o),r=0;r<e.length;r++)if(t.tags[e[r]])return e[r];for(var n=Object.keys(i),a=0;a<n.length;a++)if(t.normal.substr(-n[a].length)===n[a]&&t.normal.length>n[a].length)return i[n[a]];return null}},{"./suffix_rules":88}],88:[function(t,e,r){"use strict";for(var n={Gerund:["ing"],Actor:["erer"],Infinitive:["ate","ize","tion","rify","then","ress","ify","age","nce","ect","ise","ine","ish","ace","ash","ure","tch","end","ack","and","ute","ade","ock","ite","ase","ose","use","ive","int","nge","lay","est","ain","ant","ent","eed","er","le","own","unk","ung","en"],PastTense:["ed","lt","nt","pt","ew","ld"],PresentTense:["rks","cks","nks","ngs","mps","tes","zes","ers","les","acks","ends","ands","ocks","lays","eads","lls","els","ils","ows","nds","ays","ams","ars","ops","ffs","als","urs","lds","ews","ips","es","ts","ns","s"]},a={},i=Object.keys(n),o=i.length,s=0;s<o;s++)for(var u=n[i[s]].length,l=0;l<u;l++)a[n[i[s]][l]]=i[s];e.exports=a},{}],89:[function(t,e,r){"use strict";var n=[[/y$/,"i"],[/([aeiou][n])$/,"$1n"]],a={collect:!0,exhaust:!0,convert:!0,digest:!0,discern:!0,dismiss:!0,reverse:!0,access:!0,collapse:!0,express:!0},i={eat:"edible",hear:"audible",see:"visible",defend:"defensible",write:"legible",move:"movable",divide:"divisible",perceive:"perceptible"};e.exports=function(t){if(i.hasOwnProperty(t))return i[t];for(var e=0;e<n.length;e++)!0===n[e][0].test(t)&&(t=t.replace(n[e][0],n[e][1]));var r=t+"able";return a[t]&&(r=t+"ible"),r}},{}],90:[function(t,e,r){"use strict";var o=t("./rules"),s=t("../predict");e.exports=function(t,e){var r=e.cache.toInfinitive||{};if(t.tags.Infinitive)return t.normal;if(!0===r.hasOwnProperty(t.normal))return r[t.normal];var n=s(t);if(o[n])for(var a=0;a<o[n].length;a++){var i=o[n][a];if(t.normal.match(i.reg))return t.normal.replace(i.reg,i.to)}return t.normal}},{"../predict":87,"./rules":91}],91:[function(t,e,r){"use strict";e.exports={Participle:[{reg:/own$/i,to:"ow"},{reg:/(.)un([g|k])$/i,to:"$1in$2"}],Actor:[{reg:/(er)er$/i,to:"$1"}],PresentTense:[{reg:/(..)(ies)$/i,to:"$1y"},{reg:/(tch|sh)es$/i,to:"$1"},{reg:/(ss|zz)es$/i,to:"$1"},{reg:/([tzlshicgrvdnkmu])es$/i,to:"$1e"},{reg:/(n[dtk]|c[kt]|[eo]n|i[nl]|er|a[ytrl])s$/i,to:"$1"},{reg:/(ow)s$/i,to:"$1"},{reg:/(op)s$/i,to:"$1"},{reg:/([eirs])ts$/i,to:"$1t"},{reg:/(ll)s$/i,to:"$1"},{reg:/(el)s$/i,to:"$1"},{reg:/(ip)es$/i,to:"$1e"},{reg:/ss$/i,to:"ss"},{reg:/s$/i,to:""}],Gerund:[{reg:/pping$/i,to:"p"},{reg:/lling$/i,to:"ll"},{reg:/tting$/i,to:"t"},{reg:/dding$/i,to:"d"},{reg:/ssing$/i,to:"ss"},{reg:/(..)gging$/i,to:"$1g"},{reg:/([^aeiou])ying$/i,to:"$1y"},{reg:/([^ae]i.)ing$/i,to:"$1e"},{reg:/(ea.)ing$/i,to:"$1"},{reg:/(u[rtcb]|[bdtpkg]l|n[cg]|a[gdkvtc]|[ua]s|[dr]g|yz|o[rlsp]|cre)ing$/i,to:"$1e"},{reg:/(ch|sh)ing$/i,to:"$1"},{reg:/(..)ing$/i,to:"$1"}],PastTense:[{reg:/(ued)$/i,to:"ue"},{reg:/a([^aeiouy])ed$/i,to:"a$1e"},{reg:/([aeiou]zz)ed$/i,to:"$1"},{reg:/(e|i)lled$/i,to:"$1ll"},{reg:/(.)(sh|ch)ed$/i,to:"$1$2"},{reg:/(tl|gl)ed$/i,to:"$1e"},{reg:/(um?pt?)ed$/i,to:"$1"},{reg:/(ss)ed$/i,to:"$1"},{reg:/pped$/i,to:"p"},{reg:/tted$/i,to:"t"},{reg:/(..)gged$/i,to:"$1g"},{reg:/(..)lked$/i,to:"$1lk"},{reg:/([^aeiouy][aeiou])ked$/i,to:"$1ke"},{reg:/(.[aeiou])led$/i,to:"$1l"},{reg:/(..)(h|ion|n[dt]|ai.|[cs]t|pp|all|ss|tt|int|ail|ld|en|oo.|er|k|pp|w|ou.|rt|ght|rm)ed$/i,to:"$1$2"},{reg:/(.ut)ed$/i,to:"$1e"},{reg:/(.pt)ed$/i,to:"$1"},{reg:/(us)ed$/i,to:"$1e"},{reg:/(..[^aeiouy])ed$/i,to:"$1e"},{reg:/(..)ied$/i,to:"$1y"},{reg:/(.o)ed$/i,to:"$1o"},{reg:/(..i)ed$/i,to:"$1"},{reg:/(.a[^aeiou])ed$/i,to:"$1"},{reg:/([rl])ew$/i,to:"$1ow"},{reg:/([pl])t$/i,to:"$1t"}]}},{}],92:[function(t,e,r){"use strict";e.exports=function(t){return t.match("#Contraction+").list.forEach(function(t){t.has("#Verb")&&t.terms.forEach(function(t){t.silent_term&&(t.text||(t.whitespace.before=" "),t._text=t.silent_term,t.tags.TitleCase&&t.toTitleCase(),t.normalize(),t.silent_term=null,t.unTag("Contraction","expanded"))})}),t}},{}],93:[function(t,e,r){"use strict";var C=t("./methods/toInfinitive"),k=function(t){return(t=(t=t.match("(#Adverb|#Auxiliary|#Verb|#Negative|#Particle)+")).splitAfter("#Comma")).list[0]};e.exports=function(t){var e=t.match("#Auxiliary").first();if(e.found){var r=e.list[0].index(),n=t.parentTerms.insertAt(r+1,"not","Verb");return n.match("not").tag("Negative","tag-not"),k(n)}var a=t.match("(#Copula|will|has|had|do)").first();if(a.found){var i=a.list[0].index(),o=t.parentTerms.insertAt(i+1,"not","Verb");return o.match("not").tag("Negative","tag-not"),k(o)}var s=t.isPlural(),u=t.match("#PastTense").last();if(u.found){var l=u.list[0],c=l.index();l.terms[0].text=C(l.terms[0],t.world);var h=t.parentTerms.insertAt(c,"did not","Verb");return h.match("not").tag("Negative","tag-not"),k(h)}var f=t.match("#PresentTense").first();if(f.found){var m=f.list[0],d=m.index();m.terms[0].text=C(m.terms[0],t.world);var p=null;return(p=t.getNoun().match("(i|we|they|you)").found?t.parentTerms.insertAt(d,"do not","Verb"):t.parentTerms.insertAt(d,"does not","Verb")).match("not").tag("Negative","tag-not"),k(p)}var g=t.match("#Gerund").last();if(g.found){var v=g.list[0].index(),y=t.parentTerms.insertAt(v,"not","Verb");return y.match("not").tag("Negative","tag-not"),k(y)}var b=t.match("#Verb").last();if(b.found){var D=b.list[0],w=D.index();D.terms[0].text=C(D.terms[0],t.world);var x=t;return(x=s?t.parentTerms.insertAt(w-1,"do not","Verb"):t.parentTerms.insertAt(w-1,"does not","Verb")).match("not").tag("Negative","tag-not"),k(x)}return t}},{"./methods/toInfinitive":90}],94:[function(t,e,r){"use strict";var a=t("../../paths").Terms,n=t("./methods/conjugate"),i=t("./methods/toAdjective"),o=t("./interpret"),s=t("./toNegative"),u=t("./methods/isPlural"),l=t("./methods/verbContraction"),c=function(t){var e=t;t.negative=t.match("#Negative"),t.adverbs=t.match("#Adverb");var r=t.clone().not("(#Adverb|#Negative)");if(t.verb=r.match("#Verb").not("#Particle").last(),t.particle=r.match("#Particle").last(),t.verb.found){var n=t.verb.out("normal");t.auxiliary=e.not(n).not("(#Adverb|#Negative)"),t.verb=t.verb.list[0].terms[0]}else t.verb=e.terms[0];return t},h={parse:function(){return c(this)},data:function(t){return{text:this.out("text"),normal:this.out("normal"),parts:{negative:this.negative.out("normal"),auxiliary:this.auxiliary.out("normal"),verb:this.verb.out("normal"),particle:this.particle.out("normal"),adverbs:this.adverbs.out("normal")},interpret:o(this,t),conjugations:this.conjugate()}},getNoun:function(){if(!this.refTerms)return null;var t="#Adjective? #Noun+ "+this.out("normal");return this.refTerms.match(t).match("#Noun+")},conjugation:function(){return o(this,!1).tense},conjugate:function(t){return n(this,t)},isPlural:function(){return u(this)},isNegative:function(){return 1===this.match("#Negative").list.length},isPerfect:function(){return this.auxiliary.match("(have|had)").found},toNegative:function(){return this.isNegative()?this:s(this)},toPositive:function(){return this.match("#Negative").delete()},toPastTense:function(){this.has("#Contraction")&&(this.list=l(this.parentTerms).list);var t=this.conjugate().PastTense,e=this.replaceWith(t,!1);return e.verb.tag("#PastTense"),e},toPresentTense:function(){this.has("#Contraction")&&l(this.parentTerms);var t=this.conjugate(),e=this.replaceWith(t.PresentTense,!1);return e.verb.tag("#PresentTense"),e},toFutureTense:function(){this.has("#Contraction")&&l(this.parentTerms);var t=this.conjugate(),e=this.replaceWith(t.FutureTense,!1);return e.verb.tag("#FutureTense"),e},toInfinitive:function(){this.has("#Contraction")&&l(this.parentTerms);var t=this.conjugate(),e=this.replaceWith(t.Infinitive,!1);return e.verb.tag("#Infinitive"),e},toGerund:function(){this.has("#Contraction")&&l(this.parentTerms);var t=this.conjugate(),e="is",r=this.getNoun().out("normal");if(r){var n={i:"am",we:"are",they:"are"};n.hasOwnProperty(r)&&(e=n[r])}var a=e+" "+t.Gerund,i=this.replaceWith(a,!1);return i.verb.tag("#Gerund"),i},asAdjective:function(){return i(this.verb.out("normal"))}},f=function(t,e,r,n){return a.call(this,t,e,r,n),c(this)};f.prototype=Object.create(a.prototype),Object.keys(h).forEach(function(t){f.prototype[t]=h[t]}),e.exports=f},{"../../paths":8,"./interpret":76,"./methods/conjugate":81,"./methods/isPlural":86,"./methods/toAdjective":89,"./methods/verbContraction":92,"./toNegative":93}],95:[function(t,e,r){"use strict";var n={punctuation_step:t("./steps/01-punctuation_step"),emoji_step:t("./steps/02-emoji_step"),lexicon_step:t("./steps/03-lexicon_step"),lexicon_multi:t("./steps/04-lexicon_multi"),web_step:t("./steps/05-web_step"),suffix_step:t("./steps/06-suffix_step"),neighbour_step:t("./steps/07-neighbour_step"),capital_step:t("./steps/08-capital_step"),noun_fallback:t("./steps/09-noun_fallback"),contraction:t("./steps/10-contraction_step"),date_step:t("./steps/11-date_step"),auxiliary_step:t("./steps/12-auxiliary_step"),negation_step:t("./steps/13-negation_step"),comma_step:t("./steps/14-comma_step"),quotation_step:t("./steps/15-quotation_step"),possessive_step:t("./steps/16-possessive_step"),acronym_step:t("./steps/17-acronym_step"),person_step:t("./steps/18-person_step"),organization_step:t("./steps/19-organization_step"),parentheses_step:t("./steps/20-parentheses_step"),plural_step:t("./steps/21-plural_step"),value_step:t("./steps/22-value_step"),corrections:t("./steps/23-corrections"),properNoun:t("./steps/24-proper_noun"),custom:t("./steps/25-custom")},a=t("./phrase");e.exports=function(t){return t=n.punctuation_step(t),t=n.emoji_step(t),t=n.lexicon_step(t),t=n.lexicon_multi(t),t=n.web_step(t),t=n.suffix_step(t),t=n.comma_step(t),t=n.neighbour_step(t),t=n.capital_step(t),t=n.noun_fallback(t),t=n.contraction(t),t=n.date_step(t),t=n.auxiliary_step(t),t=n.negation_step(t),t=n.quotation_step(t),t=n.possessive_step(t),t=n.acronym_step(t),t=n.person_step(t),t=n.organization_step(t),t=n.parentheses_step(t),t=n.plural_step(t),t=n.value_step(t),t=n.corrections(t),t=n.properNoun(t),t=a(t),n.custom(t)}},{"./phrase":98,"./steps/01-punctuation_step":99,"./steps/02-emoji_step":100,"./steps/03-lexicon_step":101,"./steps/04-lexicon_multi":102,"./steps/05-web_step":103,"./steps/06-suffix_step":104,"./steps/07-neighbour_step":105,"./steps/08-capital_step":106,"./steps/09-noun_fallback":107,"./steps/10-contraction_step":108,"./steps/11-date_step":109,"./steps/12-auxiliary_step":110,"./steps/13-negation_step":111,"./steps/14-comma_step":112,"./steps/15-quotation_step":113,"./steps/16-possessive_step":114,"./steps/17-acronym_step":115,"./steps/18-person_step":116,"./steps/19-organization_step":117,"./steps/20-parentheses_step":118,"./steps/21-plural_step":119,"./steps/22-value_step":120,"./steps/23-corrections":121,"./steps/24-proper_noun":122,"./steps/25-custom":123}],96:[function(t,e,r){"use strict";e.exports=function(t){var e=t.match("#Condition .{1,7} #ClauseEnd");return e.found&&e.match("#Comma$")&&e.tag("Condition"),(e=t.match("#Condition .{1,13} #ClauseEnd #Pronoun")).found&&e.match("#Comma$")&&e.not("#Pronoun$").tag("Condition","end-pronoun"),(e=t.match("#Condition .{1,7} then")).found&&e.not("then$").tag("Condition","cond-then"),(e=t.match("as long as .{1,7} (then|#ClauseEnd)")).found&&e.not("then$").tag("Condition","as-long-then"),(e=t.match("#Comma #Condition .{1,7} .$")).found&&e.not("^#Comma").tag("Condition","comma-7-end"),(e=t.match("#Condition .{1,4}$")).found&&e.tag("Condition","cond-4-end"),t}},{}],97:[function(t,e,r){"use strict";e.exports=function(t){return t.has("(#Verb|#Auxiliary)")&&(t.match("#Verb").tag("VerbPhrase","verbphrase-verb"),t.match("#Adverb #Verb").tag("VerbPhrase","adverb-verb"),t.match("#Verb #Adverb").tag("VerbPhrase","verb-adverb"),t.match("#Verb #Negative").tag("VerbPhrase","verb-not"),t.match("never #Verb").tag("VerbPhrase","not-verb"),t.match("#Auxiliary+").tag("VerbPhrase","2"),t.match("#Copula").tag("VerbPhrase","#3"),t.match("#Adverb #Auxiliary").tag("VerbPhrase","#4")),t}},{}],98:[function(t,e,r){"use strict";var n=t("./00-conditionPass"),a=t("./01-verbPhrase");e.exports=function(t){return t=n(t),a(t)}},{"./00-conditionPass":96,"./01-verbPhrase":97}],99:[function(t,e,r){"use strict";var u=/^[A-Z][a-z']/,l=/^[IVXCM]+$/,c={a:!0,i:!0,u:!0,r:!0,c:!0,k:!0};e.exports=function(o){var s=o.world.regex||[];return o.terms.forEach(function(t,e){var r,n=t.text;!0===u.test(n)&&t.tag("TitleCase","punct-rule"),"-"===t.whitespace.after&&o.terms[e+1]&&""===o.terms[e+1].whitespace.before&&(t.tag("Hyphenated","has-hyphen"),o.terms[e+1].tag("Hyphenated","has-hyphen")),"("===t.text[0]&&t.tag("StartBracket"),!0===/\)[,.?!;:]?$/.test(t.text)&&t.tag("EndBracket"),n=n.replace(/[,\.\?]$/,"");for(var a=0;a<s.length;a++){var i=s[a];if(!0===i.reg.test(n))return void(t.canBe(i.tag)&&t.tag(i.tag,'punctuation-rule- "'+i.reg.toString()+'"'))}1===n.length&&o.terms[e+1]&&/[A-Z]/.test(n)&&!c[n.toLowerCase()]&&t.tag("Acronym","one-letter-acronym"),1<(r=t).text.length&&!0===l.test(r.text)&&r.canBe("RomanNumeral")&&t.tag("RomanNumeral","is-roman-numeral"),!0===/[0-9]\+$/.test(t.text)&&t.tag("NumericValue","number-plus")}),o}},{}],100:[function(t,e,r){"use strict";var i=t("./rules/emoji_regex"),o=t("./rules/emoticon_list");e.exports=function(t){for(var e=0;e<t.terms.length;e++){var r=t.terms[e];":"!==(a=r).text.charAt(0)||null===a.text.match(/:.?$/)||a.text.match(" ")||35<a.text.length||r.tag("Emoji","comma-emoji"),r.text.match(i)&&r.tag("Emoji","unicode-emoji"),n=r.text.replace(/^[:;]/,":"),!0===o.hasOwnProperty(n)&&r.tag("Emoji","emoticon-emoji")}var n,a;return t}},{"./rules/emoji_regex":130,"./rules/emoticon_list":131}],101:[function(t,e,r){"use strict";var o=t("./contraction/split");e.exports=function(t){for(var e=t.world.words||{},r=0;r<t.terms.length;r++){var n=t.terms[r];if(!0!==e.hasOwnProperty(n.normal))if(n.silent_term&&!0===e.hasOwnProperty(n.silent_term))n.tag(e[n.silent_term],"silent_term-lexicon");else if(n.root&&n.normal!==n.root&&!0===e.hasOwnProperty(n.root))n.tag(e[n.root],"lexicon");else{var a=o(n);if(a&&a.start){var i=a.start.toLowerCase();if(!0===e.hasOwnProperty(i)){n.tag(e[i],"contraction-lexicon");continue}}}else n.tag(e[n.normal],"lexicon")}return t}},{"./contraction/split":129}],102:[function(t,e,r){"use strict";var a=function(t,e,r){var n=r.words,a=t.terms[e].root,i=t.terms.slice(e+1,e+4).map(function(t){return t.root}),o=4;i.length<o&&(o=i.length);for(var s=o;0<s;s-=1){var u=a+" "+i.slice(0,s).join(" ");if(!0===n.hasOwnProperty(u))return t.slice(e,e+s+1).tag(n[u],"multi-lexicon-"+u),s}return 0};e.exports=function(t){t.world.cache=t.world.cache||{};for(var e=t.world.cache.firstWords||{},r=0;r<t.terms.length;r++){var n=t.terms[r];!0!==e.hasOwnProperty(n.root)||(r+=a(t,r,t.world))}return t}},{}],103:[function(t,e,r){"use strict";var a=/^\w+@\w+\.[a-z]{2,3}$/,i=/^#[a-z0-9_]{2,}$/,o=/^@\w{2,}$/,s=/^(https?:\/\/|www\.)\w+\.[a-z]{2,3}/,u=/^[\w\.\/]+\.(com|net|gov|org|ly|edu|info|biz|ru|jp|de|in|uk|br)/;e.exports=function(t){for(var e=0;e<t.length;e++){var r=t.get(e),n=r.text.trim().toLowerCase();!0===a.test(n)&&r.tag("Email","web_pass"),!0===i.test(n)&&r.tag("HashTag","web_pass"),!0===o.test(n)&&r.tag("AtMention","web_pass"),!0!==s.test(n)&&!0!==u.test(n)||r.tag("Url","web_pass")}return t}},{}],104:[function(t,e,r){"use strict";var a=t("./rules/regex_list"),i=t("./rules/suffix_lookup"),o=[[/^(lol)+[sz]$/,"Expression"],[/^ma?cd[aeiou]/,"LastName"],[/^[\-\+]?[0-9][0-9,]*(\.[0-9])*$/,"Cardinal"],[/^(un|de|re)\\-[a-z]../,"Verb"],[/^[\-\+]?[0-9]+(\.[0-9])*$/,"NumericValue"],[/^https?\:?\/\/[a-z0-9]/,"Url"],[/^www\.[a-z0-9]/,"Url"],[/^(over|under)[a-z]{2,}/,"Adjective"],[/^[0-9]{1,4}\.[0-9]{1,2}\.[0-9]{1,4}$/,"Date"],[/^[0-9]+([a-z]{1,2})$/,"Value"],[/^[0-9][0-9,\.]*(st|nd|rd|r?th)$/,["NumericValue","Ordinal"]],[/[a-z]*\\-[a-z]*\\-/,"Adjective"]],s=function(t){var e=t.normal.length,r=7;e<=r&&(r=e-1);for(var n=r;1<n;n-=1){var a=t.normal.substr(e-n,e);if(void 0!==i[n][a])return i[n][a]}return null},u=function(t){var e=t.normal.charAt(t.normal.length-1);if(void 0===a[e])return null;for(var r=a[e],n=0;n<r.length;n++)if(!0===r[n][0].test(t.normal))return r[n];return null};e.exports=function(t){for(var e=0;e<t.terms.length;e++){var r=t.terms[e],n=s(r);if(null===n||!0!==r.canBe(n))if(null===(n=u(r))||!0!==r.canBe(n[1]))for(var a=0;a<o.length;a++)!0===o[a][0].test(r.normal)&&(n=o[a][1],!0===r.canBe(n)&&r.tag(n,"misc-regex-"+o[a][0]));else r.tag(n[1],"regex-list: "+String(n[0]));else r.tag(n,"suffix-lookup")}return t}},{"./rules/regex_list":133,"./rules/suffix_lookup":134}],105:[function(t,e,r){"use strict";var n=t("./rules/neighbours"),l=n.afterThisWord,c=n.beforeThisWord,h=n.beforeThisPos,f=n.afterThisPos,m={TitleCase:!0,UpperCase:!0,CamelCase:!0,Hyphenated:!0,StartBracket:!0,EndBracket:!0,Comma:!0,ClauseEnd:!0};e.exports=function(u){return u.terms.forEach(function(t,e){var r=Object.keys(t.tags);if(0===(r=r.filter(function(t){return!1===m.hasOwnProperty(t)})).length){var n=u.terms[e-1],a=u.terms[e+1];if(n&&l.hasOwnProperty(n.normal)&&!n.tags.ClauseEnd)return void t.tag(l[n.normal],'neighbour-after-"'+n.normal+'"');if(!t.tags.ClauseEnd&&a&&c.hasOwnProperty(a.normal))return void t.tag(c[a.normal],'neighbour-before-"'+a.normal+'"');var i=[];if(n){i=Object.keys(n.tags);for(var o=0;o<i.length;o++)if(f[i[o]])return void t.tag(f[i[o]],"neighbour-after-["+i[o]+"]")}if(a){i=Object.keys(a.tags);for(var s=0;s<i.length;s++)if(h[i[s]])return void t.tag(h[i[s]],"neighbour-before-["+i[s]+"]")}}}),u}},{"./rules/neighbours":132}],106:[function(t,e,r){"use strict";e.exports=function(t){for(var e=1;e<t.terms.length;e++){var r=t.terms[e];r.tags.TitleCase&&r.isWord()&&(r.tag("Noun","capital-step"),r.tag("TitleCase","capital-step"))}var n=t.terms[0];return n&&n.tags.TitleCase&&(n.tags.Person||n.tags.Organization||n.tags.Place)&&n.tag("TitleCase","first-term-capital"),t}},{}],107:[function(t,e,r){"use strict";var n={TitleCase:!0,UpperCase:!0,CamelCase:!0,Hyphenated:!0,StartBracket:!0,EndBracket:!0,Comma:!0,ClauseEnd:!0},a=function(t){if(t.tags.Noun||t.tags.Verb||t.tags.Adjective)return!1;var e=Object.keys(t.tags);return 0===e.length||0===e.filter(function(t){return!n[t]}).length},i=function(t){if(!0===/^(re|un)-?[^aeiou]./.test(t.normal)){var e=t.normal.replace(/^(re|un)-?/,"");if(!0===t.world.words.hasOwnProperty(e)){var r=t.world.words[e];if("Infinitive"===r||"PresentTense"===r||"PastTense"===r||"Gerund"===r)return r}}return null};e.exports=function(t){for(var e=0;e<t.terms.length;e++){var r=t.terms[e];if(!r.tags.Noun&&!r.tags.Verb&&a(r)){if(!1===r.isWord())continue;var n=i(r);if(null!==n){r.tag(n,"root-tag-match");continue}r.tag("Noun","noun-fallback")}}return t}},{}],108:[function(t,e,r){"use strict";var n=t("./contraction/01-irregulars"),a=t("./contraction/02-isWasHas"),i=t("./contraction/03-easyOnes"),o=t("./contraction/04-numberRange");e.exports=function(t){return t=n(t),t=a(t),t=i(t),o(t)}},{"./contraction/01-irregulars":124,"./contraction/02-isWasHas":125,"./contraction/03-easyOnes":126,"./contraction/04-numberRange":127}],109:[function(t,e,r){"use strict";var o="(in|by|before|during|on|until|after|of|within|all)",s="(last|next|this|previous|current|upcoming|coming)",u="(start|end|middle|starting|ending|midpoint|beginning)",l="(spring|summer|winter|fall|autumn)",c=function(t,r){!0===t.found&&t.list.forEach(function(t){var e=parseInt(t.terms[0].normal,10);e&&1e3<e&&e<3e3&&t.terms[0].tag("Year",r)})},h=function(t,r){!0===t.found&&t.list.forEach(function(t){var e=parseInt(t.terms[0].normal,10);e&&1900<e&&e<2030&&t.terms[0].tag("Year",r)})};e.exports=function(t){var e="(january|april|may|june|summer|autumn|jan|sep)";t.has(e)&&(t.match("#Infinitive #Determiner? #Adjective? #Noun? (to|for) ".concat(e)).lastTerm().tag("Person","ambig-person"),t.match("#Infinitive ".concat(e)).lastTerm().tag("Person","infinitive-person"),t.match("".concat(e," #PresentTense (to|for)")).firstTerm().tag("Person","ambig-active"),t.match("".concat(e," #Modal")).firstTerm().tag("Person","ambig-modal"),t.match("#Modal ".concat(e)).lastTerm().tag("Person","modal-ambig"),t.match("(that|with|for) ".concat(e)).term(1).tag("Person","that-month"),t.match("#Copula ".concat(e)).term(1).tag("Person","is-may"),t.match("".concat(e," #Copula")).term(0).tag("Person","may-is"),t.match("".concat(e," the? #Value")).term(0).tag("Month","person-value"),t.match("#Date ".concat(e)).term(1).tag("Month","correction-may"),t.match("".concat(e," the? #Value")).firstTerm().tag("Month","may-5th"),t.match("#Value of ".concat(e)).lastTerm().tag("Month","5th-of-may"),t.match("".concat(o," ").concat(e)).ifNo("#Holiday").term(1).tag("Month","preps-month"),t.match("(next|this|last) ".concat(e)).term(1).tag("Month","correction-may"));var r="(may|march)";if(t.has(r)&&(t.match("#Adverb ".concat(r)).lastTerm().tag("Infinitive","ambig-verb"),t.match("".concat(r," #Adverb")).lastTerm().tag("Infinitive","ambig-verb"),t.match("".concat(o," ").concat(r)).lastTerm().tag("Month","in-month"),t.match("(next|this|last) ".concat(r)).lastTerm().tag("Month","this-month"),t.match("".concat(r," the? #Value")).firstTerm().tag("Month","march-5th"),t.match("#Value of? ".concat(r)).lastTerm().tag("Month","5th-of-march"),t.match("[".concat(r,"] .? #Date")).lastTerm().tag("Month","march-and-feb"),t.match("#Date .? [".concat(r,"]")).lastTerm().tag("Month","feb-and-march"),t.has("march")&&(t.match("march (up|down|back|to|toward)").term(0).tag("Infinitive","march-to"),t.match("#Modal march").term(1).tag("Infinitive","must-march"))),t.has("sun")&&(t.match("sun #Date").firstTerm().tag("WeekDay","sun-feb"),t.match("sun the #Ordinal").tag("Date").firstTerm().tag("WeekDay","sun-the-5th"),t.match("#Determiner sun").lastTerm().tag("Singular","the-sun")),t.has("sat")&&(t.match("sat #Date").firstTerm().tag("WeekDay","sat-feb"),t.match("".concat(o," sat")).lastTerm().tag("WeekDay","sat")),t.has("#Month")&&(t.match("#Month #DateRange+").tag("Date","correction-numberRange"),t.match("#Value of #Month").tag("Date","value-of-month"),t.match("#Cardinal #Month").tag("Date","cardinal-month"),t.match("#Month #Value to #Value").tag("Date","value-to-value"),t.match("#Month the #Value").tag("Date","month-the-value")),t.match("in the (night|evening|morning|afternoon|day|daytime)").tag("Time","in-the-night"),t.match("(#Value|#Time) (am|pm)").tag("Time","value-ampm"),t.has("#Value")){t.match("for #Value #Duration").tag("Date","for-x-duration"),t.match("#Value #Abbreviation").tag("Value","value-abbr"),t.match("a #Value").if("(hundred|thousand|million|billion|trillion|quadrillion|quintillion|sextillion|septillion)").tag("Value","a-value"),t.match("(minus|negative) #Value").tag("Value","minus-value"),t.match("#Value grand").tag("Value","value-grand"),t.match("(half|quarter) #Ordinal").tag("Value","half-ordinal"),t.match("(hundred|thousand|million|billion|trillion|quadrillion|quintillion|sextillion|septillion) and #Value").tag("Value","magnitude-and-value"),t.match("#Value (point|decimal) #Value").tag("Value","value-point-value"),t.match("".concat(o,"? #Value #Duration")).tag("Date","value-duration"),t.match("(#WeekDay|#Month) #Value").ifNo("#Money").tag("Date","date-value"),t.match("#Value (#WeekDay|#Month)").ifNo("#Money").tag("Date","value-date");var n=t.match("#TextValue #TextValue");n.found&&n.has("#Date")&&n.tag("#Date","textvalue-date"),t.match("#Value #Duration #Conjunction").tag("Date","val-duration-conjunction"),t.match("#Value #Duration old").unTag("Date","val-years-old")}if(t.has(l)&&(t.match("".concat(o,"? ").concat(s," ").concat(l)).tag("Date","thisNext-season"),t.match("the? ".concat(u," of ").concat(l)).tag("Date","section-season")),t.has("#Date")&&(t.match("#Date the? #Ordinal").tag("Date","correction-date"),t.match("".concat(s," #Date")).tag("Date","thisNext-date"),t.match("due? (by|before|after|until) #Date").tag("Date","by-date"),t.match("#Date (by|before|after|at|@|about) #Cardinal").not("^#Date").tag("Time","date-before-Cardinal"),t.match("#Date (am|pm)").term(1).unTag("Verb").unTag("Copula").tag("Time","date-am"),t.match("(last|next|this|previous|current|upcoming|coming|the) #Date").tag("Date","next-feb"),t.match("#Date (#Preposition|to) #Date").tag("Date","date-prep-date"),t.match("the? ".concat(u," of #Date")).tag("Date","section-of-date"),t.match("#Ordinal #Duration in #Date").tag("Date","duration-in-date"),t.match("(early|late) (at|in)? the? #Date").tag("Time","early-evening")),t.has("#Cardinal")){var a=t.match("#Date #Value #Cardinal").lastTerm();c(a,"date-value-year"),a=t.match("#Date+ #Cardinal").lastTerm(),c(a,"date-year"),a=t.match("#Month #Value #Cardinal").lastTerm(),c(a,"month-value-year"),a=t.match("#Month #Value to #Value #Cardinal").lastTerm(),c(a,"month-range-year"),a=t.match("(in|of|by|during|before|starting|ending|for|year) #Cardinal").lastTerm(),c(a,"in-year"),a=t.match("(q1|q2|q3|q4) [#Cardinal]"),c(a,"in-year"),a=t.match("#Ordinal quarter [#Cardinal]"),c(a,"in-year"),a=t.match("the year [#Cardinal]"),c(a,"in-year"),a=t.match("it (is|was) [#Cardinal]"),h(a,"in-year"),a=t.match("#Cardinal !#Plural").firstTerm(),h(a,"year-unsafe")}if(t.has("#Date")){t.has("#Time")&&(t.match("#Cardinal #Time").not("#Year").tag("Time","value-time"),t.match("(by|before|after|at|@|about) #Time").tag("Time","preposition-time"),t.match("#Time (eastern|pacific|central|mountain)").term(1).tag("Time","timezone"),t.match("#Time (est|pst|gmt)").term(1).tag("Time","timezone abbr"));var i=t.match("#Date+").splitOn("Clause");!1===i.has("(#Year|#Time)")&&i.match("#Value (#Month|#Weekday) #Value").lastTerm().unTag("Date")}return t}},{}],110:[function(t,e,r){"use strict";var a={do:!0,"don't":!0,does:!0,"doesn't":!0,will:!0,wont:!0,"won't":!0,have:!0,"haven't":!0,had:!0,"hadn't":!0,not:!0};e.exports=function(t){for(var e=0;e<t.terms.length;e++){var r=t.terms[e];if(a[r.normal]||a[r.silent_term]){var n=t.terms[e+1];if(n&&(n.tags.Verb||n.tags.Adverb||n.tags.Negative)){r.tag("Auxiliary","corrections-Auxiliary");continue}}}return t}},{}],111:[function(t,e,r){"use strict";e.exports=function(t){for(var e=0;e<t.length;e++){var r=t.get(e);if("not"===r.normal||"not"===r.silent_term)for(var n=e+1;n<t.length;n++){if(t.get(n).tags.Verb){r.tag("VerbPhrase","negate-verb");break}if(t.get(n).tags.Adjective){r.tag("AdjectivePhrase","negate-adj");break}}}return t}},{}],112:[function(t,e,r){"use strict";var c=function(t,e){var r,n=e,a=(r=t.terms[e]).tags.Adjective?"Adjective":r.tags.Noun?"Noun":r.tags.Verb?"Verb":r.tags.Value?"Value":null,i=0,o=0,s=!1;for(e+=1;e<t.terms.length;e++){var u=t.terms[e];if(0<o&&u.tags.Conjunction)s=!0;else{if(u.tags[a]){if(u.tags.Comma){o+=1,i=0;continue}if(0<o&&s)return t.slice(n,e).tag("List"),!0}if(5<(i+=1))return!1;if("Value"===a)return!0}}return!1};e.exports=function(t){for(var e=0;e<t.terms.length;e++){var r=t.terms[e],n=r.getPunctuation();","!==n?";"!==n&&":"!==n?r.whitespace.after.match(/^\.\./)?r.tag("ClauseEnd","clause-elipses"):t.terms[e+1]&&t.terms[e+1].whitespace.before.match(/ - /)&&r.tag("ClauseEnd","hypen-clause"):r.tag("ClauseEnd","clause-punt"):r.tag("Comma","comma-step")}for(var a=0;a<t.terms.length;a++){var i=t.terms[a];if(i.tags.Comma){if(i.tags.List)continue;if(s=a,u=(o=t).terms[s],(l=o.terms[s+1])&&u.tags.Place&&!u.tags.Country&&l.tags.Country)continue;c(t,a)||i.tag("ClauseEnd","phrasal-comma")}}var o,s,u,l;return t}},{}],113:[function(t,e,r){"use strict";var l={'"':{close:'"',tag:"StraightDoubleQuotes"},""":{close:""",tag:"StraightDoubleQuotesWide"},"'":{close:"'",tag:"StraightSingleQuotes"},"“":{close:"”",tag:"CommaDoubleQuotes"},"‘":{close:"’",tag:"CommaSingleQuotes"},"‟":{close:"”",tag:"CurlyDoubleQuotesReversed"},"‛":{close:"’",tag:"CurlySingleQuotesReversed"},"„":{close:"”",tag:"LowCurlyDoubleQuotes"},"⹂":{close:"”",tag:"LowCurlyDoubleQuotesReversed"},"‚":{close:"’",tag:"LowCurlySingleQuotes"},"«":{close:"»",tag:"AngleDoubleQuotes"},"‹":{close:"›",tag:"AngleSingleQuotes"},"‵":{close:"′",tag:"PrimeSingleQuotes"},"‶":{close:"″",tag:"PrimeDoubleQuotes"},"‷":{close:"‴",tag:"PrimeTripleQuotes"},"〝":{close:"〞",tag:"PrimeDoubleQuotes"},"`":{close:"´",tag:"PrimeSingleQuotes"},"〟":{close:"〞",tag:"LowPrimeDoubleQuotesReversed"}};Object.keys(l).forEach(function(t){l[t].regex=new RegExp(l[t].close+"[;:,.]*"),l[t].open=t});var c=new RegExp("["+Object.keys(l).join("")+"]");e.exports=function(t){for(var e=t.terms.slice(0),r=0;r<e.length;r++){var n=t.terms[r];if(c.test(n.whitespace.before)){var a=n.whitespace.before.match(c).shift().split("");a=a.map(function(t){return l[t]});for(var i=0;i<t.terms.length&&e[r+i]&&!(28<i);i++){for(var o=-1,s=0;s<a.length;s+=1)if(!0===a[s].regex.test(e[r+i].whitespace.after)){o=s;break}if(-1!==o){var u=a.splice(o,1).pop();if(u.regex.test(t.terms[r+i].normal)&&t.terms[r+i].whitespace.after.replace(u.regex,""),n.tag("StartQuotation","quotation_open"),t.terms[r+i].tag("EndQuotation","quotation_close"),t.slice(r,r+i+1).tag("Quotation","quotation_step"),i-=1,!a.length)break}}}}return t}},{}],114:[function(t,e,r){"use strict";var l=["it's","that's"],n="'‘’‛‚‵′`´",c=new RegExp("([a-z]s["+n+"])\\W*$"),h=new RegExp("["+n+"]"),s=new RegExp("[^"+n+"\\w]+$"),u={};[["'","'"],["‘","’"],["‛","’"],["‚","’"],["‵","′"],["`","´"]].forEach(function(t){u[t[0]]=new RegExp(t[1]+"[^"+t[1]+"\\w]*$")}),l.map(function(t){return new RegExp(t.replace("'","["+n+"]"))});var f=function(t,e,r){var n=t.get(r),a=t.get(r+1),i=t.get(r+2),o=l.map(function(t){return e.match(t)}).find(function(t){return t}),s=h.test(n.whitespace.after),u=n.tags.Pronoun;return!(o||u||!s||!c.test(e)&&void 0!==a&&!0!==a.tags.Noun&&!0!==n.tags.ClauseEnd&&(void 0===i||!a.tags.Adjective||!i.tags.Noun))};e.exports=function(t){for(var e=[],r=0;r<t.length;r++){var n=t.get(r),a=n.text;void 0!==u[a[0]]&&(e[e.length]=u[a[0]],a=a.slice(1)),a=a.replace(s,"");for(var i=-1,o=0;o<e.length;o+=1)if(!0===e[o].test(a)){i=o;break}-1!==i&&(a=a.replace(e[i],""),delete e[i]),a=a.replace(s,""),f(t,a,r)&&(n.tags.Noun||n.tag("Noun","possessive_pass"),n.tag("Possessive","possessive_pass"),!0===n.tags.Contraction&&(n.unTag("Contraction"),t.terms.splice(r+1,1),n.silent_term=""))}return t}},{}],115:[function(t,e,r){"use strict";e.exports=function(t){return t.terms.forEach(function(t){t.isAcronym()&&t.tag("Acronym","acronym-step")}),t}},{}],116:[function(t,e,r){"use strict";e.exports=function(t){t.match("(mr|mrs|ms|dr) (#TitleCase|#Possessive)+").tag("#Person","mr-putin");var e="(rose|robin|dawn|ray|holly|bill|joy|viola|penny|sky|violet|daisy|melody|kelvin|hope|mercedes|olive|jewel|faith|van|charity|miles|lily|summer|dolly|rod|dick|cliff|lane|reed|kitty|art|jean|trinity)";t.has(e)&&(t.match("(#Determiner|#Adverb|#Pronoun|#Possessive) ["+e+"]").tag("Noun","the-ray"),t.match(e+" (#Person|#Acronym|#TitleCase)").canBe("#Person").tag("Person","ray-smith"));var r="(pat|wade|ollie|will|rob|buck|bob|mark|jack)";t.has(r)&&(t.match("(#Modal|#Adverb) ["+r+"]").tag("Verb","would-mark"),t.match(r+" (#Person|#TitleCase)").tag("Person","rob-smith"));var n="(misty|rusty|dusty|rich|randy)";t.has(n)&&(t.match("#Adverb ["+n+"]").tag("Adjective","really-rich"),t.match(n+" (#Person|#TitleCase)").tag("Person","randy-smith"));var a="(april|june|may|jan|august|eve)";t.has(a)&&(t.match(String(a)+" (#Person|#TitleCase)").canBe("#Person").tag("Person","june-smith"),t.match("(in|during|on|by|before|#Date) ["+a+"]").canBe("#Date").tag("Date","in-june"),t.match(a+" (#Date|#Value)").canBe("#Date").tag("Date","june-5th"));var i="(paris|alexandria|houston|kobe|salvador|sydney)";return t.has(i)&&(t.match("(in|near|at|from|to|#Place) ["+i+"]").canBe("#Place").tag("Place","in-paris"),t.match("["+i+"] #Place").canBe("#Place").tag("Place","paris-france"),t.match("["+i+"] #Person").canBe("#Person").tag("Person","paris-hilton")),t.match("al")&&(t.match("al (#Person|#TitleCase)").canBe("#Person").tag("#Person","al-borlen"),t.match("#TitleCase al #TitleCase").canBe("#Person").tag("#Person","arabic-al-arabic")),t.match("(private|general|major|corporal|lord|lady|secretary|premier) #Honorific? #Person").terms(0).tag("Honorific","ambg-honorifics"),t.match("(1st|2nd|first|second) #Honorific").terms(0).tag("Honorific","ordinal-honorific"),t.has("#FirstName")&&(t.match("#FirstName #Noun").ifNo("^#Possessive").ifNo("#ClauseEnd .").lastTerm().canBe("#LastName").tag("#LastName","firstname-noun"),t.match("#FirstName de #Noun").canBe("#Person").tag("#Person","firstname-de-noun"),t.match("#FirstName (bin|al) #Noun").canBe("#Person").tag("#Person","firstname-al-noun"),t.match("#FirstName #Acronym #TitleCase").tag("Person","firstname-acronym-titlecase"),t.match("#FirstName #FirstName #TitleCase").tag("Person","firstname-firstname-titlecase"),t.match("#Honorific #FirstName? #TitleCase").tag("Person","Honorific-TitleCase"),t.match("#FirstName #TitleCase #TitleCase?").match("#Noun+").tag("Person","firstname-titlecase"),t.match("#FirstName the #Adjective").tag("Person","correction-determiner5"),t.match("#FirstName (green|white|brown|hall|young|king|hill|cook|gray|price)").tag("#Person","firstname-maybe"),t.match("#FirstName #Acronym #Noun").ifNo("#Date").tag("#Person","n-acro-noun").lastTerm().tag("#LastName","n-acro-noun"),t.match("#FirstName [#Determiner? #Noun] #LastName").tag("#NickName","first-noun-last").tag("#Person","first-noun-last"),t.match("#FirstName (#Singular|#Possessive)").ifNo("#Date").ifNo("#NickName").tag("#Person","first-possessive").lastTerm().tag("#LastName","first-possessive")),t.has("#LastName")&&(t.match("#Noun #LastName").firstTerm().canBe("#FirstName").tag("#FirstName","noun-lastname"),t.match("(will|may|april|june|said|rob|wade|ray|rusty|drew|miles|jack|chuck|randy|jan|pat|cliff|bill) #LastName").firstTerm().tag("#FirstName","maybe-lastname"),t.match("#TitleCase #Acronym? #LastName").ifNo("#Date").tag("#Person","title-acro-noun").lastTerm().tag("#LastName","title-acro-noun"),t.match("#Copula (#Noun|#PresentTense) #LastName").term(1).tag("#FirstName","copula-noun-lastname")),t.has("#TitleCase")&&(t.match("#Acronym #TitleCase").canBe("#Person").tag("#Person","acronym-titlecase"),t.match("#TitleCase (van|al|bin) #TitleCase").canBe("#Person").tag("Person","correction-titlecase-van-titlecase"),t.match("#TitleCase (de|du) la? #TitleCase").canBe("#Person").tag("Person","correction-titlecase-van-titlecase"),t.match("#Person #TitleCase").match("#TitleCase #Noun").canBe("#Person").tag("Person","correction-person-titlecase"),t.match("(lady|queen|sister) #TitleCase").ifNo("#Date").ifNo("#Honorific").tag("#FemaleName","lady-titlecase"),t.match("(king|pope|father) #TitleCase").ifNo("#Date").tag("#MaleName","correction-poe")),t.match("#Noun van der? #Noun").canBe("#Person").tag("#Person","von der noun"),t.match("(king|queen|prince|saint|lady) of? #Noun").canBe("#Person").tag("#Person","king-of-noun"),t.match("#Honorific #Acronym").tag("Person","Honorific-TitleCase"),t.match("#Person #Person the? #RomanNumeral").tag("Person","correction-roman-numeral"),t.match("#Honorific #Person").tag("Person","Honorific-Person"),t.match("^#Honorific$").unTag("Person","single-honorific"),t}},{}],117:[function(t,e,r){"use strict";var i=t("../../world/more-data/orgWords"),o=function(t){return!(!t.tags.Noun||t.tags.Pronoun||t.tags.Comma||t.tags.Possessive||t.tags.Place||!(t.tags.TitleCase||t.tags.Organization||t.tags.Acronym))};e.exports=function(t){for(var e=0;e<t.terms.length;e++){var r=t.terms[e];if(!0===i.hasOwnProperty(r.root)){var n=t.terms[e-1];if(n&&o(n)){n.tag("Organization","org-word-1"),r.tag("Organization","org-word-2");continue}var a=t.terms[e+1];if(a&&"of"===a.normal&&t.terms[e+2]&&o(t.terms[e+2])){r.tag("Organization","org-of-word-1"),a.tag("Organization","org-of-word-2"),t.terms[e+2].tag("Organization","org-of-word-3");continue}}}return t.has("#Acronym")&&(t.match("the #Acronym").not("(iou|fomo|yolo|diy|dui|nimby)").lastTerm().tag("Organization","the-acronym"),t.match("#Acronym").match("#Possessive").tag("Organization","possessive-acronym")),t}},{"../../world/more-data/orgWords":221}],118:[function(t,e,r){"use strict";e.exports=function(n){return n.terms.forEach(function(t,e){if(t.tags.StartBracket)for(var r=e;r<n.terms.length;r+=1)if(!0===n.terms[r].tags.EndBracket){n.slice(e,r+1).tag("Parentheses");break}}),n}},{}],119:[function(t,e,r){"use strict";var a=t("../../subset/nouns/isPlural");e.exports=function(t){for(var e=0;e<t.terms.length;e++){var r=t.terms[e];if(r.tags.Noun){if(r.tags.Singular||r.tags.Plural)continue;var n=a(r,r.world);!0===n?r.tag("Plural","pluralStep"):!1===n&&r.tag("Singular","pluralStep")}}return t}},{"../../subset/nouns/isPlural":39}],120:[function(t,e,r){"use strict";var n=/^\$?[0-9,](\.[0-9])?/,a=/[0-9](st|nd|rd|th)$/;e.exports=function(t){for(var e=0;e<t.terms.length;e++){var r=t.terms[e];!0===r.tags.Value&&void 0===r.tags.Ordinal&&void 0===r.tags.Cardinal&&(!0===n.test(r.normal)?(r.tag("Cardinal","cardinal-val-regex"),r.tag("NumericValue","NumericValue-regex")):!0===a.test(r.normal)&&(r.tag("Ordinal","ordinal-value-regex"),r.tag("NumericValue","NumericValue-regex")))}return t.match("#Cardinal #Plural").lastTerm().tag("Unit","cardinal-plural"),t.match("#Ordinal #Singular").lastTerm().tag("Unit","ordinal-singular"),t}},{}],121:[function(t,e,r){"use strict";e.exports=function(t){if(t.has("so")&&(t.match("so #Adjective").match("so").tag("Adverb","so-adv"),t.match("so #Noun").match("so").tag("Conjunction","so-conj"),t.match("do so").match("so").tag("Noun","so-noun")),t.has("all")&&(t.match("[all] #Determiner? #Noun").tag("Adjective","all-noun"),t.match("[all] #Verb").tag("Adverb","all-verb")),t.has("(that|which)")&&(t.match("#Verb #Adverb? #Noun (that|which)").lastTerm().tag("Preposition","that-prep"),t.match("that #Noun #Verb").firstTerm().tag("Determiner","that-determiner"),t.match("#Comma [which] (#Pronoun|#Verb)").tag("Preposition","which-copula")),t.has("#Determiner")&&(t.match("(the|this) [#Verb] #Preposition .").tag("Noun","correction-determiner1"),t.match("(the|those|these) (#Infinitive|#PresentTense|#PastTense)").term(1).tag("Noun","correction-determiner2"),t.match("(a|an) [#Gerund]").tag("Adjective","correction-a|an"),t.match("(a|an) #Adjective (#Infinitive|#PresentTense)").term(2).tag("Noun","correction-a|an2"),t.match("(some [#Verb] #Plural").tag("Noun","correction-determiner6"),t.match("#Determiner #Adjective$").not("(#Comparative|#Superlative)").term(1).tag("Noun","the-adj-1"),t.match("#Determiner [#Adjective] (#Copula|#PastTense|#Auxiliary)").tag("Noun","the-adj-2"),t.match("(the|this|those|these) #Adjective [#Verb]").tag("Noun","the-adj-verb"),t.match("(the|this|those|these) #Adverb #Adjective [#Verb]").tag("Noun","correction-determiner4"),t.match("(the|this|a|an) [#Infinitive] #Adverb? #Verb").tag("Noun","correction-determiner5"),t.match("#Determiner [#Verb] of").tag("Noun","the-verb-of"),t.match("#Determiner #Noun of [#Verb]").tag("Noun","noun-of-noun"),t.match("#Determiner #Adverb? [close]").tag("Adjective","a-close"),t.match("#Verb (a|an) [#Value]").tag("Singular","a-value"),t.match("(a|an) #Noun [#Infinitive]").tag("Noun","a-noun-inf")),t.has("like")&&(t.match("just [like]").tag("Preposition","like-preposition"),t.match("#Noun [like] #Noun").tag("Preposition","noun-like"),t.match("#Verb [like]").tag("Adverb","verb-like"),t.match("#Adverb like").not("(really|generally|typically|usually|sometimes|often) like").lastTerm().tag("Adverb","adverb-like")),t.has("#Value")&&(t.match("half a? #Value").tag("Value","half-a-value"),t.match("#Value and a (half|quarter)").tag("Value","value-and-a-half"),t.match("#Value+ #Currency").tag("Money","value-currency").lastTerm().tag("Unit","money-unit"),t.match("#Money and #Money #Currency?").tag("Money","money-and-money"),t.match("1 #Value #PhoneNumber").tag("PhoneNumber","1-800-Value"),t.match("#NumericValue #PhoneNumber").tag("PhoneNumber","(800) PhoneNumber"),t.match("#TextValue+").match("#Cardinal+ #Ordinal").tag("Ordinal","two-hundredth")),t.has("#Noun")&&(t.match("more #Noun").tag("Noun","more-noun"),t.match("[second] #Noun").not("#Honorific").unTag("Unit").tag("Ordinal","second-noun"),t.match("#Noun #Adverb [#Noun]").tag("Verb","correction"),t.match("#Noun [#Particle]").tag("Preposition","repair-noPhrasal"),t.match("#Noun (&|n) #Noun").tag("Organization","Noun-&-Noun"),t.match("#Noun #Actor").tag("Actor","thing-doer"),t.match("(this|that) [#Plural]").tag("PresentTense","this-verbs"),t.match("#Determiner #Infinitive$").lastTerm().tag("Noun","a-inf"),t.match("#Determiner [(western|eastern|northern|southern|central)] #Noun").tag("Noun","western-line"),t.match("(#Determiner|#Value) [(linear|binary|mobile|lexical|technical|computer|scientific|formal)] #Noun").tag("Noun","technical-noun"),t.has("#Organization")&&(t.match("#Organization of the? #TitleCase").tag("Organization","org-of-place"),t.match("#Organization #Country").tag("Organization","org-country"),t.match("(world|global|international|national|#Demonym) #Organization").tag("Organization","global-org")),t.has("#Possessive")&&(t.match("#Possessive [#FirstName]").unTag("Person","possessive-name"),t.match("#FirstName #Acronym? #Possessive").notIf("#Comma").match("#FirstName #Acronym? #LastName").tag("Possessive"),t.match("#Organization+ #Possessive").notIf("#Comma").tag("Possessive"),t.match("#Place+ #Possessive").notIf("#Comma").tag("Possessive"))),t.has("#Verb")){if(t.match("[still] #Verb").tag("Adverb","still-verb"),t.match("[u] #Verb").tag("Pronoun","u-pronoun-1"),t.match("is no [#Verb]").tag("Noun","is-no-verb"),t.match("[#Verb] than").tag("Noun","correction"),t.match("#Possessive [#Verb]").tag("Noun","correction-possessive"),t.match("there (are|were) #Adjective? [#PresentTense]").tag("Plural","there-are"),t.has("(who|what|where|why|how|when)")){t.match("^how").tag("QuestionWord","how-question").tag("QuestionWord","how-question"),t.match("how (#Determiner|#Copula|#Modal|#PastTense)").term(0).tag("QuestionWord","how-is"),t.match("^which").tag("QuestionWord","which-question").tag("QuestionWord","which-question"),t.match("which . (#Noun)+ #Pronoun").term(0).tag("QuestionWord","which-question2"),t.match("which").tag("QuestionWord","which-question3");var e=t.match("#QuestionWord #Noun #Copula #Adverb? (#Verb|#Adjective)").firstTerm();e.unTag("QuestionWord").tag("Conjunction","how-he-is-x"),(e=t.match("#QuestionWord #Noun #Adverb? #Infinitive not? #Gerund").firstTerm()).unTag("QuestionWord").tag("Conjunction","when i go fishing")}t.has("#Copula")&&(t.match("#Copula #Adjective to #Verb").match("#Adjective to").tag("Verb","correction"),t.match("#Copula [#Infinitive] #Noun").tag("Noun","is-pres-noun"),t.match("[#Infinitive] #Copula").tag("Noun","infinitive-copula"),t.match("#Copula (pretty|dead|full|well) (#Adjective|#Noun)").notIf("#Comma").tag("#Copula #Adverb #Adjective","sometimes-adverb"),t.match("#Copula [(just|alone)$]").tag("Adjective","not-adverb"));var r="(#Adverb|not)+?";t.has(r)&&(t.match("(has|had) ".concat(r," #PastTense")).not("#Verb$").tag("Auxiliary","had-walked"),t.match("#Copula ".concat(r," #Gerund")).not("#Verb$").tag("Auxiliary","copula-walking"),t.match("(be|been) ".concat(r," #Gerund")).not("#Verb$").tag("Auxiliary","be-walking"),t.match("(#Modal|did) ".concat(r," #Verb")).not("#Verb$").tag("Auxiliary","modal-verb"),t.match("#Modal ".concat(r," have ").concat(r," had ").concat(r," #Verb")).not("#Verb$").tag("Auxiliary","would-have"),t.match("(#Modal) ".concat(r," be ").concat(r," #Verb")).not("#Verb$").tag("Auxiliary","would-be"),t.match("(#Modal|had|has) ".concat(r," been ").concat(r," #Verb")).not("#Verb$").tag("Auxiliary","would-be")),t.match("#PhrasalVerb #PhrasalVerb").lastTerm().tag("Particle","phrasal-particle"),t.has("#Gerund")&&(t.match("#Gerund #Adverb? not? #Copula").firstTerm().tag("Activity","gerund-copula"),t.match("#Gerund #Modal").firstTerm().tag("Activity","gerund-modal"),t.match("#Gerund #Determiner [#Infinitive]").tag("Noun","running-a-show")),t.has("will #Adverb? not? #Adverb? be")&&!1===t.has("will #Adverb? not? #Adverb? be #Gerund")&&(t.match("will not? be").tag("Copula","will-be-copula"),t.match("will #Adverb? not? #Adverb? be #Adjective").match("be").tag("Copula","be-copula"))}if(t.has("#Adjective")&&(t.match("still #Adjective").match("still").tag("Adverb","still-advb"),t.match("#Adjective [#PresentTense]").tag("Noun","adj-presentTense"),t.match("will [#Adjective]").tag("Verb","will-adj"),t.match("#PresentTense (hard|quick|long|bright|slow)").lastTerm().tag("Adverb","lazy-ly"),t.match("(his|her|its) [#Adjective]").tag("Noun","his-fine"),t.match("#Noun #Adverb? [left]").tag("PastTense","left-verb")),t.has("#TitleCase")&&(t.match("#TitleCase (ltd|co|inc|dept|assn|bros)").tag("Organization","org-abbrv"),t.match("#TitleCase+ (district|region|province|county|prefecture|municipality|territory|burough|reservation)").tag("Region","foo-district"),t.match("(district|region|province|municipality|territory|burough|state) of #TitleCase").tag("Region","district-of-Foo")),t.has("#Hyphenated")){t.match("#Hyphenated #Hyphenated").match("#Noun #Verb").tag("Noun","hyphen-verb");var n=t.match("#Hyphenated+");n.has("#Expression")&&n.tag("Expression","ooh-wee")}return t.has("#Place")&&(t.match("(west|north|south|east|western|northern|southern|eastern)+ #Place").tag("Region","west-norfolk"),t.match("#City [#Acronym]").match("(al|ak|az|ar|ca|ct|dc|fl|ga|id|il|nv|nh|nj|ny|oh|or|pa|sc|tn|tx|ut|vt|pr)").tag("Region","us-state")),t.match("(foot|feet)").tag("Noun","foot-noun"),t.match("#Value (foot|feet)").term(1).tag("Unit","foot-unit"),t.match("#Conjunction [u]").tag("Pronoun","u-pronoun-2"),t.match("(a|an) (#Duration|hundred|thousand|million|billion|trillion|quadrillion|quintillion|sextillion|septillion)").ifNo("#Plural").term(0).tag("Value","a-is-one"),t.match("holy (shit|fuck|hell)").tag("Expression","swears-expression"),t.match("#Determiner (shit|damn|hell)").term(1).tag("Noun","swears-noun"),t.match("(shit|damn|fuck) (#Determiner|#Possessive|them)").term(0).tag("Verb","swears-verb"),t.match("#Copula fucked up?").not("#Copula").tag("Adjective","swears-adjective"),t.match("#Holiday (day|eve)").tag("Holiday","holiday-day"),t.match("(standard|daylight|summer|eastern|pacific|central|mountain) standard? time").tag("Time","timezone"),t.match("#Demonym #Currency").tag("Currency","demonym-currency"),t.match("about to #Adverb? #Verb").match("about to").tag(["Auxiliary","Verb"],"about-to"),t.match("#Honorific #Person").tag("Person","honorific-person"),t.match("#Person (jr|sr|md)").tag("Person","person-honorific"),t.match("(right|rights) of .").tag("Noun","right-of"),t}},{}],122:[function(t,e,r){"use strict";e.exports=function(t){return!0===t.has("#Person")&&(t.match("#FirstName #Person+").tag("ProperNoun"),t.match("#Person+ #LastName").tag("ProperNoun")),!0===t.has("#Place")&&t.match("(#City|#Region|#Country)").tag("ProperNoun"),t.match("#Organization").tag("ProperNoun"),t.match("#Month").tag("ProperNoun"),t}},{}],123:[function(t,e,r){"use strict";e.exports=function(e){var r=e.world.patterns;return Object.keys(r).forEach(function(t){e.match(t).tag(r[t],"post-hoc: "+t)}),e}},{}],124:[function(t,e,r){"use strict";var a=t("./fix"),i={wanna:["want","to"],gonna:["going","to"],im:["i","am"],alot:["a","lot"],dont:["do","not"],dun:["do","not"],ive:["i","have"],"won't":["will","not"],wont:["will","not"],"can't":["can","not"],cant:["can","not"],cannot:["can","not"],"shan't":["should","not"],imma:["I","will"],"where'd":["where","did"],whered:["where","did"],"when'd":["when","did"],whend:["when","did"],"how'd":["how","did"],howd:["how","did"],"what'd":["what","did"],whatd:["what","did"],"let's":["let","us"],dunno:["do","not","know"],brb:["be","right","back"],gtg:["got","to","go"],irl:["in","real","life"],tbh:["to","be","honest"],imo:["in","my","opinion"],til:["today","i","learned"],rn:["right","now"],twas:["it","was"],"@":["at"]};e.exports=function(t){for(var e=0;e<t.terms.length;e++){var r=t.terms[e];if(i[r.normal]){var n=i[r.normal];t=a(t,n,e),e+=n.length-1}}return t}},{"./fix":128}],125:[function(t,e,r){"use strict";var c=t("./fix"),h=t("./split"),f={"that's":!0,"there's":!0},a={we:!0,they:!0,you:!0},m=function(t,e){var r=["is","not"];if(t.terms[e-1]){var n=t.terms[e-1];n.tags.Adverb&&t.terms[e-2]&&(n=t.terms[e-2]),(n.tags.Plural||!0===a[n.normal])&&(r[0]="are")}return r};e.exports=function(t){for(var e=0;e<t.terms.length;e++)if(!t.terms[e].silent_term)if("ain't"!==t.terms[e].normal&&"aint"!==t.terms[e].normal){var r=h(t.terms[e]);if(r&&"s"===r.end){if(s=e,u=(o=t).terms[s],l=o.terms[s+1],!u.tags.Pronoun&&!u.tags.QuestionWord&&!f[u.normal]&&(!l||l.tags.Infinitive||!l.tags.VerbPhrase&&(l.tags.Noun||l.tags.Adjective&&o.terms[s+2]&&o.terms[s+2].tags.Noun||(l.tags.Adjective||l.tags.Adverb||l.tags.Verb,0)))){t.terms[e].tag("#Possessive","hard-contraction");continue}var n=[r.start,"is"];if(t.terms[e+1]){var a=t.terms[e].normal;t.match(a+" (#Negative|#Adverb|#Auxiliary)+? #Gerund").found?n=[r.start,"is"]:t.match(a+" (#Negative|#Adverb|#Auxiliary)+? #Verb").found&&(n=[r.start,"has"])}t=c(t,n,e),e+=1}}else{var i=m(t,e);t=c(t,i,e),e+=1}var o,s,u,l;return t}},{"./fix":128,"./split":129}],126:[function(t,e,r){"use strict";var i=t("./fix"),o=t("./split"),s={ll:"will",ve:"have",re:"are",m:"am","n't":"not"};e.exports=function(t){for(var e=0;e<t.terms.length;e++)if(!t.terms[e].silent_term){var r=o(t.terms[e]);if(r){if(r.start=r.start.toLowerCase(),s[r.end]){var n=[r.start,s[r.end]];t=i(t,n,e),e+=1}if("d"===r.end){var a=[r.start,"would"];t.terms[e+1]&&t.terms[e+1].tags.PastTense&&(a[1]="had"),t.terms[e+2]&&t.terms[e+2].tags.PastTense&&t.terms[e+1].tags.Adverb&&(a[1]="had"),t=i(t,a,e),e+=1}}}return t}},{"./fix":128,"./split":129}],127:[function(t,e,r){"use strict";var i=t("./fix"),o=t("../../../term"),s=function(t){var e=/(-|–|—)/;return e.test(t.whitespace.before)||e.test(t.whitespace.after)};e.exports=function(t){t.match("#Hyphenated #Hyphenated").match("#NumericValue #NumericValue").tag("NumberRange");for(var e=0;e<t.terms.length;e++){var r=t.terms[e];if(!r.silent_term&&!r.tags.TextValue){if(r.tags.Value&&t.terms[e+1]&&0<e&&(s(r)||s(t.terms[e-1]))&&t.terms[e-1].tags.Value){var n=new o("",t.world);return n.silent_term="to",t.insertAt(e,n),t.terms[e-1].tag("NumberRange","number-number1"),t.terms[e].tag("NumberRange","number-number2"),t.terms[e].whitespace.before="",t.terms[e].whitespace.after="",t.terms[e+1].tag("NumberRange","number-number3"),t}if(r.tags.NumberRange){var a=r.text.split(/(-|–|—)/);a[1]="to",(t=i(t,a,e)).terms[e].tag(["NumberRange","NumericValue"],"numRange-1"),t.terms[e+1].tag(["NumberRange","Preposition"],"numRange-silent"),t.terms[e+2].tag(["NumberRange","NumericValue"],"numRange-3"),e+=2}}}return t}},{"../../../term":143,"./fix":128}],128:[function(t,e,r){"use strict";var o=t("../../../term"),n={not:"Negative",will:"Verb",would:"Modal",have:"Verb",are:"Copula",is:"Copula",am:"Verb"},s=function(t){n[t.silent_term]&&t.tag(n[t.silent_term])};e.exports=function(t,e,r){var n=t.terms[r];if(n.silent_term=e[0],n.tag("Contraction","tagger-contraction"),e[1]){var a=new o("",t.world);a.silent_term=e[1],a.tag("Contraction","tagger-contraction"),t.insertAt(r+1,a),a.whitespace.before="",a.whitespace.after="",s(a)}if(e[2]){var i=new o("",t.world);i.silent_term=e[2],t.insertAt(r+2,i),i.tag("Contraction","tagger-contraction"),s(i)}return t}},{"../../../term":143}],129:[function(t,e,r){"use strict";var n=/^([a-z]+)'([a-z][a-z]?)$/i,a=/[a-z]s'$/i,i={re:1,ve:1,ll:1,t:1,s:1,d:1,m:1};e.exports=function(t){if("can't"===t.normal)return{start:"can",end:"n't"};var e=t.normal.match(n);return e&&e[1]&&1===i[e[2]]?("t"===e[2]&&e[1].match(/[a-z]n$/)&&(e[1]=e[1].replace(/n$/,""),e[2]="n't"),!0===t.tags.TitleCase&&(e[1]=e[1].replace(/^[a-z]/,function(t){return t.toUpperCase()})),{start:e[1],end:e[2]}):!0===a.test(t.text)?{start:t.normal.replace(/s'?$/,""),end:""}:null}},{}],130:[function(t,e,r){"use strict";e.exports=/(?:0\u20E3\n1\u20E3|2\u20E3|3\u20E3|4\u20E3|5\u20E3|6\u20E3|7\u20E3|8\u20E3|9\u20E3|#\u20E3|\*\u20E3|\uD83C(?:\uDDE6\uD83C(?:\uDDE8|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDEE|\uDDF1|\uDDF2|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFC|\uDDFD|\uDDFF)|\uDDE7\uD83C(?:\uDDE6|\uDDE7|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDEF|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFB|\uDDFC|\uDDFE|\uDDFF)|\uDDE8\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF5|\uDDF7|\uDDFA|\uDDFB|\uDDFC|\uDDFD|\uDDFE|\uDDFF)|\uDDE9\uD83C(?:\uDDEA|\uDDEC|\uDDEF|\uDDF0|\uDDF2|\uDDF4|\uDDFF)|\uDDEA\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEC|\uDDED|\uDDF7|\uDDF8|\uDDF9|\uDDFA)|\uDDEB\uD83C(?:\uDDEE|\uDDEF|\uDDF0|\uDDF2|\uDDF4|\uDDF7)|\uDDEC\uD83C(?:\uDDE6|\uDDE7|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDF1|\uDDF2|\uDDF3|\uDDF5|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFC|\uDDFE)|\uDDED\uD83C(?:\uDDF0|\uDDF2|\uDDF3|\uDDF7|\uDDF9|\uDDFA)|\uDDEE\uD83C(?:\uDDE8|\uDDE9|\uDDEA|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9)|\uDDEF\uD83C(?:\uDDEA|\uDDF2|\uDDF4|\uDDF5)|\uDDF0\uD83C(?:\uDDEA|\uDDEC|\uDDED|\uDDEE|\uDDF2|\uDDF3|\uDDF5|\uDDF7|\uDDFC|\uDDFE|\uDDFF)|\uDDF1\uD83C(?:\uDDE6|\uDDE7|\uDDE8|\uDDEE|\uDDF0|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFB|\uDDFE)|\uDDF2\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF5|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFB|\uDDFC|\uDDFD|\uDDFE|\uDDFF)|\uDDF3\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEB|\uDDEC|\uDDEE|\uDDF1|\uDDF4|\uDDF5|\uDDF7|\uDDFA|\uDDFF)|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C(?:\uDDE6|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF7|\uDDF8|\uDDF9|\uDDFC|\uDDFE)|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C(?:\uDDEA|\uDDF4|\uDDF8|\uDDFA|\uDDFC)|\uDDF8\uD83C(?:\uDDE6|\uDDE7|\uDDE8|\uDDE9|\uDDEA|\uDDEC|\uDDED|\uDDEE|\uDDEF|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF7|\uDDF8|\uDDF9|\uDDFB|\uDDFD|\uDDFE|\uDDFF)|\uDDF9\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEB|\uDDEC|\uDDED|\uDDEF|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF7|\uDDF9|\uDDFB|\uDDFC|\uDDFF)|\uDDFA\uD83C(?:\uDDE6|\uDDEC|\uDDF2|\uDDF8|\uDDFE|\uDDFF)|\uDDFB\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEC|\uDDEE|\uDDF3|\uDDFA)|\uDDFC\uD83C(?:\uDDEB|\uDDF8)|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C(?:\uDDEA|\uDDF9)|\uDDFF\uD83C(?:\uDDE6|\uDDF2|\uDDFC)))|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267B\u267F\u2692-\u2694\u2696\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD79\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED0\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3]|\uD83E[\uDD10-\uDD18\uDD80-\uDD84\uDDC0]/g},{}],131:[function(t,e,r){"use strict";e.exports={":(":!0,":)":!0,":P":!0,":p":!0,":O":!0,":3":!0,":|":!0,":/":!0,":\\":!0,":$":!0,":*":!0,":@":!0,":-(":!0,":-)":!0,":-P":!0,":-p":!0,":-O":!0,":-3":!0,":-|":!0,":-/":!0,":-\\":!0,":-$":!0,":-*":!0,":-@":!0,":^(":!0,":^)":!0,":^P":!0,":^p":!0,":^O":!0,":^3":!0,":^|":!0,":^/":!0,":^\\":!0,":^$":!0,":^*":!0,":^@":!0,"):":!0,"(:":!0,"$:":!0,"*:":!0,")-:":!0,"(-:":!0,"$-:":!0,"*-:":!0,")^:":!0,"(^:":!0,"$^:":!0,"*^:":!0,"<3":!0,"</3":!0,"<\\3":!0}},{}],132:[function(t,e,r){"use strict";e.exports={beforeThisWord:{there:"Verb",me:"Verb",man:"Adjective",only:"Verb",him:"Verb",were:"Noun",took:"Noun",himself:"Verb",went:"Noun",who:"Noun",jr:"Person"},afterThisWord:{i:"Verb",first:"Noun",it:"Verb",there:"Verb",not:"Verb",because:"Noun",if:"Noun",but:"Noun",who:"Verb",this:"Noun",his:"Noun",when:"Noun",you:"Verb",very:"Adjective",old:"Noun",never:"Verb",before:"Noun"},beforeThisPos:{Copula:"Noun",PastTense:"Noun",Conjunction:"Noun",Modal:"Noun",PluperfectTense:"Noun",PerfectTense:"Verb"},afterThisPos:{Adjective:"Noun",Possessive:"Noun",Determiner:"Noun",Adverb:"Verb",Pronoun:"Verb",Value:"Noun",Ordinal:"Noun",Modal:"Verb",Superlative:"Noun",Demonym:"Noun",Honorific:"Person"}}},{}],133:[function(t,e,r){"use strict";var n="Adjective",a="Infinitive",i="Singular",o="PastTense",s="Expression",u="LastName";e.exports={a:[[/.[aeiou]na$/,"Noun"],[/.[oau][wvl]ska$/,u],[/.[^aeiou]ica$/,i],[/^([hyj]a)+$/,s]],c:[[/.[^aeiou]ic$/,n]],d:[[/.[ia]sed$/,n],[/.[gt]led$/,n],[/.[aeiou][td]ed$/,o],[/.[^aeiou]led$/,o],[/[^aeiou]ard$/,i],[/[aeiou][^aeiou]id$/,n],[/[aeiou]c?ked$/,o],[/[^aeiou][aeiou][tvx]ed$/,o],[/.[vrl]id$/,n]],e:[[/.[lnr]ize$/,a],[/.[^aeiou]ise$/,a],[/.[aeiou]te$/,a],[/.[^aeiou][ai]ble$/,n],[/.[^aeiou]eable$/,n],[/.[^aeiou]ive$/,n]],h:[[/.[^aeiouf]ish$/,n],[/.v[iy]ch$/,u],[/^ug?h+$/,s],[/^uh[ -]?oh$/,s]],i:[[/.[oau][wvl]ski$/,u]],k:[[/^(k)+$/,s]],l:[[/.[gl]ial$/,n],[/.[^aeiou]ful$/,n],[/.[nrtumcd]al$/,n],[/.[^aeiou][ei]al$/,n]],m:[[/.[^aeiou]ium$/,i],[/[^aeiou]ism$/,i],[/^h*u*m+$/,s],[/^\d+ ?[ap]m$/,"Date"]],n:[[/.[lsrnpb]ian$/,n],[/[^aeiou]ician$/,"Actor"],[/okin$/,"Gerund"]],o:[[/^no+$/,s],[/^(yo)+$/,s],[/^woo+[pt]?$/,s]],r:[[/.[ilk]er$/,"Comparative"],[/[aeiou][pns]er$/,i],[/[^i]fer$/,a],[/.[^aeiou][ao]pher$/,"Actor"]],t:[[/.[di]est$/,"Superlative"],[/.[icldtgrv]ent$/,n],[/[aeiou].*ist$/,n],[/^[a-z]et$/,"Verb"]],s:[[/.[rln]ates$/,"PresentTense"],[/.[^z]ens$/,"Verb"],[/.[lstrn]us$/,i],[/[aeiou][^aeiou]is$/,i],[/[a-z]\'s$/,"Noun"],[/^yes+$/,s]],v:[[/.[^aeiou][ai][kln]ov$/,u]],y:[[/.[cts]hy$/,n],[/.[st]ty$/,n],[/.[gk]y$/,n],[/.[tnl]ary$/,n],[/.[oe]ry$/,i],[/[rdntkbhs]ly$/,"Adverb"],[/...lly$/,"Adverb"],[/[bszmp]{2}y$/,n],[/.(gg|bb|zz)ly$/,n],[/.[aeiou]my$/,n],[/[ea]{2}zy$/,n],[/.[^aeiou]ity$/,i]]}},{}],134:[function(t,e,r){"use strict";var n="Adjective",a="Infinitive",i="PresentTense",o="Singular",s="PastTense",u="Adverb",l="Plural",c="Actor",h="Verb",f="LastName";e.exports=[null,null,{ea:o,ia:"Noun",ic:n,ly:u,"'n":h,"'t":h},{que:n,lar:n,ike:n,ffy:n,nny:n,rmy:n,azy:n,oid:n,mum:n,ous:n,end:h,sis:o,rol:o,ize:a,ify:a,zes:i,nes:i,ing:"Gerund"," so":u,"'ll":"Modal","'re":"Copula"},{teen:"Value",tors:"Noun",amed:s,ched:s,ends:h,oses:i,fies:i,ects:i,nded:s,cede:a,tage:a,gate:a,vice:o,tion:o,cted:s,ette:o,some:n,llen:n,ried:n,gone:n,made:n,fore:u,less:u,ices:l,ions:l,ints:l,aped:s,lked:s,ould:"Modal",tive:c,sson:f,czyk:f,chuk:f,enko:f,akis:f,nsen:f},{fully:u,where:u,wards:u,urned:s,tized:s,eased:s,ances:l,tures:l,ports:l,ettes:l,ities:l,rough:n,bound:n,tieth:"Ordinal",ishes:i,tches:i,nssen:f,marek:f},{keeper:c,logist:c,auskas:f,teenth:"Value"},{sdottir:f,opoulos:f}]},{}],135:[function(t,e,r){"use strict";e.exports=function(r){var n=Object.keys(r);n.forEach(function(t){r[t].downward=[];for(var e=0;e<n.length;e++)r[n[e]].isA&&r[n[e]].isA===t&&r[t].downward.push(n[e])})}},{}],136:[function(t,e,r){"use strict";e.exports=[["Noun","Verb","Adjective","Adverb","Determiner","Conjunction","Preposition","QuestionWord","Expression","Url","PhoneNumber","Email","Emoji"],["Person","Organization","Value","Place","Actor","Demonym","Pronoun"],["Acronym","Pronoun","Actor","Unit","Address"],["Acronym","Plural"],["Plural","Singular"],["MaleName","FemaleName"],["FirstName","LastName","Honorific"],["Comparative","Superlative"],["Value","Verb","Adjective"],["Ordinal","Cardinal"],["TextValue","NumericValue"],["NiceNumber","TextValue"],["Ordinal","Currency"],["PastTense","PresentTense","FutureTense"],["Pluperfect","Copula","Modal","Participle","Infinitive","Gerund","FuturePerfect","PerfectTense"],["Auxiliary","Noun","Value"],["Month","WeekDay","Year","Duration","Holiday"],["Particle","Conjunction","Adverb","Preposition"],["Date","Verb","Adjective","Person"],["Date","Money","RomanNumeral","Fraction"],["Value","Determiner"],["Url","Value","HashTag","PhoneNumber","Emoji"],["RomanNumeral","Fraction","NiceNumber"],["RomanNumeral","Money"],["UpperCase","TitleCase","CamelCase"],["VerbPhrase","Noun","Adjective","Value"],["QuestionWord","VerbPhrase"],["Acronym","VerbPhrase"]]},{}],137:[function(t,e,r){"use strict";var n,a,i,o=t("./conflicts"),s=t("./tags/nouns"),u=t("./tags/verbs"),l=t("./tags/values"),c=t("./tags/dates"),h=t("./tags/misc"),f=t("./addDownward"),m={Noun:"blue",Date:"red",Value:"red",Verb:"green",Auxiliary:"green",Negative:"green",VerbPhrase:"green",Preposition:"cyan",Condition:"cyan",Conjunction:"cyan",Determiner:"cyan",Adjective:"magenta",Adverb:"cyan"},d=function(e,r){Object.keys(e).forEach(function(t){r[t]=e[t]})};e.exports=(d(s,i={}),d(u,i),d(l,i),d(c,i),d(h,i),f(i),n=i,Object.keys(n).forEach(function(e){n[e].notA={};for(var t=0;t<o.length;t++){var r=o[t];-1!==r.indexOf(e)&&(r=r.filter(function(t){return t!==e})).forEach(function(t){n[e].notA[t]=!0})}n[e].notA=Object.keys(n[e].notA)}),a=i,Object.keys(a).forEach(function(t){m[t]?a[t].color=m[t]:a[t].isA&&m[a[t].isA]?a[t].color=m[a[t].isA]:a[t].isA&&a[a[t].isA].color&&(a[t].color=a[a[t].isA].color)}),i)},{"./addDownward":135,"./conflicts":136,"./tags/dates":138,"./tags/misc":139,"./tags/nouns":140,"./tags/values":141,"./tags/verbs":142}],138:[function(t,e,r){"use strict";e.exports={Date:{},Month:{isA:"Date",also:"Singular"},WeekDay:{isA:"Date",also:"Noun"},RelativeDay:{isA:"Date"},Year:{isA:"Date"},Duration:{isA:"Date",also:"Noun"},Time:{isA:"Date",also:"Noun"},Holiday:{isA:"Date",also:"Noun"}}},{}],139:[function(t,e,r){"use strict";e.exports={Adjective:{},Comparable:{isA:"Adjective"},Comparative:{isA:"Adjective"},Superlative:{isA:"Adjective"},NumberRange:{isA:"Contraction"},Adverb:{},Currency:{},Determiner:{},Conjunction:{},Preposition:{},QuestionWord:{},RelativeProunoun:{isA:"Pronoun"},Expression:{},Abbreviation:{},Url:{},PhoneNumber:{},HashTag:{},AtMention:{is:"Noun"},Emoji:{},Email:{},Condition:{},VerbPhrase:{},Auxiliary:{},Negative:{},Contraction:{},TitleCase:{},CamelCase:{},UpperCase:{},Hyphenated:{},Acronym:{},ClauseEnd:{},Quotation:{},StartQuotation:{isA:"Quotation"},EndQuotation:{isA:"Quotation"},Parentheses:{},EndBracket:{isA:"Parentheses"},StartBracket:{isA:"Parentheses"}}},{}],140:[function(t,e,r){"use strict";e.exports={Noun:{},Singular:{isA:"Noun"},ProperNoun:{isA:"Noun"},Person:{isA:"Singular"},FirstName:{isA:"Person"},MaleName:{isA:"FirstName"},FemaleName:{isA:"FirstName"},LastName:{isA:"Person"},Honorific:{isA:"Noun"},Place:{isA:"Singular"},Country:{isA:"Place"},City:{isA:"Place"},Region:{isA:"Place"},Address:{isA:"Place"},Organization:{isA:"Singular"},SportsTeam:{isA:"Organization"},Company:{isA:"Organization"},School:{isA:"Organization"},Plural:{isA:"Noun"},Uncountable:{isA:"Noun"},Pronoun:{isA:"Noun"},Actor:{isA:"Noun"},Activity:{isA:"Noun"},Unit:{isA:"Noun"},Demonym:{isA:"Noun"},Possessive:{isA:"Noun"}}},{}],141:[function(t,e,r){"use strict";e.exports={Value:{},Ordinal:{isA:"Value"},Cardinal:{isA:"Value"},Multiple:{isA:"Value"},RomanNumeral:{isA:"Cardinal"},Fraction:{isA:"Value"},TextValue:{isA:"Value"},NumericValue:{isA:"Value"},NiceNumber:{isA:"Value"},Money:{},Percent:{isA:"Value"}}},{}],142:[function(t,e,r){"use strict";e.exports={Verb:{isA:"VerbPhrase"},PresentTense:{isA:"Verb"},Infinitive:{isA:"PresentTense"},Gerund:{isA:"PresentTense"},PastTense:{isA:"Verb"},PerfectTense:{isA:"Verb"},FuturePerfect:{isA:"Verb"},Pluperfect:{isA:"Verb"},Copula:{isA:"Verb"},Modal:{isA:"Verb"},Participle:{isA:"Verb"},Particle:{isA:"Verb"},PhrasalVerb:{isA:"Verb"}}},{}],143:[function(t,e,r){"use strict";var n=t("./paths").fns,a=t("./whitespace"),i=t("./makeUID"),o=t("./methods/normalize/normalize").addNormal,s=t("./methods/normalize/root"),u=function(t,e){this.tags={},this._text=n.ensureString(t),Object.defineProperty(this,"world",{enumerable:!1,value:e});var r=a(this._text);this.whitespace=r.whitespace,this._text=r.text,this.parent=null,this.silent_term="",this.lumped=!1,o(this),s(this),this.dirty=!1,this.uid=i(this.normal),Object.defineProperty(this,"text",{get:function(){return this._text},set:function(t){t=t||"",this._text=t.trim(),this.dirty=!0,this.normalize()}}),Object.defineProperty(this,"isA",{get:function(){return"Term"}})};u.prototype.normalize=function(){return o(this),s(this),this},u.prototype.index=function(){var t=this.parentTerms;return t?t.terms.indexOf(this):null},u.prototype.clone=function(){var t=new u(this._text,this.world);return t.tags=n.copy(this.tags),t.whitespace=n.copy(this.whitespace),t.silent_term=this.silent_term,t},t("./methods/misc")(u),t("./methods/out")(u),t("./methods/tag")(u),t("./methods/case")(u),t("./methods/punctuation")(u),e.exports=u},{"./makeUID":144,"./methods/case":146,"./methods/misc":147,"./methods/normalize/normalize":149,"./methods/normalize/root":150,"./methods/out":153,"./methods/punctuation":156,"./methods/tag":158,"./paths":161,"./whitespace":162}],144:[function(t,e,r){"use strict";e.exports=function(t){for(var e="",r=0;r<5;r++)e+=parseInt(9*Math.random(),10);return t+"-"+e}},{}],145:[function(t,e,r){"use strict";var n={Auxiliary:1,Possessive:1,TitleCase:1,ClauseEnd:1,Comma:1,CamelCase:1,UpperCase:1,Hyphenated:1,VerbPhrase:1,EndBracket:1,StartBracket:1,Parentheses:1,Quotation:1};e.exports=function(t){var r=t.world.tags,e=Object.keys(t.tags);return(e=(e=e.sort()).sort(function(t,e){return r[t]?n[e]||!r[e]?-1:(r[t].downward.length,r[e].downward.length,1):1}))[0]}},{}],146:[function(t,e,r){"use strict";e.exports=function(e){var r={toUpperCase:function(){return this.text=this._text.toUpperCase(),this.tag("#UpperCase","toUpperCase"),this},toLowerCase:function(){return this.text=this._text.toLowerCase(),this.unTag("#TitleCase"),this.unTag("#UpperCase"),this},toTitleCase:function(){return this.text=this._text.replace(/^ *[a-z]/,function(t){return t.toUpperCase()}),this.tag("#TitleCase","toTitleCase"),this},needsTitleCase:function(){for(var t=["Person","Place","Organization","Acronym","UpperCase","Currency","RomanNumeral","Month","WeekDay","Holiday","Demonym"],e=0;e<t.length;e++)if(this.tags[t[e]])return!0;for(var r=["i","god","allah"],n=0;n<r.length;n++)if(this.normal===r[n])return!0;return!1}};return Object.keys(r).forEach(function(t){e.prototype[t]=r[t]}),e}},{}],147:[function(t,e,r){"use strict";var n=t("./normalize/isAcronym"),a=t("./bestTag"),i=/[aeiouy]/i,o=/[a-z]/,s=/[0-9]/;e.exports=function(e){var r={bestTag:function(){return a(this)},isAcronym:function(){return n(this._text)},isWord:function(){var t=this;return!(!t.silent_term&&(!1===/[a-z|A-Z|0-9]/.test(t.text)||3<t.normal.length&&!0===o.test(t.normal)&&!1===i.test(t.normal)&&!1===t.isAcronym()||!0===s.test(t.normal)&&!1===t.tags.hasOwnProperty("Value")&&!0===/[a-z][0-9][a-z]/.test(t.normal)))}};return Object.keys(r).forEach(function(t){e.prototype[t]=r[t]}),e}},{"./bestTag":145,"./normalize/isAcronym":148}],148:[function(t,e,r){"use strict";var n=/([A-Z]\.)+[A-Z]?,?$/,a=/^[A-Z]\.,?$/,i=/[A-Z]{2}('s|,)?$/;e.exports=function(t){return!0===n.test(t)||!0===a.test(t)||!0===i.test(t)}},{}],149:[function(t,e,r){"use strict";var n=t("./unicode"),a=t("./isAcronym");r.normalize=function(t){var e=t=(t=(t=t||"").toLowerCase()).trim();return t=(t=(t=(t=(t=(t=(t=n(t)).replace(/^[#@]/,"")).replace(/[,;.!?]+$/,"")).replace(/[\u0027\u0060\u00B4\u2018\u2019\u201A\u201B\u2032\u2035\u2039\u203A]+/g,"'")).replace(/[\u0022\u00AB\u00BB\u201C\u201D\u201E\u201F\u2033\u2034\u2036\u2037\u2E42\u301D\u301E\u301F\uFF02]+/g,'"')).replace(/\u2026/g,"...")).replace(/\u2013/g,"-"),!0===/[a-z][^aeiou]in['’]$/.test(t)&&(t=t.replace(/in['’]$/,"ing")),!0===/^(re|un)-?[^aeiou]./.test(t)&&(t=t.replace("-","")),!1===/^[:;]/.test(t)&&(t=(t=(t=t.replace(/\.{3,}$/g,"")).replace(/['",\.!:;\?\)]+$/g,"")).replace(/^['"\(]+/g,"")),""===(t=t.trim())&&(t=e),t},r.addNormal=function(t){var e=t._text||"";e=r.normalize(e),a(t._text)&&(e=e.replace(/\./g,"")),e=e.replace(/([0-9]),([0-9])/g,"$1$2"),t.normal=e}},{"./isAcronym":148,"./unicode":151}],150:[function(t,e,r){"use strict";e.exports=function(t){var e=t.normal||t.silent_term||"";e=(e=e.replace(/'s\b/,"")).replace(/'$/,""),t.root=e}},{}],151:[function(t,e,r){"use strict";var n={"!":"¡","?":"¿Ɂ",'"':'“”"❝❞',"'":"‘‛❛❜","-":"—–",a:"ªÀÁÂÃÄÅàáâãäåĀāĂ㥹ǍǎǞǟǠǡǺǻȀȁȂȃȦȧȺΆΑΔΛάαλАДадѦѧӐӑӒӓƛɅæ",b:"ßþƀƁƂƃƄƅɃΒβϐϦБВЪЬбвъьѢѣҌҍҔҕƥƾ",c:"¢©ÇçĆćĈĉĊċČčƆƇƈȻȼͻͼͽϲϹϽϾϿЄСсєҀҁҪҫ",d:"ÐĎďĐđƉƊȡƋƌǷ",e:"ÈÉÊËèéêëĒēĔĕĖėĘęĚěƎƏƐǝȄȅȆȇȨȩɆɇΈΕΞΣέεξϱϵ϶ЀЁЕЭеѐёҼҽҾҿӖӗӘәӚӛӬӭ",f:"ƑƒϜϝӺӻҒғӶӷſ",g:"ĜĝĞğĠġĢģƓǤǥǦǧǴǵ",h:"ĤĥĦħƕǶȞȟΉΗЂЊЋНнђћҢңҤҥҺһӉӊ",I:"ÌÍÎÏ",i:"ìíîïĨĩĪīĬĭĮįİıƖƗȈȉȊȋΊΐΪίιϊІЇії",j:"ĴĵǰȷɈɉϳЈј",k:"ĶķĸƘƙǨǩΚκЌЖКжкќҚқҜҝҞҟҠҡ",l:"ĹĺĻļĽľĿŀŁłƚƪǀǏǐȴȽΙӀӏ",m:"ΜϺϻМмӍӎ",n:"ÑñŃńŅņŇňʼnŊŋƝƞǸǹȠȵΝΠήηϞЍИЙЛПийлпѝҊҋӅӆӢӣӤӥπ",o:"ÒÓÔÕÖØðòóôõöøŌōŎŏŐőƟƠơǑǒǪǫǬǭǾǿȌȍȎȏȪȫȬȭȮȯȰȱΌΘΟθοσόϕϘϙϬϭϴОФоѲѳӦӧӨөӪӫ¤ƍΏ",p:"ƤƿΡρϷϸϼРрҎҏÞ",q:"Ɋɋ",r:"ŔŕŖŗŘřƦȐȑȒȓɌɍЃГЯгяѓҐґ",s:"ŚśŜŝŞşŠšƧƨȘșȿςϚϛϟϨϩЅѕ",t:"ŢţŤťŦŧƫƬƭƮȚțȶȾΓΤτϮϯТт҂Ҭҭ",u:"µÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųƯưƱƲǓǔǕǖǗǘǙǚǛǜȔȕȖȗɄΰμυϋύϑЏЦЧцџҴҵҶҷӋӌӇӈ",v:"νѴѵѶѷ",w:"ŴŵƜωώϖϢϣШЩшщѡѿ",x:"×ΧχϗϰХхҲҳӼӽӾӿ",y:"ÝýÿŶŷŸƳƴȲȳɎɏΎΥΫγψϒϓϔЎУучўѰѱҮүҰұӮӯӰӱӲӳ",z:"ŹźŻżŽžƩƵƶȤȥɀΖζ"},a={};Object.keys(n).forEach(function(e){n[e].split("").forEach(function(t){a[t]=e})}),e.exports=function(t){var r=t.split("");return r.forEach(function(t,e){a[t]&&(r[e]=a[t])}),r.join("")}},{}],152:[function(t,e,r){"use strict";var n=t("../../paths"),i=n.fns,o=n.tags;e.exports=function(t){for(var e="silver",r=Object.keys(t.tags),n=0;n<r.length;n++)if(o[r[n]]&&o[r[n]].color){e=o[r[n]].color;break}var a=i.leftPad(t.text,12);a+=" "+r,console.log("%c "+a,"color: "+e)}},{"../../paths":161}],153:[function(t,e,r){"use strict";function n(t){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var a=t("./renderHtml"),i=t("./client"),o=t("./server"),s={text:function(t){return(t.whitespace.before||"")+t._text+(t.whitespace.after||"")},normal:function(t){return t.normal},root:function(t){return t.root||t.normal},html:function(t){return a(t)},tags:function(t){return{text:t.text,normal:t.normal,tags:Object.keys(t.tags)}},debug:function(t){"object"===("undefined"==typeof window?"undefined":n(window))?i(t):o(t)}};e.exports=function(t){return t.prototype.out=function(t){return s[t]||(t="text"),s[t](this)},t}},{"./client":152,"./renderHtml":154,"./server":155}],154:[function(t,e,r){"use strict";var a=function(t){var e={"<":"<",">":">","&":"&",'"':""","'":"'"," ":" "};return t.replace(/[<>&"' ]/g,function(t){return e[t]})};e.exports=function(t){var e=Object.keys(t.tags).filter(function(t){return"Term"!==t});e=(e=e.map(function(t){return"nl-"+t})).join(" ");var r=function(t){for(var e,r="(?:[^\"'>]|\"[^\"]*\"|'[^']*')*",n=new RegExp("<(?:!--(?:(?:-*[^->])*--+|-?)|script\\b"+r+">[\\s\\S]*?<\/script\\s*|style\\b"+r+">[\\s\\S]*?</style\\s*|/?[a-z]"+r+")>","gi");(t=(e=t).replace(n,""))!==e;);return t.replace(/</g,"<")}(t.text),n='<span class="'+e+'">'+(r=a(r))+"</span>";return a(t.whitespace.before)+n+a(t.whitespace.after)}},{}],155:[function(t,e,r){"use strict";var a=t("../../paths").fns;e.exports=function(t){var e=Object.keys(t.tags).map(function(t){return a.printTag(t)}).join(", "),r=t.text;r="'"+a.yellow(r||"-")+"'";var n="";t.silent_term&&(n="["+t.silent_term+"]"),r=a.leftPad(r,20),r+=a.leftPad(n,8),console.log(" "+r+" - "+e)}},{"../../paths":161}],156:[function(t,e,r){"use strict";var n=/([a-z0-9 ])([,:;.!?]+)$/i;e.exports=function(e){var r={getPunctuation:function(){var t=this.text.match(n);return t?t[2]:null},setPunctuation:function(t){return this.killPunctuation(),this.text+=t,","===t&&(this.tags.Comma=!0),this},hasComma:function(){return","===this.getPunctuation()},killPunctuation:function(){return this.text=this._text.replace(n,"$1"),delete this.tags.Comma,delete this.tags.ClauseEnd,this}};return Object.keys(r).forEach(function(t){e.prototype[t]=r[t]}),e}},{}],157:[function(t,e,r){"use strict";e.exports=function t(e,r){var n=e.world.tags;if(void 0===n[r])return!0;for(var a=n[r].notA||[],i=0;i<a.length;i++)if(!0===e.tags[a[i]])return!1;return void 0===n[r].isA||t(e,n[r].isA)}},{}],158:[function(t,e,r){"use strict";var n=t("./setTag"),a=t("./unTag"),i=t("./canBe"),o={".":!0};e.exports=function(e){var r={tag:function(t,e){!0!==o[t]&&n(this,t,e)},unTag:function(t,e){!0!==o[t]&&a(this,t,e)},canBe:function(t){if("string"==typeof(t=t||"")){if(!0===o[t])return!0;t=t.replace(/^#/,"")}return i(this,t)}};return Object.keys(r).forEach(function(t){e.prototype[t]=r[t]}),e}},{"./canBe":157,"./setTag":159,"./unTag":160}],159:[function(t,e,r){"use strict";var n=t("../../paths"),u=n.log,a=n.fns,l=t("./unTag"),i=function t(e,r,n){var a=e.world.tags;if(r=r.replace(/^#/,""),!0!==e.tags[r]&&(e.tags[r]=!0,u.tag(e,r,n),a[r])){for(var i=a[r].notA||[],o=0;o<i.length;o++)!0===e.tags[i[o]]&&l(e,i[o],n);if(a[r].isA){var s=a[r].isA;!0!==e.tags[s]&&t(e,s," --\x3e "+r)}}};e.exports=function(e,t,r){if(e&&t){var n=e.world.tags;a.isArray(t)?t.forEach(function(t){return i(e,t,r)}):(i(e,t,r),n[t]&&void 0!==n[t].also&&i(e,n[t].also,r))}}},{"../../paths":161,"./unTag":160}],160:[function(t,e,r){"use strict";var s=t("../../paths").log;e.exports=function(t,e,r){t&&e&&("*"!==e?function t(e,r,n){var a=e.world.tags;if(e.tags[r]&&(s.unTag(e,r,n),delete e.tags[r],a[r]))for(var i=a[r].downward,o=0;o<i.length;o++)t(e,i[o]," - - - ")}(t,e,r):t.tags={})}},{"../../paths":161}],161:[function(t,e,r){"use strict";e.exports={fns:t("../fns"),log:t("../log")}},{"../fns":3,"../log":6}],162:[function(t,e,r){"use strict";var n=/^([\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]|\x2D+|\.\.+|\/|"|"|\uFF02|'|\u201C|\u2018|\u201F|\u201B|\u201E|\u2E42|\u201A|\xAB|\u2039|\u2035|\u2036|\u2037|\u301D|`|\u301F)+/,a=/([\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+|\x2D+|\.\.+|"|"|\uFF02|'|\u201D|\u2019|\xBB|\u203A|\u2032|\u2033|\u2034|\u301E|\xB4)+$/,i=/([\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+|\x2D+|\.\.+|"|"|\uFF02|'|\u201D|\u2019|\xBB|\u203A|\u2032|\u2033|\u2034|\u301E|\xB4)+[ !,\.;\?]*$/,o=/^( *)-(\$|€|¥|£)?([0-9])/;e.exports=function(t){var e={before:"",after:""},r=t.match(o);return null!==r?(e.before=r[1],t=t.replace(/^ */,"")):null!==(r=t.match(n))&&(e.before=t.match(n)[0],t=t.replace(n,"")),null!==(r=t.match(i))&&(t=t.replace(a,""),e.after=r[0]),{whitespace:e,text:t}}},{}],163:[function(t,e,r){"use strict";var d=t("../term"),p=/\S/,g=/^[!?.]+$/,v={".":!0,"-":!0,"–":!0,"—":!0,"--":!0,"...":!0};e.exports=function(t,e){var r,n=[],a=[];"number"==typeof(t=t||"")&&(t=String(t));for(var i,o=t.split(/(\S+)/),s=0;s<o.length;s++){var u=o[s];if(!0==(!0!==/^(re|un)-?[^aeiou]./.test(r=u)&&(!0===/^([a-z`"'/]+)(-|–|—)([a-z0-9].*)/i.test(r)||!!/^([0-9]+)(–|—)([0-9].*)/i.test(r))))for(var l=u.split(/[-–—]/),c=0;c<l.length;c++)c===l.length-1?a.push(l[c]):a.push(l[c]+"-");else if(1==!(!/[a-z]\/[a-z]/.test(i=u)||2!==i.split(/\//g).length)){var h=u.split(/\//);a.push(h[0]),a.push("/"+h[1])}else a.push(u)}for(var f="",m=0;m<a.length;m++)!0===p.test(a[m])&&!1===v.hasOwnProperty(a[m])&&!1===g.test(a[m])?(n.push(f+a[m]),f=""):f+=a[m];return f&&0<n.length&&(n[n.length-1]+=f),n.map(function(t){return new d(t,e)})}},{"../term":143}],164:[function(t,e,r){"use strict";e.exports={parent:{get:function(){return this.refText||this},set:function(t){return this.refText=t,this}},parentTerms:{get:function(){return this.refTerms||this},set:function(t){return this.refTerms=t,this}},dirty:{get:function(){for(var t=0;t<this.terms.length;t++)if(!0===this.terms[t].dirty)return!0;return!1},set:function(e){this.terms.forEach(function(t){t.dirty=e})}},refTerms:{get:function(){return this._refTerms||this},set:function(t){return this._refTerms=t,this}},found:{get:function(){return 0<this.terms.length}},length:{get:function(){return this.terms.length}},isA:{get:function(){return"Terms"}},whitespace:{get:function(){var e=this;return{before:function(t){return e.firstTerm().whitespace.before=t,e},after:function(t){return e.lastTerm().whitespace.after=t,e}}}}}},{}],165:[function(t,e,r){"use strict";var a=t("./build"),s=t("./getters"),u=t("../world"),i=function(t,e,r,n){var a=this;this.terms=t,this.world=e||u,this.refText=r,this._refTerms=n,this.get=function(t){return a.terms[t]};for(var i=Object.keys(s),o=0;o<i.length;o++)Object.defineProperty(this,i[o],s[i[o]])};i.fromString=function(t,e){var r=a(t,e),n=new i(r,e,null);return n.terms.forEach(function(t){t.parentTerms=n}),n},t("./match")(i),t("./methods/tag")(i),t("./methods/loops")(i),t("./match/not")(i),t("./methods/delete")(i),t("./methods/insert")(i),t("./methods/misc")(i),t("./methods/out")(i),t("./methods/replace")(i),t("./methods/split")(i),t("./methods/transform")(i),t("./methods/lump")(i),e.exports=i},{"../world":215,"./build":163,"./getters":164,"./match":166,"./match/not":176,"./methods/delete":177,"./methods/insert":178,"./methods/loops":179,"./methods/lump":181,"./methods/misc":182,"./methods/out":183,"./methods/replace":184,"./methods/split":185,"./methods/tag":186,"./methods/transform":187}],166:[function(t,e,r){"use strict";var i=t("./lib/syntax"),o=t("./lib/startHere"),s=t("../../text"),u=t("./lib");e.exports=function(a){var e={match:function(t,e){var r=this;if(0===this.terms.length)return new s([],this.world,this.parent);if(!t)return new s([],this.world,this.parent);var n=u(this,t,e);return n=n.map(function(t){return new a(t,r.world,r.refText,r.refTerms)}),new s(n,this.world,this.parent)},matchOne:function(t){if(0===this.terms.length)return null;for(var e=i(t),r=0;r<this.terms.length&&!(e[0]&&e[0].starting&&0<r);r++){var n=o(this,r,e);if(n)return n}return null},has:function(t){return null!==this.matchOne(t)}};return Object.keys(e).forEach(function(t){a.prototype[t]=e[t]}),a}},{"../../text":192,"./lib":170,"./lib/startHere":174,"./lib/syntax":175}],167:[function(t,e,r){"use strict";e.exports=function(t,e){e.capture?t.captureGroup=!0:t.captureGroup=void 0}},{}],168:[function(t,e,r){"use strict";e.exports=function(t){var n=[];return t.forEach(function(t){if(0!==t.filter(function(t){return!0===t.captureGroup}).length){for(var e=[],r=0;r<t.length;r+=1)t[r].captureGroup?e.push(t[r]):0<e.length&&(n.push(e),e=[]);0<e.length&&n.push(e)}else n.push(t)}),n}},{}],169:[function(t,e,r){"use strict";e.exports=function(t,e){for(var r=0;r<e.length;r++){var n=e[r],a=!1;if(!0!==n.optional&&!0!==n.negative&&void 0===n.minMax){if(void 0!==n.normal){for(var i=0;i<t.terms.length;i++){if(t.terms[i].normal===n.normal||t.terms[i].silent_term===n.normal){a=!0;break}if(!0===t.terms[i].lumped)return!1}if(!1===a)return!0}if(void 0!==n.tag){for(var o=0;o<t.terms.length;o++)if(!0===t.terms[o].tags[n.tag]){a=!0;break}if(!1===a)return!0}}}return!1}},{}],170:[function(t,e,r){"use strict";var o=t("./syntax"),s=t("./startHere"),u=t("./fastPass"),l=t("./captureGroup"),c=function(t){return t?t.terms.map(function(t){return{id:t.uid}}):[]};e.exports=function(t,e,r){if("string"==typeof e?e=o(e):e&&"Text"===e.isA?e=c(e.list[0]):e&&"Terms"===e.isA&&(e=c(e)),!e||0===e.length)return[];if(!0===u(t,e,r))return[];for(var n=[],a=0;a<t.terms.length&&!(0<a&&e[0]&&e[0].starting);a+=1){var i=s(t,a,e,r);i&&0<i.length&&(n.push(i),a+=i.length-1)}return l(n)}},{"./captureGroup":168,"./fastPass":169,"./startHere":174,"./syntax":175}],171:[function(t,e,r){"use strict";var a=t("./applyCaptureGroup");e.exports=function(t,e,r){if(!t||!e)return!1;var n=function(t,e){if(!t||!e)return!1;if(!0===e.anyOne)return!0;if(void 0!==e.tag)return t.tags[e.tag];if(void 0!==e.id)return e.id===t.uid;if(void 0!==e.normal)return e.normal===t.normal||e.normal===t.silent_term;if(!0===e.suffix&&void 0!==e.partial){var r=t.normal.length;return t.normal.substr(r-e.partial.length,r)===e.partial}if(!0===e.prefix&&void 0!==e.partial)return t.normal.substr(0,e.partial.length)===e.partial;if(!0===e.infix&&e.partial)return-1!==t.normal.indexOf(e.partial);if(void 0!==e.regex)return e.regex.test(t.normal)||e.regex.test(t.text);if(void 0===e.oneOf)return!1;for(var n=0;n<e.oneOf.tagArr.length;n++)if(!0===t.tags.hasOwnProperty(e.oneOf.tagArr[n]))return!0;return e.oneOf.terms.hasOwnProperty(t.normal)||e.oneOf.terms.hasOwnProperty(t.silent_term)}(t,e);return e.negative&&(n=!Boolean(n)),n&&a(t,e),n}},{"./applyCaptureGroup":167}],172:[function(t,e,r){"use strict";var a=function(t,e){return e.normal.substr(0,t.length)===t};e.exports=function(t,e,r){var n=e[r].normal;if(void 0!==n&&a(n,t))for(r+=1;r<e.length;r++){if((n+=" "+e[r].normal)===t.normal)return r;if(!1===a(n,t))return null}return null}},{}],173:[function(t,e,r){arguments[4][73][0].apply(r,arguments)},{"../../paths":189,dup:73}],174:[function(t,e,r){"use strict";var x=t("./lumpMatch"),C=t("./isMatch"),k=t("./applyCaptureGroup"),E=function(t,e,r){for(;e<t.length;e++)if(C(t.terms[e],r))return e;return null},A=function(t,e,r,n){for(;e<t.length;e++){var a=t.terms[e];if(n&&C(a,n))return e;if(!C(a,r))return e}return e};e.exports=function(t,e,r,n){for(var a=e,i=0;i<r.length;i++){var o=t.terms[a],s=r[i],u=r[i+1];if(!o){if(!0===s.optional)continue;return null}if(!0===s.starting&&0<a)return null;if(!0===s.ending&&a!==t.length-1&&!s.minMax)return null;if(!0!==s.astrix)if(void 0===r[i].minMax)if(!0!==s.optional)if(C(o,s,n)){if(a+=1,!0===s.consecutive){var l=r[i+1];a=A(t,a,s,l)}}else if(!o.silent_term||o.normal){var c=x(o,r,i,n);if(null===c){if(!0!==s.optional)return null}else i=c,a+=1}else{if(0===i)return null;a+=1,i-=1}else{var h=r[i+1];a=A(t,a,s,h)}else for(var f=r[i].minMax.min||0,m=r[i].minMax.max,d=r[i+1],p=0;p<m;p++){var g=t.terms[a+p];if(!g)return null;if(!1===C(g,s))return null;if(!(p<f-1)){if(!d){a+=1;break}if(f<=p&&C(g,d))break;var v=t.terms[a+p+1];if(v&&C(v,d)){a+=p+2,i+=1;break}if(p===m-1)return null}}else{if(!u){for(var y=t.terms.slice(e,t.length),b=a-e;b<y.length;b++)k(y[b],s);return y}var D=E(t,a,r[i+1]);if(!D)return null;for(var w=a;w<D;w++)k(t.terms[w],s);a=D+1,i+=1}}return t.terms.slice(e,a)}},{"./applyCaptureGroup":167,"./isMatch":171,"./lumpMatch":172}],175:[function(t,e,r){"use strict";var i=t("./paths").fns,o=/\{[0-9,]+\}$/,s=function(t){return t.substr(1,t.length)},u=function(t){return t.substring(0,t.length-1)};e.exports=function(t){for(var e=(t=t||"").split(/ +/),r=0;r<e.length;r+=1)if(-1!==e[r].indexOf("(")&&-1===e[r].indexOf(")")){var n=e[r+1];n&&-1===n.indexOf("(")&&-1!==n.indexOf(")")&&(e[r+1]=e[r]+" "+e[r+1],e[r]="")}e=e.filter(function(t){return t});var a=!1;return e.map(function(t){var e=!1;return"["===t.charAt(0)&&(t=s(t),a=!0),"]"===t.charAt(t.length-1)&&(t=u(t),e=!(a=!1)),t=function(t){t=(t=t||"").trim();var r={};if(1===t.length&&"."!==t&&"*"!==t)return r.normal=t.toLowerCase(),r;if("!"===t.charAt(0)&&(t=s(t),r.negative=!0),"^"===t.charAt(0)&&(t=s(t),r.starting=!0),"$"===t.charAt(t.length-1)&&(t=u(t),r.ending=!0),"?"===t.charAt(t.length-1)&&(t=u(t),r.optional=!0),"+"===t.charAt(t.length-1)&&(t=u(t),r.consecutive=!0),"_"===t.charAt(t.length-1)?(t=u(t),r.prefix=!0,"_"===t.charAt(0)&&(t=s(t),r.prefix=void 0,r.infix=!0),r.partial=t,t=""):"_"===t.charAt(0)&&(t=s(t),r.suffix=!0,r.partial=t,t=""),"}"===t.charAt(t.length-1)&&!0===o.test(t)){var e=t.match(/\{([0-9])*,? ?([0-9]+)\}/);r.minMax={min:parseInt(e[1],10)||0,max:parseInt(e[2],10)},t=t.replace(o,"")}if("#"===t.charAt(0)&&(t=s(t),r.tag=i.titleCase(t),t=""),"/"===t.charAt(0)&&"/"===t.charAt(t.length-1)&&(t=u(t),t=s(t),r.regex=new RegExp(t,"i"),t=""),"("===t.charAt(0)&&")"===t.charAt(t.length-1)){t=u(t);var n=(t=s(t)).split(/\|/g);r.oneOf={terms:{},tagArr:[]},n.forEach(function(t){if("#"===t.charAt(0)){var e=t.substr(1,t.length);e=i.titleCase(e),r.oneOf.tagArr.push(e)}else r.oneOf.terms[t]=!0}),t=""}return"."===t&&(r.anyOne=!0,t=""),"*"===t&&(r.astrix=!0,t=""),""!==t&&(t=t.replace(/\\([\\#\*\.\[\]\(\)\+\?\^])/g,""),r.normal=t.toLowerCase()),r}(t),!0!==a&&!0!==e||(t.capture=!0),t})}},{"./paths":173}],176:[function(t,e,r){"use strict";function a(t){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var l=t("./lib/syntax"),c=t("./lib/startHere"),h=t("../../text");e.exports=function(u){var n={notObj:function(e,r){var n=[],a=[];return e.terms.forEach(function(t){r.hasOwnProperty(t.normal)?(a.length&&n.push(a),a=[]):a.push(t)}),a.length&&n.push(a),n=n.map(function(t){return new u(t,e.world,e.refText,e.refTerms)}),new h(n,e.world,e.parent)},notString:function(e,t,r){for(var n=[],a=l(t),i=[],o=0;o<e.terms.length;o++){var s=c(e,o,a,r);s&&0<s.length?(0<i.length&&(n.push(i),i=[]),o+=s.length-1):i.push(e.terms[o])}return 0<i.length&&n.push(i),n=n.map(function(t){return new u(t,e.world,e.refText,e.refTerms)}),new h(n,e.world,e.parent)},notArray:function(t,e){var r=e.reduce(function(t,e){return t[e]=!0,t},{});return n.notObj(t,r)},notText:function(t,e){var r=e.out("array");return n.notArray(t,r)}};return u.prototype.not=function(t,e){if("object"===a(t)){var r=Object.prototype.toString.call(t);if("[object Array]"===r)return n.notArray(this,t,e);if("[object Object]"===r)return"Text"===t.isA?n.notText(this,t,e):n.notObj(this,t,e)}return"string"==typeof t?n.notString(this,t,e):this},u}},{"../../text":192,"./lib/startHere":174,"./lib/syntax":175}],177:[function(t,e,r){"use strict";var n=t("../mutate");e.exports=function(t){return t.prototype.delete=function(t){if(!this.found)return this;if(!t)return this.parentTerms=n.deleteThese(this.parentTerms,this),this;var e=this.match(t);return e.found?n.deleteThese(this,e):this.parentTerms},t}},{"../mutate":188}],178:[function(t,e,r){"use strict";var o=t("../mutate"),s=function(t,e){return t.terms.length&&t.terms[e]&&(t.terms[e].whitespace.before=" "),t};e.exports=function(n){var i=function(t,e){if("Terms"===t.isA)return t;if("Term"===t.isA)return new n([t],e);var r=n.fromString(t,e);return r.tagger(),r},e={insertBefore:function(t,e){var r=this.terms.length,n=i(t,this.world);e&&n.tag(e);var a=this.index();return s(this.parentTerms,a),0<a&&s(n,0),this.parentTerms.terms=o.insertAt(this.parentTerms.terms,a,n),this.terms.length===r&&(this.terms=n.terms.concat(this.terms)),this},insertAfter:function(t,e){var r=this.terms.length,n=i(t,this.world);e&&n.tag(e);var a=this.terms[this.terms.length-1].index();return s(n,0),this.parentTerms.terms=o.insertAt(this.parentTerms.terms,a+1,n),this.terms.length===r&&(this.terms=this.terms.concat(n.terms)),this},insertAt:function(t,e,r){t<0&&(t=0);var n=this.terms.length,a=i(e,this.world);return r&&a.tag(r),0<t&&s(a,0),this.parentTerms.terms=o.insertAt(this.parentTerms.terms,t,a),this.terms.length===n&&Array.prototype.splice.apply(this.terms,[t,0].concat(a.terms)),0===t&&(this.terms[0].whitespace.before="",a.terms[a.terms.length-1].whitespace.after=" "),this}};return Object.keys(e).forEach(function(t){n.prototype[t]=e[t]}),n}},{"../mutate":188}],179:[function(t,e,r){"use strict";e.exports=function(e){return[["toUpperCase","UpperCase"],["toLowerCase"],["toTitleCase","TitleCase"]].forEach(function(t){var r=t[0],n=t[1];e.prototype[r]=function(){var e=arguments;return this.terms.forEach(function(t){t[r].apply(t,e)}),n&&this.tag(n,r),this}}),e}},{}],180:[function(t,e,r){"use strict";var u=t("../../../term");e.exports=function(t,e){var r=t.terms[e],n=t.terms[e+1];if(n){var a,i,o,s=(i=n,o=(a=r).whitespace.before+a.text+a.whitespace.after,o+=i.whitespace.before+i.text+i.whitespace.after);t.terms[e]=new u(s,r.context),t.terms[e].normal=r.normal+" "+n.normal,t.terms[e].lumped=!0,t.terms[e].parentTerms=t.terms[e+1].parentTerms,t.terms[e+1]=null,t.terms=t.terms.filter(function(t){return null!==t})}}},{"../../../term":143}],181:[function(t,e,r){"use strict";var i=t("./combine"),a=t("../../mutate"),o=function(t,e){for(var r=t.terms.length,n=0;n<r;n++)i(t,0);var a=t.terms[0];return a.tags=e,a};e.exports=function(t){return t.prototype.lump=function(){var t=this.index(),e={};if(this.terms.forEach(function(t){Object.keys(t.tags).forEach(function(t){return e[t]=!0})}),this.parentTerms===this){var r=o(this,e);return this.terms=[r],this}this.parentTerms=a.deleteThese(this.parentTerms,this);var n=o(this,e);return this.parentTerms.terms=a.insertAt(this.parentTerms.terms,t,n),this},t}},{"../../mutate":188,"./combine":180}],182:[function(t,e,r){"use strict";var a=t("../../tagger");e.exports=function(n){var e={tagger:function(){return a(this),this},firstTerm:function(){return this.terms[0]},lastTerm:function(){return this.terms[this.terms.length-1]},all:function(){return this.parent},data:function(){return{text:this.out("text"),normal:this.out("normal")}},term:function(t){return this.terms[t]},first:function(){var t=this.terms[0];return new n([t],this.world,this.refText,this.refTerms)},last:function(){var t=this.terms[this.terms.length-1];return new n([t],this.world,this.refText,this.refTerms)},slice:function(t,e){var r=this.terms.slice(t,e);return new n(r,this.world,this.refText,this.refTerms)},index:function(){var t=this.parentTerms,e=this.terms[0];if(!t||!e)return null;for(var r=0;r<t.terms.length;r++)if(e===t.terms[r])return r;return null},termIndex:function(){var t=this.terms[0],e=this.refText||this;if(!e||!t)return null;for(var r=0,n=0;n<e.list.length;n++)for(var a=e.list[n],i=0;i<a.terms.length;i++){if(a.terms[i]===t)return r;r+=1}return r},chars:function(){return this.terms.reduce(function(t,e){return t+=e.whitespace.before.length,(t+=e.text.length)+e.whitespace.after.length},0)},wordCount:function(){return this.terms.length},setPunctuation:function(t){this.terms[this.terms.length-1].setPunctuation(t)},getPunctuation:function(){var t=this.last().terms[0];return t&&t.getPunctuation()||""},toCamelCase:function(){return this.toTitleCase(),this.terms.forEach(function(t,e){0!==e&&(t.whitespace.before=""),t.whitespace.after=""}),this.tag("#CamelCase","toCamelCase"),this}};return Object.keys(e).forEach(function(t){n.prototype[t]=e[t]}),n}},{"../../tagger":95}],183:[function(t,e,r){"use strict";var n=t("../paths").fns,a={text:function(t){return t.terms.reduce(function(t,e){return t+e.out("text")},"")},match:function(t){for(var e="",r=t.terms.length,n=0;n<r;n++)0<n&&(e+=t.terms[n].whitespace.before),e+=t.terms[n].text.replace(/[,.?!]$/,""),n<r-1&&(e+=t.terms[n].whitespace.after);return e},normal:function(t){var e=t.terms.filter(function(t){return t.text});return(e=e.map(function(t){return t.normal})).join(" ")},grid:function(t){var e=" ";return(e+=t.terms.reduce(function(t,e){return t+n.leftPad(e.text,11)},""))+"\n\n"},color:function(t){return t.terms.reduce(function(t,e){return t+n.printTerm(e)},"")},csv:function(t){return t.terms.map(function(t){return t.normal.replace(/,/g,"")}).join(",")},newlines:function(t){return t.terms.reduce(function(t,e){return t+e.out("text").replace(/\n/g," ")},"").replace(/^\s/,"")},root:function(t){return t.terms.map(function(t){return t.silent_term||t.root}).join(" ").toLowerCase()},html:function(t){return t.terms.map(function(t){return t.render.html()}).join(" ")},debug:function(t){t.terms.forEach(function(t){t.out("debug")})},custom:function(t,n){return t.terms.map(function(r){return Object.keys(n).reduce(function(t,e){return n[e]&&r[e]&&("function"==typeof r[e]?t[e]=r[e]():t[e]=r[e]),t},{})})}};a.plaintext=a.text,a.normalize=a.normal,a.normalized=a.normal,a.colors=a.color,a.tags=a.terms,e.exports=function(t){return t.prototype.out=function(t){if("string"==typeof t){if(a[t])return a[t](this)}else if(!0===n.isObject(t))return a.custom(this,t);return a.text(this)},t.prototype.debug=function(){return a.debug(this)},t}},{"../paths":189}],184:[function(t,e,r){"use strict";var o=t("../mutate");e.exports=function(i){var e={replace:function(t,e,r){return void 0===e?this.replaceWith(t,r):(this.match(t).replaceWith(e,r),this)},replaceWith:function(t,e){var n=i.fromString(t,this.world);n.tagger(),e&&this.terms.forEach(function(t,e){var r=Object.keys(t.tags);void 0!==n.terms[e]&&r.forEach(function(t){return n.terms[e].tag(t,"from-memory")})});var r=this.getPunctuation(),a=this.index();return this.parentTerms=o.deleteThese(this.parentTerms,this),this.parentTerms.terms=o.insertAt(this.parentTerms.terms,a,n),this.terms=n.terms,0<this.terms.length&&(this.terms[this.terms.length-1].whitespace.after+=r),this}};return Object.keys(e).forEach(function(t){i.prototype[t]=e[t]}),i}},{"../mutate":188}],185:[function(t,e,r){"use strict";var l=function(t,e){for(var r=e.terms[0],n=e.terms.length,a=0;a<t.length;a++)if(t[a]===r)return{before:t.slice(0,a),match:t.slice(a,a+n),after:t.slice(a+n,t.length)};return{after:t}};e.exports=function(u){var e={splitAfter:function(t,e){var r=this,n=this.match(t,e),a=this.terms,i=[];return n.list.forEach(function(t){var e=l(a,t);e.before&&e.match&&i.push(e.before.concat(e.match)),a=e.after}),a.length&&i.push(a),i=i.map(function(t){var e=r.refText;return new u(t,r.world,e,r.refTerms)})},splitOn:function(t,e){var r=this,n=this.match(t,e),a=this.terms,i=[];return n.list.forEach(function(t){var e=l(a,t);e.before&&i.push(e.before),e.match&&i.push(e.match),a=e.after}),a.length&&i.push(a),i=(i=i.filter(function(t){return t&&t.length})).map(function(t){return new u(t,t.world,t.refText,r.refTerms)})},splitBefore:function(t,e){var r=this,n=this.match(t,e),a=this.terms,i=[];n.list.forEach(function(t){var e=l(a,t);e.before&&i.push(e.before),e.match&&i.push(e.match),a=e.after}),a.length&&i.push(a);for(var o=0;o<i.length;o++)for(var s=0;s<n.length;s++)n.list[s].terms[0]===i[o][0]&&i[o+1]&&(i[o]=i[o].concat(i[o+1]),i[o+1]=[]);return i=(i=i.filter(function(t){return t&&t.length})).map(function(t){return new u(t,t.world,t.refText,r.refTerms)})}};return Object.keys(e).forEach(function(t){u.prototype[t]=e[t]}),u}},{}],186:[function(t,e,r){"use strict";e.exports=function(r){var e={tag:function(e,r){var n=[];return"string"==typeof e&&(n=e.split(" ")),1<n.length?this.terms.forEach(function(t,e){t.tag(n[e],r)}):this.terms.forEach(function(t){t.tag(e,r)}),this},unTag:function(e,r){var n=[];return"string"==typeof e&&(n=e.split(" ")),1<n.length?this.terms.forEach(function(t,e){t.unTag(n[e],r)}):this.terms.forEach(function(t){t.unTag(e,r)}),this},canBe:function(e){var t=this.terms.filter(function(t){return t.canBe(e)});return new r(t,this.world,this.refText,this.refTerms)}};return Object.keys(e).forEach(function(t){r.prototype[t]=e[t]}),r}},{}],187:[function(t,e,r){"use strict";e.exports=function(e){var r={clone:function(){var t=this.terms.map(function(t){return t.clone()});return new e(t,this.world,this.refText,null)},hyphenate:function(){var r=this;return this.terms.forEach(function(t,e){e!==r.terms.length-1&&(t.whitespace.after="-"),0!==e&&(t.whitespace.before="")}),this},dehyphenate:function(){return this.terms.forEach(function(t){"-"===t.whitespace.after&&(t.whitespace.after=" ")}),this},trim:function(){return this.length<=0||(this.terms[0].whitespace.before="",this.terms[this.terms.length-1].whitespace.after=""),this}};return Object.keys(r).forEach(function(t){e.prototype[t]=r[t]}),e}},{}],188:[function(t,e,r){"use strict";var a=function(t){var e=[];return"Terms"===t.isA?e=t.terms:"Text"===t.isA?e=t.flatten().list[0].terms:"Term"===t.isA&&(e=[t]),e};r.deleteThese=function(t,e){var r=a(e);return t.terms=t.terms.filter(function(t){for(var e=0;e<r.length;e++)if(t===r[e])return!1;return!0}),t},r.insertAt=function(t,e,r){r.dirty=!0;var n=a(r);return 0<e&&n[0]&&!n[0].whitespace.before&&(n[0].whitespace.before=" "),Array.prototype.splice.apply(t,[e,0].concat(n)),t}},{}],189:[function(t,e,r){"use strict";e.exports={fns:t("../fns"),Term:t("../term")}},{"../fns":3,"../term":143}],190:[function(t,e,r){"use strict";var a=t("./index"),i=t("./tokenize"),n=t("./paths"),o=n.Terms,s=n.fns;e.exports=function(t,e){var r=(s.isArray(t)?t:(t=s.ensureString(t),i(t))).map(function(t){return o.fromString(t,e)}),n=new a(r,e);return n.list.forEach(function(t){t.refText=n}),n}},{"./index":192,"./paths":205,"./tokenize":207}],191:[function(t,e,r){"use strict";e.exports={found:function(){return 0<this.list.length},parent:function(){return this.original||this},length:function(){return this.list.length},isA:function(){return"Text"},whitespace:function(){var t=this;return{before:function(e){return t.list.forEach(function(t){t.whitespace.before(e)}),t},after:function(e){return t.list.forEach(function(t){t.whitespace.after(e)}),t}}}}},{}],192:[function(t,e,r){"use strict";var i=t("./getters");function a(t,e,r){this.list=t||[],"function"==typeof e&&(e=e()),this.world=function(){return e},this.original=r;for(var n=Object.keys(i),a=0;a<n.length;a++)Object.defineProperty(this,n[a],{get:i[n[a]]})}(e.exports=a).addMethods=function(t,e){for(var r=Object.keys(e),n=0;n<r.length;n++)t.prototype[r[n]]=e[r[n]]},a.makeSubset=function(t,e){var r=function(t,e,r){a.call(this,t,e,r)};return r.prototype=Object.create(a.prototype),a.addMethods(r,t),r.find=e,r},t("./methods/misc")(a),t("./methods/loops")(a),t("./methods/match")(a),t("./methods/out")(a),t("./methods/sort")(a),t("./methods/split")(a),t("./methods/normalize")(a),t("./subsets")(a);var o={acronyms:t("../subset/acronyms"),adjectives:t("../subset/adjectives"),adverbs:t("../subset/adverbs"),contractions:t("../subset/contractions"),dates:t("../subset/dates"),nouns:t("../subset/nouns"),people:t("../subset/people"),sentences:t("../subset/sentences"),terms:t("../subset/terms"),possessives:t("../subset/possessives"),values:t("../subset/values"),verbs:t("../subset/verbs"),ngrams:t("../subset/ngrams"),startGrams:t("../subset/ngrams/startGrams"),endGrams:t("../subset/ngrams/endGrams")};Object.keys(o).forEach(function(n){a.prototype[n]=function(t,e){var r=o[n].find(this,t,e);return new o[n](r.list,this.world,this.parent)}}),a.prototype.words=a.prototype.terms},{"../subset/acronyms":9,"../subset/adjectives":10,"../subset/adverbs":17,"../subset/contractions":23,"../subset/dates":25,"../subset/ngrams":35,"../subset/ngrams/endGrams":32,"../subset/ngrams/startGrams":36,"../subset/nouns":38,"../subset/people":49,"../subset/possessives":51,"../subset/sentences":52,"../subset/terms":58,"../subset/values":65,"../subset/verbs":75,"./getters":191,"./methods/loops":193,"./methods/match":194,"./methods/misc":195,"./methods/normalize":196,"./methods/out":197,"./methods/sort":202,"./methods/split":204,"./subsets":206}],193:[function(t,e,r){"use strict";var n=["toTitleCase","toUpperCase","toLowerCase","toCamelCase","hyphenate","dehyphenate","trim","insertBefore","insertAfter","insertAt","replace","replaceWith","delete","lump","tagger","unTag"];e.exports=function(t){n.forEach(function(e){t.prototype[e]=function(){for(var t=0;t<this.list.length;t++)this.list[t][e].apply(this.list[t],arguments);return this}}),t.prototype.tag=function(){if(0===this.list.length)return this;for(var t=0;t<this.list.length;t++)this.list[t].tag.apply(this.list[t],arguments);return this}}},{}],194:[function(t,e,r){"use strict";var u=t("../../../terms/match/lib/syntax"),a=t("../../../terms");e.exports=function(s){var i=function(e,r){var n=[];return e.list.forEach(function(t){t.terms.forEach(function(t){!0===r.hasOwnProperty(t.normal)&&n.push(t)})}),n=n.map(function(t){return new a([t],e.world(),e,t.parentTerms)}),new s(n,e.world(),e.parent)},o=function(t,e){var r=e.reduce(function(t,e){return t[e]=!0,t},{});return i(t,r)},t={match:function(t,e){if(0===this.list.length||null==t){var r=this.parent||this;return new s([],this.world(),r)}if("string"==typeof t||"number"==typeof t)return function(t,e,r){var n=[];e=u(e),t.list.forEach(function(t){t.match(e,r).list.forEach(function(t){n.push(t)})});var a=t.parent||t;return new s(n,t.world(),a)}(this,t,e);var n,a=Object.prototype.toString.call(t);return"[object Array]"===a?o(this,t):"[object Object]"===a?"Text"===t.isA?(this,n=t.out("array"),o(this,n)):i(this,t):this},not:function(r,n){var a=[];this.list.forEach(function(t){var e=t.not(r,n);a=a.concat(e.list)});var t=this.parent||this;return new s(a,this.world(),t)},if:function(t){for(var e=[],r=0;r<this.list.length;r++)!0===this.list[r].has(t)&&e.push(this.list[r]);var n=this.parent||this;return new s(e,this.world(),n)},ifNo:function(t){for(var e=[],r=0;r<this.list.length;r++)!1===this.list[r].has(t)&&e.push(this.list[r]);var n=this.parent||this;return new s(e,this.world(),n)},has:function(t){for(var e=0;e<this.list.length;e++)if(!0===this.list[e].has(t))return!0;return!1},before:function(t){for(var e=[],r=0;r<this.list.length;r++){var n=this.list[r].matchOne(t);if(n){var a=n[0].index(),i=this.list[r].slice(0,a);0<i.length&&e.push(i)}}var o=this.parent||this;return new s(e,this.world(),o)},after:function(t){for(var e=[],r=0;r<this.list.length;r++){var n=this.list[r].matchOne(t);if(n){var a=n[n.length-1].index(),i=this.list[r].slice(a+1,this.list[r].length);0<i.length&&e.push(i)}}var o=this.parent||this;return new s(e,this.world(),o)}};return t.and=t.match,t.notIf=t.ifNo,t.only=t.if,t.onlyIf=t.if,s.addMethods(s,t),s}},{"../../../terms":165,"../../../terms/match/lib/syntax":175}],195:[function(t,e,r){"use strict";function n(t){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var o=t("../../terms");e.exports=function(i){var t={all:function(){return this.parent},index:function(){return this.list.map(function(t){return t.index()})},wordCount:function(){return this.terms().length},data:function(){return this.list.map(function(t){return t.data()})},map:function(n){var a=this;return this.list.map(function(t,e){var r=new i([t],a.world);return n(r,e)})},forEach:function(n){var a=this;return this.list.forEach(function(t,e){var r=new i([t],a.world);n(r,e)}),this},filter:function(n){var a=this,t=this.list.filter(function(t,e){var r=new i([t],a.world);return n(r,e)});return new i(t,this.world)},reduce:function(n,t){var a=this;return this.list.reduce(function(t,e){var r=new i([e],a.world);return n(t,r)},t)},find:function(t){for(var e=0;e<this.list.length;e++){var r=this.list[e],n=new i([r],this.world);if(t(n))return n}},clone:function(){var t=this.list.map(function(t){return t.clone()});return new i(t,this.world)},term:function(n){var a=this,t=this.list.map(function(t){var e=[],r=t.terms[n];return r&&(e=[r]),new o(e,a.world,a.refText,a.refTerms)});return new i(t,this.world,this.parent)},firstTerm:function(){return this.match("^.")},lastTerm:function(){return this.match(".$")},slice:function(t,e){return this.list=this.list.slice(t,e),this},get:function(t){if(!t&&0!==t||!this.list[t])return new i([],this.world,this.parent);var e=this.list[t];return new i([e],this.world,this.parent)},first:function(t){return t||0===t?new i(this.list.slice(0,t),this.world,this.parent):this.get(0)},last:function(t){if(!t&&0!==t)return this.get(this.list.length-1);var e=this.list.length,r=e-t;return new i(this.list.slice(r,e),this.world,this.parent)},concat:function(){for(var t=0;t<arguments.length;t++){var e=arguments[t];"object"===n(e)&&("Text"===e.isA&&e.list&&(this.list=this.list.concat(e.list)),"Terms"===e.isA&&this.list.push(e))}return this},flatten:function(){var e=[];if(this.list.forEach(function(t){e=e.concat(t.terms)}),!e.length)return new i(null,this.world,this.parent);var t=new o(e,this.world,this,null);return new i([t],this.world,this.parent)},canBe:function(e){return this.list.forEach(function(t){t.terms=t.terms.filter(function(t){return t.canBe(e)})}),this},random:function(t){t=t||1;var e=Math.floor(Math.random()*this.list.length),r=this.list.slice(e,e+t);if(r.length<t){var n=t-r.length;e<n&&(n=e),r=r.concat(this.list.slice(0,n))}return new i(r,this.world,this.parent)},setPunctuation:function(e){return this.list.forEach(function(t){return t.setPunctuation(e)}),this},getPunctuation:function(t){return t||0===t?this.list[t]?this.list[t].getPunctuation():"":this.list.map(function(t){return t.getPunctuation()})},offset:function(){return this.out("offset")},text:function(){return this.out("text")}};t.eq=t.get,t.join=t.flatten,i.addMethods(i,t)}},{"../../terms":165}],196:[function(t,e,r){"use strict";var n=t("../../term/methods/normalize/unicode"),a={whitespace:!0,case:!0,numbers:!0,punctuation:!0,unicode:!0,contractions:!0,acronyms:!0,parentheses:!1,possessives:!1,plurals:!1,verbs:!1,honorifics:!1},i={whitespace:function(t){return t.terms().list.forEach(function(t,e){var r=t.terms[0];0<e&&!r.silent_term?r.whitespace.before=" ":0===e&&(r.whitespace.before=""),!(r.whitespace.after="")===r.tags.StartQuotation&&(r.whitespace.before+='"'),!0===r.tags.EndQuotation&&(r.whitespace.after='"'+r.whitespace.after)}),t},case:function(t){return t.list.forEach(function(r){r.terms.forEach(function(t,e){0===e||t.tags.Person||t.tags.Place||t.tags.Organization||r.toLowerCase()})}),t},numbers:function(t){return t.values().toNumber(),t},punctuation:function(t){return t.list.forEach(function(t){if(t.terms.length){t.terms[0]._text=t.terms[0]._text.replace(/^¿/,"");for(var e=0;e<t.terms.length-1;e++){var r=t.terms[e];r._text=r._text.replace(/[:;,]$/,"")}var n=t.terms[t.terms.length-1];n._text=n._text.replace(/\.+$/,"."),n._text=n._text.replace(/!+$/,"!"),n._text=n._text.replace(/\?+!?$/,"?")}}),t},unicode:function(t){return t.list.forEach(function(t){t.terms.forEach(function(t){t.text=n(t.text)})}),t},contractions:function(t){return t.contractions().expand(),t},acronyms:function(t){return t.acronyms().stripPeriods(),t},possessives:function(t){return t.possessives().strip(),t},parentheses:function(t){return t.parentheses().delete(),t},plurals:function(t){return t.nouns().toSingular(),t},verbs:function(t){return t.verbs().toInfinitive(),t},honorifics:function(t){return t.delete("#Honorific")}};e.exports=function(t){t.prototype.normalize=function(e){var r=this;e=e||{};var n=Object.assign({},a);return Object.keys(e).forEach(function(t){n[t]=e[t]}),Object.keys(n).forEach(function(t){n[t]&&void 0!==i[t]&&(r=i[t](r))}),r}}},{"../../term/methods/normalize/unicode":151}],197:[function(t,e,r){"use strict";var n=t("./topk"),a=t("./offset"),i=t("./indexes"),o=t("../paths").fns,s={text:function(t){return t.list.reduce(function(t,e){return t+e.out("text")},"")},match:function(t){return t.list.reduce(function(t,e){return t+e.out("match")},"")},normal:function(t){return t.list.map(function(t){var e=t.out("normal");if(t.last()){var r=t.getPunctuation();"."!==r&&"!"!==r&&"?"!==r||(e+=r)}return e}).join(" ")},root:function(t){return t.list.map(function(t){return t.out("root")}).join(" ")},offsets:function(t){return a(t)},index:function(t){return i(t)},grid:function(t){return t.list.reduce(function(t,e){return t+e.out("grid")},"")},color:function(t){return t.list.reduce(function(t,e){return t+e.out("color")},"")},array:function(t){return t.list.map(function(t){return t.out("normal")})},csv:function(t){return t.list.map(function(t){return t.out("csv")}).join("\n")},newlines:function(t){return t.list.map(function(t){return t.out("newlines")}).join("\n")},json:function(t){return t.list.reduce(function(t,e){var r=e.terms.map(function(t){return{text:t.text,normal:t.normal,tags:t.tag}});return t.push(r),t},[])},html:function(t){return"<span> "+t.list.reduce(function(t,e){return t+"\n <span>"+e.terms.reduce(function(t,e){return t+"\n "+e.out("html")},"")+"\n </span>"},"")+"\n</span>"},terms:function(t){var e=[];return t.list.forEach(function(t){t.terms.forEach(function(t){e.push({text:t.text,normal:t.normal,tags:Object.keys(t.tags)})})}),e},debug:function(t){return console.log("===="),t.list.forEach(function(t){console.log(" --"),t.debug()}),t},topk:function(t){return n(t)},custom:function(t,e){return t.list.map(function(t){return t.out(e)})}};s.plaintext=s.text,s.normalized=s.normal,s.colors=s.color,s.tags=s.terms,s.offset=s.offsets,s.idexes=s.index,s.frequency=s.topk,s.freq=s.topk,s.arr=s.array,e.exports=function(t){return t.prototype.out=function(t){if("string"==typeof t){if(s[t])return s[t](this)}else if(!0===o.isObject(t))return s.custom(this,t);return s.text(this)},t.prototype.debug=function(){return s.debug(this)},t}},{"../paths":201,"./indexes":198,"./offset":199,"./topk":200}],198:[function(t,e,r){"use strict";e.exports=function(t){var n=[],a={};t.terms().list.forEach(function(t){a[t.terms[0].uid]=!0});var i=0;return t.all().list.forEach(function(t,r){t.terms.forEach(function(t,e){void 0!==a[t.uid]&&n.push({text:t.text,normal:t.normal,term:i,sentence:r,sentenceTerm:e}),i+=1})}),n}},{}],199:[function(t,e,r){"use strict";e.exports=function(t){var s=t.all();return t.list.map(function(t){for(var e=[],r=0;r<t.terms.length;r++)e.push(t.terms[r].normal);var n=function(t){var e=t.terms;if(e.length<=2)return t.out("normal");for(var r=e[0].normal,n=1;n<e.length-1;n++){var a=e[n];r+=a.whitespace.before+a.text+a.whitespace.after}return r+" "+e[t.terms.length-1].normal}(t),a=t.out("text"),i=function(t,e){for(var r=0,n=0;n<t.list.length;n++)for(var a=0;a<t.list[n].terms.length;a++){var i=t.list[n].terms[a];if(i.uid===e.uid)return r;r+=i.whitespace.before.length+i._text.length+i.whitespace.after.length}return null}(s,t.terms[0]),o=i+t.terms[0].whitespace.before.length;return{text:a,normal:t.out("normal"),offset:i,length:a.length,wordStart:o,wordEnd:o+n.length}})}},{}],200:[function(t,e,r){"use strict";e.exports=function(e,t){var r={};e.list.forEach(function(t){var e=t.out("root");r[e]=r[e]||0,r[e]+=1});var n=[];return Object.keys(r).forEach(function(t){n.push({normal:t,count:r[t]})}),n.forEach(function(t){t.percent=parseFloat((t.count/e.list.length*100).toFixed(2))}),n=n.sort(function(t,e){return t.count>e.count?-1:1}),t&&(n=n.splice(0,t)),n}},{}],201:[function(t,e,r){"use strict";e.exports=t("../paths")},{"../paths":205}],202:[function(t,e,r){"use strict";var n=t("./methods");e.exports=function(e){var t={sort:function(t){return(t=(t=t||"alphabetical").toLowerCase())&&"alpha"!==t&&"alphabetical"!==t?"chron"===t||"chronological"===t?n.chron(this,e):"length"===t?n.lengthFn(this,e):"freq"===t||"frequency"===t?n.freq(this,e):"wordcount"===t?n.wordCount(this,e):this:n.alpha(this,e)},reverse:function(){return this.list=this.list.reverse(),this},unique:function(){var r={};return this.list=this.list.filter(function(t){var e=t.out("root");return!r.hasOwnProperty(e)&&(r[e]=!0)}),this}};return e.addMethods(e,t),e}},{"./methods":203}],203:[function(t,e,r){"use strict";var n=function(t){return(t=t.sort(function(t,e){return t.index>e.index?1:t.index===e.index?0:-1})).map(function(t){return t.ts})};r.alpha=function(t){return t.list.sort(function(t,e){if(t===e)return 0;if(t.terms[0]&&e.terms[0]){if(t.terms[0].root>e.terms[0].root)return 1;if(t.terms[0].root<e.terms[0].root)return-1}return t.out("root")>e.out("root")?1:-1}),t},r.chron=function(t){var e=t.list.map(function(t){return{ts:t,index:t.termIndex()}});return t.list=n(e),t},r.lengthFn=function(t){var e=t.list.map(function(t){return{ts:t,index:t.chars()}});return t.list=n(e).reverse(),t},r.wordCount=function(t){var e=t.list.map(function(t){return{ts:t,index:t.length}});return t.list=n(e),t},r.freq=function(t){var r={};t.list.forEach(function(t){var e=t.out("root");r[e]=r[e]||0,r[e]+=1});var e=t.list.map(function(t){var e=r[t.out("root")]||0;return{ts:t,index:-1*e}});return t.list=n(e),t}},{}],204:[function(t,e,r){"use strict";e.exports=function(t){return t.addMethods(t,{splitAfter:function(e,r){var n=[];return this.list.forEach(function(t){t.splitAfter(e,r).forEach(function(t){n.push(t)})}),this.list=n,this},splitBefore:function(e,r){var n=[];return this.list.forEach(function(t){t.splitBefore(e,r).forEach(function(t){n.push(t)})}),this.list=n,this},splitOn:function(e,r){var n=[];return this.list.forEach(function(t){t.splitOn(e,r).forEach(function(t){n.push(t)})}),this.list=n,this}}),t}},{}],205:[function(t,e,r){arguments[4][201][0].apply(r,arguments)},{"../paths":8,dup:201}],206:[function(t,e,r){"use strict";var a=t("../subset/sentences/isQuestion");e.exports=function(n){var e={clauses:function(t){var e=this.splitAfter("#ClauseEnd");return"number"==typeof t&&(e=e.get(t)),e},hashTags:function(t){var e=this.match("#HashTag").terms();return"number"==typeof t&&(e=e.get(t)),e},organizations:function(t){var e=this.splitAfter("#Comma");return e=e.match("#Organization+"),"number"==typeof t&&(e=e.get(t)),e},phoneNumbers:function(t){var e=this.splitAfter("#Comma");return e=e.match("#PhoneNumber+"),"number"==typeof t&&(e=e.get(t)),e},places:function(t){var e=this.splitAfter("#Comma");return e=e.match("#Place+"),"number"==typeof t&&(e=e.get(t)),e},quotations:function(t){var e=this.match("#Quotation+"),i=[];return e.list.forEach(function(r){var n=0,a=null;r.terms.forEach(function(t,e){!0===t.tags.StartQuotation&&(0===n&&(a=e),n+=1),0<n&&!0===t.tags.EndQuotation&&(n-=1),0===n&&null!==a&&(i.push(r.slice(a,e+1)),a=null)}),null!==a&&i.push(r.slice(a,r.terms.length))}),e.list=i,"number"==typeof t&&(e=e.get(t)),e},topics:function(t){var e=this.clauses(),r=e.people();return r.concat(e.places()),r.concat(e.organizations()),(r=r.not(["someone","man","woman","mother","brother","sister","father"])).sort("chronological"),"number"==typeof t&&(r=r.get(t)),r},urls:function(t){var e=this.match("#Url");return"number"==typeof t&&(e=e.get(t)),e},questions:function(t){var e=this.all();"number"==typeof t&&(e=e.get(t));var r=e.list.filter(function(t){return a(t)});return new n(r,this.world,this.parent)},statements:function(t){var e=this.all();"number"==typeof t&&(e=e.get(t));var r=e.list.filter(function(t){return!1===a(t)});return new n(r,this.world,this.parent)},parentheses:function(t){var e=this.match("#Parentheses+");return e=e.splitAfter("#EndBracket"),"number"==typeof t&&(e=e.get(t)),e}};return Object.keys(e).forEach(function(t){n.prototype[t]=e[t]}),n}},{"../subset/sentences/isQuestion":53}],207:[function(t,e,r){"use strict";var n=Object.keys(t("../world/more-data/abbreviations")),u=new RegExp("\\b("+n.join("|")+")[.!?‽⸘‼⁇-⁉] *$","i"),l=/[ .][A-Z]\.? *$/i,c=/(?:\u2026|\.{2,}) *$/,h=/((?:\r?\n|\r)+)/,f=/(\S.+?[.!?\u203D\u2E18\u203C\u2047-\u2049])(?=\s+|$)/g,m=/[a-z0-9\u0000-\u007F]/i,d=/\S/;e.exports=function(o){o=o||"";var t=[],e=[];if(!(o=String(o))||"string"!=typeof o||!1===d.test(o))return t;for(var r=function(t){for(var e=[],r=o.split(h),n=0;n<r.length;n++)for(var a=r[n].split(f),i=0;i<a.length;i++)e.push(a[i]);return e}(),n=0;n<r.length;n++){var a=r[n];if(void 0!==a&&""!==a){if(!1===d.test(a)){if(e[e.length-1]){e[e.length-1]+=a;continue}if(r[n+1]){r[n+1]=a+r[n+1];continue}}e.push(a)}}for(var i=0;i<e.length;i++){var s=e[i];e[i+1]&&m.test(s)&&(u.test(s)||l.test(s)||c.test(s))?e[i+1]=s+(e[i+1]||""):s&&0<s.length&&m.test(s)&&(t.push(s),e[i]="")}return 0===t.length?[o]:t}},{"../world/more-data/abbreviations":216}],208:[function(t,e,r){"use strict";e.exports='{"words":"Comparative¦better|Superlative¦earlier|PresentTense¦sounds|Value¦a few|Noun¦autumn,daylight9eom,here,no doubt,one d8s5t2w0yesterd8;eek0int5;d6end;mr1o0;d4morrow;!w;ome 1tandard3umm0;er;d0point;ay; time|Copula¦a1is,w0;as,ere;m,re|Condition¦if,unless|PastTense¦be2came,d1had,mea0sa1taken,we0;nt;id;en,gan|Gerund¦accord0be0develop0go0result0stain0;ing|Negative¦n0;ever,o0;!n,t|QuestionWord¦how3wh0;at,e1ich,o0y;!m,se;n,re; come,\'s|Singular¦a05bYcTdPeNfKgJhFici09jel06kitty,lEmCnBoAp7question mark,r6s4t1us 0;dollUstV; rex,a1h0ic,ragedy,v show;ere,i06;l02x return;ky,tu0uper bowl,yst05;dIff;alZi02oom;a1robl02u0;dCrpo8;rt,tE;cean,thers;othiXumbG;ayfTeeNo0;del,nopoS;iRunch;ead start,o0;lPme1u0;se;! run;adfMirlIlaci8od,rand slam,ulM;amiLly,olLr1un0;diN;iGosD;conomy,gg,ner3v0xampG;ent;eath,inn2o0ragonfG;cument6g0iFlFor;gy;er;an3eiliFhocol2i0ottage,redit card;ty,vil w0;ar;ate;ary;ankiAel7les9o2reakfast,u0;n0tterf6;ti8;dy,tt2y0;fri0;end;le;d1l0noma0;ly; homin2verti0;si0;ng;em|Infinitive¦0:6Y;1:7C;2:7A;3:79;4:74;5:5F;6:6D;7:6L;8:78;9:6W;A:73;B:7D;C:76;D:6R;E:68;F:60;a6Qb69c5Bd4Je43f3Qg3Jh3Ci2Zj2Xk2Tl2Km2Bn28o24p1Pques3Rr0Xs05tWuRvOwHyG;awn,ield;aJe24hist7iIoGre6H;nd0rG;k,ry;n,pe,sh,th0;lk,nHrGsh,tDve;n,raB;d0t;aHiGo8;ew,sA;l6Rry;nHpGr3se;gra4Wli49;dGi8lo65;erGo;go,mi5H;aNeMhKie,oJrHuGwi4;ne,rn;aGe0Ui60u4y;de,in,nsf0p,v5O;r37uD;ank,rG;eat2Vi2;nd,st;ke,lk,rg5Os8;a06c03eZhWi4Jkip,lVmUneTo56pQtJuGwitD;bmAck,ff0gge4ppHrGspe6;ge,pri1rou53vi2;ly,o3D;aLeKoJrHuG;dy,mb7;aEeGi2;ngth2Lss,tD;p,re;m,p;in,ke,r0Yy;iHlaFoil,rinG;g,k7;n,t;ak,e3E;aFe22i7o5B;am,e1Qip;aHiv0oG;ck,ut;re,ve;arDeIle6nHr2tG;!t7;d,se;k,m;aHo5rG;atDew;le,re;il,ve;a05eIisk,oHuG;b,in,le,n,sh;am,ll;a01cZdu9fYgXje6lUmTnt,pQquPsKtJvGwa5V;eGiew,o4U;al,l,rG;se,t;aEi5u42;eJi4oItG;!o5rG;i6uc20;l2rt;mb7nt,r2;e4i5;air,eHlGo40reseB;a9y;at;aEemb0i3Wo2;aHeGi2y;a1nt;te,x;a5Dr4A;act1Yer,le6u1;a12ei2k5PoGyc7;gni2Cnci7rd;ch,li2Bs5N;i1nG;ge,k;aTerSiRlPoNrIuG;b21ll,mp,rGsh,t;cha1s4Q;ai1eJiBoG;cHdu9greChibAmi1te4vG;e,i2U;eClaim;di6pa5ss,veB;iBp,rtr43sGur;e,t;a3RuG;g,n3;ck,le;fo32mAsi4;ck,iBrt4Mss,u1y;bIccur,ff0pera8utweHverGwe;co47lap,ta3Qu1whelm;igh;ser2taE;eHotG;e,i9;ed,gle6;aLeKiIoHuG;ltip3Frd0;nit14ve;nGrr13;d,g7us;asu5lt,n0Qr3ssa3;intaEke d40na3rHtG;ch,t0;ch,k39ry;aMeLiIoGu1F;aGck,ok,ve;d,n;ft,ke,mAnHstGve;!en;e,k;a2Gc0Ht;b0Qck,uG;gh,nD;eIiHnoG;ck,w;ck,ll,ss;ep;am,oEuG;d3mp;gno5mQnGss3I;cOdica8flu0NhNsKtIvG;eGol2;nt,st;erGrodu9;a6fe5;i4tG;aGru6;ll;abAibA;lu1Fr1D;agi22pG;lemeBo20ro2;aKeIi5oHuG;nt,rry;ld fa4n03pe,st;aGlp;d,t;nd7ppGrm,te;en;aLet,loCoKrIuG;arGeCi14;ant39d;aGip,ow,umb7;b,sp;es,ve1I;in,th0ze;aQeaPiNlLoIracHuncG;ti3I;tu5;cus,lHrG;ce,eca4m,s30;d,l22;aFoG;at,od,w;gu5lGniFx;e,l;r,tu5;il,ll,vG;or;a13cho,dAle6mSnPstNvalua8xG;a0AcLerKi4pGte16;a15eHlaEoGreC;rt,se;ct,riG;en9;ci1t;el,han3;abGima8;liF;ab7couXdHfor9ga3han9j03riDsu5t0vG;isi2Vy;!u5;body,er3pG;hasiGow0;ze;a06eUiMoLrHuG;mp;aIeHiGop;ft;am,ss;g,in;!d3ubt;e,ff0p,re6sHvG;e,iXor9;aJcGli13miCpl18tinguiF;oGuC;uGv0;ra3;gr1YppG;ear,ro2;al,cNem,fLliv0ma0Cny,pKsHterG;mi0D;cribe,er2iHtrG;oy;gn,re;a08e07i6osA;eGi08y;at,ct;iIlHrG;ea1;a5i04;de;ma3n9re,te;a0Ae09h06i8l03oJrGut;aHeGoCuFy;a8dA;ck,ve;llYmSnHok,py,uGv0;gh,nt;cePdu6fMsKtIvG;eGin9;rt,y;aEin0XrG;a4ibu8ol;iGtitu8;d0st;iHoGroB;rm;gu5rm;rn;biKe,foJmaIpG;a5laE;re;nd;rt;ne;ap1e6;aHiGo1;ng,p;im,w;aHeG;at,ck,w;llen3n3r3se;a1nt0;ll,ncHrGt0u1;e,ry;el;aUeQloPoNrKuG;dgIlHrG;n,y;ly;et;aHuF;sh;ke;a4mb,o4rrGth0un9;ow;ck;ar,coSgElHnefAtrG;ay;ie2ong;in;nGse;!g;band0Jc0Bd06ffo05gr04id,l01mu1nYppTrQsKttGvoid,waA;acIeHra6;ct;m0Fnd;h,k;k,sG;eIiHocia8uG;me;gn,st;mb7rt;le;chHgGri2;ue;!i2;eaJlIroG;aDve;ch;aud,y;l,r;noun9sw0tG;icipa8;ce;lHt0;er;e3ow;ee;rd;aRdIju4mAoR;it;st;!reC;ss;cJhie2knowled3tiva8;te;ge;ve;eIouBu1;se;nt;pt;on|Actor¦aJbGcFdCengineIfAgardenIh9instructPjournalLlawyIm8nurse,opeOp5r3s1t0;echnCherapK;ailNcientJoldiGu0;pervKrgeon;e0oofE;ceptionGsearC;hotographClumbColi1r0sychologF;actitionBogrammB;cem6t5;echanic,inist9us4;airdress8ousekeep8;arm7ire0;fight6m2;eputy,iet0;ici0;an;arpent2lerk;ricklay1ut0;ch0;er;ccoun6d2ge7r0ssis6ttenda7;chitect,t0;ist;minist1v0;is1;rat0;or;ta0;nt|Honorific¦aObrigadiNcHdGexcellency,fiBking,liDmaAofficNp6queen,r3s0taoiseach,vice5;e0ultJ;c0rgeaC;ond liAretary;abbi,e0;ar0verend; adJ;astFr0;eside6i0ofessE;me ministEnce0;!ss;gistrate,r4yB;eld mar3rst l0;ady,i0;eutena0;nt;shA;oct5utchess;aptain,hance3o0;lonel,mmand4ngress0unci2;m0wom0;an;ll0;or;er;d0yatullah;mir0;al|SportsTeam¦0:1M;1:1T;2:1U;a1Rb1Dc0Zd0Qfc dallas,g0Nhouston 0Mindiana0Ljacksonville jagua0k0Il0Fm02newVoRpKqueens parkJrIsAt5utah jazz,vancouver whitecaps,w3yY;ashington 3est ham0Xh16;natio21redski1wizar12;ampa bay 6e5o3;ronto 3ttenham hotspur;blu1Hrapto0;nnessee tita1xasD;buccanee0ra1G;a7eattle 5heffield0Qporting kansas13t3;. louis 3oke12;c1Srams;mari02s3;eah1IounI;cramento Sn 3;antonio spu0diego 3francisco gi0Bjose earthquak2;char0EpaB;eal salt lake,o04; ran0C;a8h5ittsburgh 4ortland t3;imbe0rail blaze0;pirat2steele0;il3oenix su1;adelphia 3li2;eagl2philNunE;dr2;akland 4klahoma city thunder,r3;i10lando magic;athle0Trai3;de0; 3castle05;england 6orleans 5york 3;city fc,giUje0Lkn02me0Lred bul19y3;anke2;pelica1sain0J;patrio0Irevolut3;ion;aBe9i3ontreal impact;ami 7lwaukee b6nnesota 3;t4u0Rvi3;kings;imberwolv2wi1;re0Cuc0W;dolphi1heat,marli1;mphis grizz3ts;li2;nchester 5r3vN;i3li1;ne0;c00u0H;a4eicesterYos angeles 3;clippe0dodFlaA; galaxy,ke0;ansas city 3nH;chiefs,ro3;ya0M; pace0polis colX;astr0Edynamo,rockeWtexa1;i4olden state warrio0reen bay pac3;ke0;anT;.c.Aallas 7e3i0Cod5;nver 5troit 3;lio1pisto1ti3;ge0;bronc06nuggeO;cowboUmav3;er3;ic06; uX;arCelNh8incinnati 6leveland 5ol3;orado r3umbus crew sc;api5ocki2;brow1cavalie0india1;benga03re3;ds;arlotte horCicago 3;b4cubs,fire,wh3;iteE;ea0ulY;di3olina panthe0;ff3naW; c3;ity;altimore ElAoston 7r3uffalo bilT;av2e5ooklyn 3;ne3;ts;we0;cel4red3; sox;tics;ackburn rove0u3;e ja3;ys;rs;ori3rave1;ol2;rizona Ast8tlanta 3;brav2falco1h4u3;nited;aw9;ns;es;on villa,r3;os;c5di3;amondbac3;ks;ardi3;na3;ls|Uncountable¦0:1C;a1Hb1Bc12e0Wf0Qg0Mh0Gi0Dj0Cknowled1Gl07mYnXoWpRrOsCt8vi7w1;a5ea0Ai4o1;o2rld1;! seI;d,l;ldlife,ne;rmth,t0;neg0Xol08;e3hund0ime,oothpaste,r1una;affRou1;ble,sers,t;a,nnis;aAcene07e9h8il7now,o6p3te2u1;g0Rnshi0L;am,el;ace2e1;ciOed;!c12;ap,cc0ft0B;k,v0;eep,opp0O;riJ;d07fe0Wl1nd;m0Qt;ain,e1i0W;c1laxa0Csearch;ogni0Brea0B;a4e2hys0Elast9o1ress00;rk,w0;a1pp0trol;ce,nR;p0tiK;il,xygen;ews,oi0C;a7ea5i4o3u1;mps,s1;ic;nHo08;lk,st;sl1t;es;chine1il,themat00; learn02ry;aught0e3i2u1;ck,g07;ghtnZqu0CteratI;a1isH;th0;ewel7usti08;ce,mp1nformaOtself;ati1ortan06;en05;a4isto3o1;ck1mework,n1spitali01;ey;ry;ir,lib1ppi9;ut;o2r1um,ymnastJ;a7ound;l1ssip;d,f;i5lour,o2ruit,urnit1;ure;od,rgive1wl;ne1;ss;c6sh;conom9duca5lectriciMn3quip4th9very1;body,o1thB;ne;joy1tertain1;ment;tiC;a8elcius,h4iv3loth6o1urrency;al,ffee,ld w1nfusiAttA;ar;ics;aos,e1;e2w1;ing;se;ke,sh;a3eef,is2lood,read,utt0;er;on;g1ss;ga1;ge;c4dvi3irc2mnes1rt;ty;raft;ce;id|Unit¦0:17;a12b10c0Md0Le0Jf0Fg0Bh08in07joule0k01lZmOnNoMpIqHsqCt7volts,w6y4z3°2µ1;g,s;c,f,n;b,e2;a0Lb,d0Rears old,o1;tt0F;att0b;able4b3e2on1sp;!ne0;a2r0B;!l,sp;spo03; ft,uare 1;c0Gd0Ff3i0Dkilo0Hm1ya0C;e0Kil1;e0li0F;eet0o0B;t,uart0;a3e2i1ou0Nt;c0Knt0;rcent,t00;!scals;hms,uVz;an0GewtR;/s,b,e7g,i3l,m2p1²,³;h,s;!²;!/h,cro3l1;e1li05;! DsC²;g05s0A;gPter1;! 2s1;! 1;per second;b,iZm,u1x;men0x0;b,elvin0g,ilo2m1nQ;!/h,ph,²;byYgWmeter1;! 2s1;! 1;per hour;²,³;e1g,z;ct1rtz0;aWogP;al2b,ig9ra1;in0m0;!l1;on0;a3emtOl1tG; oz,uid ou1;nce0;hrenheit0rad0;b,x1;abyH;eciCg,l,mA;arat0eAg,l,m9oulomb0u1;bic 1p0;c5d4fo3i2meAya1;rd0;nch0;ot0;eci2;enti1;me4;!²,³;lsius0nti1;g2li1me1;ter0;ram0;bl,y1;te0;c4tt1;os1;eco1;nd0;re0;!s|Pronoun¦\'em,elle,h4i3me,ourselves,she5th1us,we,you0;!rself;e0ou;m,y;!l,t;e0im;!\'s|Organization¦0:44;a39b2Qc2Ad22e1Yf1Ug1Mh1Hi1Ej1Ak18l14m0Tn0Go0Dp07qu06rZsStFuBv8w3y1;amaha,m0You1w0Y;gov,tu2R;a3e1orld trade organizati3Z;lls fargo,st1;fie23inghou17;l1rner br3B;-m12gree30l street journ25m12;an halNeriz3Uisa,o1;dafo2Gl1;kswagLvo;bs,kip,n2ps,s1;a tod2Qps;es33i1;lev2Wted natio2T; mobi2Jaco bePd bMeAgi frida9h3im horto2Smz,o1witt2V;shiba,y1;ota,s r Y;e 1in lizzy;b3carpen31daily ma2Vguess w2holli0rolling st1Ns1w2;mashing pumpki2Nuprem0;ho;ea1lack eyed pe3Dyrds;ch bo1tl0;ys;l2s1;co,la m13;efoni08us;a6e4ieme2Fnp,o2pice gir5ta1ubaru;rbucks,to2L;ny,undgard1;en;a2Px pisto1;ls;few24insbu25msu1W;.e.m.,adiohead,b6e3oyal 1yan2V;b1dutch she4;ank;/max,aders dige1Ed 1vl30;bu1c1Thot chili peppe2Ilobst27;ll;c,s;ant2Tizno2D;an5bs,e3fiz23hilip morrBi2r1;emier25octer & gamb1Qudenti14;nk floyd,zza hut;psi26tro1uge09;br2Ochina,n2O; 2ason1Wda2E;ld navy,pec,range juli2xf1;am;us;aAb9e5fl,h4i3o1sa,wa;kia,tre dame,vart1;is;ke,ntendo,ss0L;l,s;c,stl3tflix,w1; 1sweek;kids on the block,york09;e,é;a,c;nd1Rs2t1;ional aca2Co,we0P;a,cYd0N;aAcdonald9e5i3lb,o1tv,yspace;b1Knsanto,ody blu0t1;ley crue,or0N;crosoft,t1;as,subisO;dica3rcedes2talli1;ca;!-benz;id,re;\'s,s;c\'s milk,tt11z1V;\'ore08a3e1g,ittle caesa1H;novo,x1;is,mark; pres5-z-boy,bour party;atv,fc,kk,m1od1H;art;iffy lu0Jo3pmorgan1sa;! cha1;se;hnson & johns1Py d1O;bm,hop,n1tv;g,te1;l,rpol; & m,asbro,ewlett-packaSi3o1sbc,yundai;me dep1n1G;ot;tac1zbollah;hi;eneral 6hq,l5mb,o2reen d0Gu1;cci,ns n ros0;ldman sachs,o1;dye1g09;ar;axo smith kliYencore;electr0Gm1;oto0S;a3bi,da,edex,i1leetwood mac,oFrito-l08;at,nancial1restoU; tim0;cebook,nnie mae;b04sa,u3xxon1; m1m1;ob0E;!rosceptics;aiml08e5isney,o3u1;nkin donuts,po0Tran dur1;an;j,w j1;on0;a,f leppa2ll,peche mode,r spiegXstiny\'s chi1;ld;rd;aEbc,hBi9nn,o3r1;aigsli5eedence clearwater reviv1ossra03;al;ca c5l4m1o08st03;ca2p1;aq;st;dplLgate;ola;a,sco1tigroup;! systems;ev2i1;ck fil-a,na daily;r0Fy;dbury,pital o1rl\'s jr;ne;aFbc,eBf9l5mw,ni,o1p,rexiteeV;ei3mbardiJston 1;glo1pizza;be;ng;ack & deckFo2ue c1;roW;ckbuster video,omingda1;le; g1g1;oodriM;cht3e ge0n & jer2rkshire hathaw1;ay;ryG;el;nana republ3s1xt5y5;f,kin robbi1;ns;ic;bWcRdidQerosmith,ig,lKmEnheuser-busDol,pple9r6s3t&t,v2y1;er;is,on;hland1sociated F; o1;il;by4g2m1;co;os; compu2bee1;\'s;te1;rs;ch;c,d,erican3t1;!r1;ak; ex1;pre1;ss; 4catel2t1;air;!-luce1;nt;jazeera,qae1;da;as;/dc,a3er,t1;ivisi1;on;demy of scienc0;es;ba,c|Demonym¦0:16;1:13;a0Wb0Nc0Cd0Ae09f07g04h02iYjVkTlPmLnIomHpDqatari,rBs7t5u4v3wel0Rz2;am0Fimbabwe0;enezuel0ietnam0H;g9krai1;aiwThai,rinida0Iu2;ni0Qrkmen;a4cot0Ke3ingapoOlovak,oma0Tpa05udRw2y0X;edi0Kiss;negal0Br08;mo0uU;o6us0Lw2;and0;a3eru0Hhilipp0Po2;li0Ertugu06;kist3lesti1na2raguay0;ma1;ani;amiZi2orweP;caragu0geri2;an,en;a3ex0Mo2;ngo0Erocc0;cedo1la2;gasy,y08;a4eb9i2;b2thua1;e0Dy0;o,t02;azakh,eny0o2uwaiti;re0;a2orda1;ma0Bp2;anN;celandic,nd4r2sraeli,ta02vo06;a2iT;ni0qi;i0oneV;aiDin2ondur0unN;di;amDe2hanai0reek,uatemal0;or2rm0;gi0;i2ren7;lipino,n4;cuadoVgyp6ngliJsto1thiopi0urope0;a2ominXut4;niH;a9h6o4roa3ub0ze2;ch;ti0;lom2ngol5;bi0;a6i2;le0n2;ese;lifor1m2na3;bo2eroo1;di0;angladeshi,el8o6r3ul2;gaG;aziBi2;ti2;sh;li2s1;vi0;aru2gi0;si0;fAl7merBngol0r5si0us2;sie,tr2;a2i0;li0;gent2me1;ine;ba1ge2;ri0;ni0;gh0r2;ic0;an|Region¦a20b1Sc1Id1Des1Cf19g13h10i0Xj0Vk0Tl0Qm0FnZoXpSqPrMsDtAut9v5w2y0zacatec22;o05u0;cat18kZ;a0est vir4isconsin,yomi14;rwick1Qshington0;! dc;er2i0;cto1Ir0;gin1R;acruz,mont;ah,tar pradesh;a1e0laxca1Cusca9;nnessee,x1Q;bas0Jmaulip1PsmI;a5i3o1taf0Nu0ylh12;ffUrrZs0X;me0Zno19uth 0;cRdQ;ber1Hc0naloa;hu0Rily;n1skatchew0Qxo0;ny; luis potosi,ta catari1H;a0hode6;j0ngp01;asth0Lshahi;inghai,u0;e0intana roo;bec,ensVreta0D;ara3e1rince edward0; isT;i,nnsylv0rnambu01;an13;!na;axa0Mdisha,h0klaho1Antar0reg3x03;io;ayarit,eAo2u0;evo le0nav0K;on;r0tt0Qva scot0W;f5mandy,th0; 0ampton0P;c2d1yo0;rk0N;ako0X;aroli0U;olk;bras0Wva00w0; 1foundland0;! and labrador;brunswick,hamp0Gjers0mexiIyork state;ey;a5i1o0;nta0Mrelos;ch2dlanAn1ss0;issippi,ouri;as geraFneso0L;igPoacP;dhya,harasht03ine,ni2r0ssachusetts;anhao,y0;land;p0toba;ur;anca03e0incoln03ouis7;e0iG;ds;a0entucky,hul09;ns07rnata0Cshmir;alis0iangxi;co;daho,llino1nd0owa;ia04;is;a1ert0idalDun9;fordS;mpRwaii;ansu,eorgVlou4u0;an1erre0izhou,jarat;ro;ajuato,gdo0;ng;cesterL;lori1uji0;an;da;sex;e3o1uran0;go;rs0;et;lawaDrbyC;a7ea6hi5o0umbrG;ahui3l2nnectic1rsi0ventry;ca;ut;iLorado;la;apDhuahua;ra;l7m0;bridge2peche;a4r3uck0;ingham0;shi0;re;emen,itish columb2;h1ja cal0sque,var1;iforn0;ia;guascalientes,l3r0;izo1kans0;as;na;a1ber0;ta;ba1s0;ka;ma|Possessive¦anyAh5its,m3noCo1sometBthe0yo1;ir1mselves;ur0;!s;i8y0;!se4;er1i0;mse2s;!s0;!e0;lf;o1t0;hing;ne|Currency¦$,aud,bRcPdKeurJfIgbp,hkd,inr,jpy,kGlEp8r7s3usd,x2y1z0¢,£,¥,ден,лв,руб,฿,₡,₨,€,₭,﷼;lotyRł;en,uanQ;af,of;h0t5;e0il5;k0q0;elL;iel,oubleKp,upeeK;e2ound st0;er0;lingH;n0soG;ceFn0;ies,y;e0i7;i,mpi6;n,r0wanzaByatB;!onaAw;ori7ranc9t;!o8;en3i2kk,o0;b0ll2;ra5;me4n0rham4;ar3;ad,e0ny;nt1;aht,itcoin0;!s|Country¦0:38;1:2L;a2Wb2Dc21d1Xe1Rf1Lg1Bh19i13j11k0Zl0Um0Gn05om3CpZqat1JrXsKtCu6v4wal3yemTz2;a24imbabwe;es,lis and futu2X;a2enezue31ietnam;nuatu,tican city;.5gTkraiZnited 3ruXs2zbeE;a,sr;arab emirat0Kkingdom,states2;! of am2X;k.,s.2; 27a.;a7haBimor-les0Bo6rinidad4u2;nis0rk2valu;ey,me2Xs and caic1T; and 2-2;toba1J;go,kel0Ynga;iw2Vji2nz2R;ki2T;aCcotl1eBi8lov7o5pa2Bri lanka,u4w2yr0;az2ed9itzerl1;il1;d2Qriname;lomon1Vmal0uth 2;afr2IkLsud2O;ak0en0;erra leoEn2;gapo1Wt maart2;en;negKrb0ychellY;int 2moa,n marino,udi arab0;hele24luc0mart1Z;epublic of ir0Com2Cuss0w2;an25;a3eHhilippinTitcairn1Ko2uerto riM;l1rtugE;ki2Bl3nama,pua new0Tra2;gu6;au,esti2;ne;aAe8i6or2;folk1Gth3w2;ay; k2ern mariana1B;or0M;caragua,ger2ue;!ia;p2ther18w zeal1;al;mib0u2;ru;a6exi5icro09o2yanm04;ldova,n2roc4zamb9;a3gol0t2;enegro,serrat;co;c9dagascZl6r4urit3yot2;te;an0i14;shall0Vtin2;ique;a3div2i,ta;es;wi,ys0;ao,ed00;a5e4i2uxembourg;b2echtenste10thu1E;er0ya;ban0Gsotho;os,tv0;azakh1De2iriba02osovo,uwait,yrgyz1D;eling0Jnya;a2erF;ma15p1B;c6nd5r3s2taly,vory coast;le of m19rael;a2el1;n,q;ia,oI;el1;aiSon2ungary;dur0Mg kong;aAermany,ha0Pibralt9re7u2;a5ern4inea2ya0O;!-biss2;au;sey;deloupe,m,tema0P;e2na0M;ce,nl1;ar;bTmb0;a6i5r2;ance,ench 2;guia0Dpoly2;nes0;ji,nl1;lklandTroeT;ast tim6cu5gypt,l salv5ngl1quatorial3ritr4st2thiop0;on0; guin2;ea;ad2;or;enmark,jibou4ominica3r con2;go;!n B;ti;aAentral african 9h7o4roat0u3yprQzech2; 8ia;ba,racao;c3lo2morPngo-brazzaville,okFsta r03te d\'ivoiK;mb0;osD;i2ristmasF;le,na;republic;m2naTpe verde,yman9;bod0ero2;on;aFeChut00o8r4u2;lgar0r2;kina faso,ma,undi;azil,itish 2unei;virgin2; is2;lands;liv0nai4snia and herzegoviGtswaGuvet2; isl1;and;re;l2n7rmuF;ar2gium,ize;us;h3ngladesh,rbad2;os;am3ra2;in;as;fghaFlCmAn5r3ustr2zerbaijH;al0ia;genti2men0uba;na;dorra,g4t2;arct6igua and barbu2;da;o2uil2;la;er2;ica;b2ger0;an0;ia;ni2;st2;an|City¦a2Wb26c1Wd1Re1Qf1Og1Ih1Ai18jakar2Hk0Zl0Tm0Gn0Co0ApZquiYrVsLtCuBv8w3y1z0;agreb,uri1Z;ang1Te0okohama;katerin1Hrev34;ars3e2i0rocl3;ckl0Vn0;nipeg,terth0W;llingt1Oxford;aw;a1i0;en2Hlni2Z;lenc2Uncouv0Gr2G;lan bat0Dtrecht;a6bilisi,e5he4i3o2rondheim,u0;nVr0;in,ku;kyo,ronIulouC;anj23l13miso2Jra2A; haJssaloni0X;gucigalpa,hr2Ol av0L;i0llinn,mpe2Bngi07rtu;chu22n2MpT;a3e2h1kopje,t0ydney;ockholm,uttga12;angh1Fenzh1X;o0KvZ;int peters0Ul3n0ppo1F; 0ti1B;jo0salv2;se;v0z0Q;adU;eykjavik,i1o0;me,t25;ga,o de janei17;to;a8e6h5i4o2r0ueb1Qyongya1N;a0etor24;gue;rt0zn24; elizabe3o;ls1Grae24;iladelph1Znom pe07oenix;r0tah tik19;th;lerJr0tr10;is;dessa,s0ttawa;a1Hlo;a2ew 0is;delTtaip0york;ei;goya,nt0Upl0Uv1R;a5e4i3o1u0;mb0Lni0I;nt0scH;evideo,real;l1Mn01skolc;dellín,lbour0S;drid,l5n3r0;ib1se0;ille;or;chest0dalWi0Z;er;mo;a4i1o0vAy01;nd00s angel0F;ege,ma0nz,sbZverpo1;!ss0;ol; pla0Iusan0F;a5hark4i3laipeda,o1rak0uala lump2;ow;be,pavog0sice;ur;ev,ng8;iv;b3mpa0Kndy,ohsiu0Hra0un03;c0j;hi;ncheMstanb0̇zmir;ul;a5e3o0; chi mi1ms,u0;stI;nh;lsin0rakliG;ki;ifa,m0noi,va0A;bu0SiltD;alw4dan3en2hent,iza,othen1raz,ua0;dalaj0Gngzhou;bu0P;eUoa;sk;ay;es,rankfu0;rt;dmont4indhovU;a1ha01oha,u0;blRrb0Eshanbe;e0kar,masc0FugavpiJ;gu,je0;on;a7ebu,h2o0raioJuriti01;lo0nstanJpenhagNrk;gFmbo;enn3i1ristchur0;ch;ang m1c0ttagoL;ago;ai;i0lgary,pe town,rac4;ro;aHeBirminghWogoAr5u0;char3dap3enos air2r0sZ;g0sa;as;es;est;a2isba1usse0;ls;ne;silPtisla0;va;ta;i3lgrade,r0;g1l0n;in;en;ji0rut;ng;ku,n3r0sel;celo1ranquil0;la;na;g1ja lu0;ka;alo0kok;re;aBb9hmedabad,l7m4n2qa1sh0thens,uckland;dod,gabat;ba;k0twerp;ara;m5s0;terd0;am;exandr0maty;ia;idj0u dhabi;an;lbo1rh0;us;rg|Place¦aMbKcIdHeFfEgBhAi9jfk,kul,l7m5new eng4ord,p2s1the 0upJyyz;bronx,hamptons;fo,oho,under2yd;acifMek,h0;l,x;land;a0co,idDuc;libu,nhattK;a0gw,hr;s,x;ax,cn,ndianGst;arlem,kg,nd;ay village,re0;at 0enwich;britain,lak2;co,ra;urope,verglad0;es;en,fw,own1xb;dg,gk,hina0lt;town;cn,e0kk,rooklyn;l air,verly hills;frica,m5ntar1r1sia,tl0;!ant1;ct0;ic0; oce0;an;ericas,s|FemaleName¦0:G0;1:G4;2:FT;3:FF;4:FE;5:FU;6:ER;7:GH;8:F1;9:ET;A:GD;B:E7;C:GA;D:FQ;E:FN;F:EI;G:C8;aE4bD6cB9dAJe9Hf92g8Ih85i7Uj6Wk61l4Pm3An2Vo2Sp2Hqu2Fr1Ps0Rt05ursu9vVwPyMzH;aKeIoH;e,la,ra;lHna;da,ma;da,ra;as7GeIol1UvH;et6onBA;le0sen3;an8endBPhiB5iH;lJnH;if3BniHo0;e,f3A;a,helmi0lHma;a,ow;aNeKiH;cIviH;an9YenG4;kD1tor3;da,l8Wnus,rH;a,nHoniD4;a,iDE;leHnesEF;nDOrH;i1y;aTeQhOiNoKrHu9y4;acG6iHu0F;c3na,sH;h9Nta;nIrH;a,i;i9Kya;a5KffaCIna,s5;al3eHomasi0;a,l8Ho6Zres1;g7Vo6YrIssH;!a,ie;eFi,ri7;bOliNmLnJrIs5tHwa0;ia0um;a,yn;iHya;a,ka,s5;a4e4iHmCCra;!ka;a,t5;at5it5;a06carlet2Ze05hViTkye,oRtNuIyH;bFMlvi1;e,sIzH;an2Uet6ie,y;anHi7;!a,e,nH;aEe;aJeH;fHl3EphH;an2;cFBr73;f3nHphi1;d4ia,ja,ya;er4lv3mon1nHobh76;dy;aLeHirlBNo0y9;ba,e0i9lJrH;iHrBRyl;!d71;ia,lBX;ki4nJrIu0w0yH;la,na;i,leAon,ron;a,da,ia,nHon;a,on;l60re0;bNdMi8lLmJndIrHs5vannaE;aEi0;ra,y;aHi4;nt5ra;lBPome;e,ie;in1ri0;a03eYhWiUoIuH;by,thBM;bRcQlPnOsIwe0xH;an95ie,y;aIeHie,lC;ann7ll1marBHtB;!lHnn1;iHyn;e,nH;a,d7X;da,i,na;an8;hel55io;bin,erByn;a,cHkki,na,ta;helC2ki;ea,iannE0oH;da,n13;an0bJgi0i0nHta,y0;aHee;!e,ta;a,eH;cATkaE;chHe,i0mo0n5FquCGvDy0;aCFelHi8;!e,le;een2iH;a0nn;aNeMhKoJrH;iHudenAX;scil1Uyamva8;lly,rt3;ilome0oebe,ylH;is,lis;arl,ggy,nelope,r9t4;ige,m0Fn4Po9rvaBDtIulH;a,et6in1;ricHsy,tA9;a,e,ia;ctav3deIf86lHph86;a,ga,iv3;l3t6;aReQiKoHy9;eIrH;aEeDma;ll1mi;aLcJkHla,na,s5ta;iHki;!ta;hoB4k8ColH;a,eBJ;!mh;l7Una,risF;dJi5PnIo23taH;li1s5;cy,et6;eAiCQ;a01ckenz2eViLoIrignayani,uriBIyrH;a,na,tAV;i4ll9ZnH;a,iH;ca,ka,qB7;a,chPkaOlKmi,nJrHtzi;aHiam;!n8;a,dy,erva,h,n2;a,dJi9LlH;iHy;cent,e;red;!e9;ae9el3I;ag4LgLi,lIrH;edi62isFyl;an2iHliF;nHsAP;a,da;!an,han;b09c9Gd07e,g05i04l02n00rLtKuIv6TxGyHz2;a,bell,ra;de,rH;a,eD;h77il8t2;a,cTgPiKjor2l6Jn2s5tJyH;!aHbe5RjaAlou;m,n9V;a,ha,i0;!aJbAOeIja,lCna,sHt54;!a,ol,sa;!l07;!h,m,nH;!a,e,n1;arJeIie,oHr3Lueri6;!t;!ry;et3JiB;elHi62y;a,l1;dHon,ue9;akranBy;iHlo97;a,ka,n8;a,re,s2;daHg2;!l2Y;alCd2elHge,isBJon0;eiAin1yn;el,le;a0Je09iXoRuLyH;d3la,nH;!a,dIe9VnHsAT;!a,e9U;a,sAR;aB4cKelJiFlIna,pHz;e,iB;a,u;a,la;iHy;a2Ce,l27n8;is,l1IrItt2uH;el9is1;aJeIi7na,rH;aGi7;lei,n1tB;!in1;aRbQd3lMnJsIv3zH;!a,be4Let6z2;a,et6;a,dH;a,sHy;ay,ey,i,y;a,iaJlH;iHy;a8Je;!n4G;b7Verty;!n5T;aOda,e0iMla,nLoJslAUtHx2;iHt2;c3t3;la,nHra;a,ie,o4;a,or1;a,gh,laH;!ni;!h,nH;a,d4e,n4O;cOdon7Ui9kes5na,rNtLurJvIxHy9;mi;ern1in3;a,eHie,yn;l,n;as5is5oH;nya,ya;a,isF;ey,ie,y;a01eWhadija,iOoNrJyH;lHra;a,ee,ie;isHy5D;!tH;a,en,iHy;!e,n48;ri,urtn9C;aNerMl9BmJrHzzy;a,stH;en,in;!berlH;eHi,y;e,y;a,stD;!na,ra;el6QiKlJnIrH;a,i,ri;d4na;ey,i,l9Ss2y;ra,s5;c8Yi5YlPma9nyakumari,rNss5MtKviByH;!e,lH;a,eH;e,i7A;a5FeIhHi3PlCri0y;arGerGie,leDr9Hy;!lyn75;a,en,iHl4Vyn;!ma,n31sF;ei74i,l2;a05eWilUoNuH;anLdKliHstG;aIeHsF;!nAt0W;!n8Z;e,i2Ry;a,iB;!anMcelCd5Wel73han6JlKni,sIva0yH;a,ce;eHie;fi0lCphG;eHie;en,n1;!a,e,n36;!i10lH;!i0Z;anMle0nJrIsH;i5Rsi5R;i,ri;!a,el6Rif1RnH;a,et6iHy;!e,f1P;a,e74iInH;a,e73iH;e,n1;cMd1mi,nIqueliAsmin2Uvie4yAzH;min7;a7eIiH;ce,e,n1s;!lHsFt06;e,le;inIk2lCquelH;in1yn;da,ta;da,lQmOnNo0rMsIvaH;!na;aIiHob6W;do4;!belHdo4;!a,e,l2G;en1i0ma;a,di4es,gr5T;el8ogH;en1;a,eAia0o0se;aNeKilIoHyacin1N;ll2rten1H;a5HdHla5H;a,egard;ath0XiIlHnrietBrmiAst0X;en25ga;di;il78lLnKrHtt2yl78z6G;iHmo4Hri4I;etH;!te;aEnaE;ey,l2;aZeUiPlNold13rJwH;enHyne19;!dolC;acIetHisel8;a,chD;e,ieH;!la;adys,enHor3yn1Z;a,da,na;aKgi,lIna,ov74selH;a,e,le;da,liH;an;!n0;mZnJorgIrH;aldGi,m2Utru76;et6i5W;a,eHna;s1Ovieve;briel3Hil,le,rnet,yle;aSePio0loNrH;anIe8iH;da,e8;!cH;esIiHoi0H;n1s3X;!ca;!rH;a,en45;lIrnH;!an8;ec3ic3;rItiHy7;ma;ah,rah;d0GileDkBl01mVn4DrSsNtMuLvH;aJelIiH;e,ta;in0Byn;!ngelG;geni1la,ni3T;h55ta;meral8peranKtH;eIhHrel9;er;l2Rr;za;iHma,nestGyn;cHka,n;a,ka;eKilJmH;aHie,y;!liA;ee,i1y;lHrald;da,y;aUeSiNlMma,no4oKsJvH;a,iH;na,ra;a,ie;iHuiH;se;a,en,ie,y;a0c3da,nKsHzaI;aHe;!beH;th;!a,or;anor,nH;!a;in1na;en,iHna,wi0;e,th;aXeLiKoHul2W;lor54miniq41n32rHtt2;a,eDis,la,othHthy;ea,y;an0AnaEonAx2;anQbPde,eOiMja,lJmetr3nHsir4X;a,iH;ce,se;a,iIla,orHphiA;es,is;a,l5M;dHrdH;re;!d4Pna;!b2EoraEra;a,d4nH;!a,e;hl3i0mNnLphn1rIvi1YyH;le,na;a,by,cIia,lH;a,en1;ey,ie;a,et6iH;!ca,el1Cka;arHia;is;a0Se0Oh06i04lWoKrIynH;di,th3;istHy06;al,i0;lQnNrIurH;tn1F;aKdJiHnJriA;!nH;a,e,n1;el3;!l1T;n2sH;tanHuelo;ce,za;eHleD;en,t6;aJeoIotH;il4D;!pat4;ir7rJudH;et6iH;a,ne;a,e,iH;ce,sY;a4er4ndH;i,y;aQeNloe,rH;isIyH;stal;sy,tH;aIen,iHy;!an1e,n1;!l;lseIrH;!i7yl;a,y;nMrH;isKlImH;aiA;a,eHot6;n1t6;!sa;d4el1RtH;al,el1Q;cIlH;es6i3H;el3ilH;e,ia,y;iZlYmilXndWrOsMtHy9;aKeJhHri0;erGleDrCy;in1;ri0;li0ri0;a2IsH;a2Hie;a,iNlLmeJolIrH;ie,ol;!e,in1yn;lHn;!a,la;a,eHie,y;ne,y;na,sF;a0Ei0E;a,e,l1;isBl2;tlH;in,yn;arb0DeZianYlWoUrH;andSeQiJoIyH;an0nn;nwCok7;an2PdgLg0KtH;n29tH;!aInH;ey,i,y;ny;etH;!t7;an0e,nH;da,na;i7y;bbi7nH;iBn2;ancHossom,ythe;a,he;ca;aScky,lin8niBrOssNtJulaEvH;!erlH;ey,y;hIsy,tH;e,i11y7;!anH;ie,y;!ie;nHt5yl;adIiH;ce;et6iA;!triH;ce,z;a4ie,ra;aliy2Bb26d1Ng1Ji1Bl0Um0Pn03rYsPthe0uLvJyH;anHes5;a,na;a,eHr27;ry;drJgusIrH;el3o4;ti0;a,ey,i,y;hItrH;id;aLlHt1Q;eIi7yH;!n;e,iHy;gh;!nH;ti;iJleIpiB;ta;en,n1t6;an1AelH;le;aZdXeVgRiPja,nItoHya;inet6n3;!aKeIiHmJ;e,ka;!mHt6;ar2;!belIliFmU;sa;!le;ka,sHta;a,sa;elHie;a,iH;a,ca,n1qH;ue;!t6;te;je9rea;la;!bImHstas3;ar3;el;aJberIel3iHy;e,na;!ly;l3n8;da;aUba,eOiLlJma,ta,yH;a,c3sH;a,on,sa;iHys0K;e,s0J;a,cIna,sHza;a,ha,on,sa;e,ia;c3is5jaJna,ssaJxH;aHia;!nd4;nd4;ra;ia;i0nIyH;ah,na;a,is,naE;c5da,leDmMnslLsH;haElH;inHyX;g,n;!h;ey;ee;en;at5g2nH;es;ie;ha;aWdiTelMrH;eJiH;anMenH;a,e,ne;an0;na;aLeKiIyH;nn;a,n1;a,e;!ne;!iH;de;e,lCsH;on;yn;!lH;iAyn;ne;agaKbIiH;!gaJ;ey,i7y;!e;il;ah|Person¦a01bZcTdQeOfMgJhHinez,jFkEleDmAnettPo9p7r4s3t2uncle,v0womL;a0irgin maH;lentino rossi,n go3;heresa may,iger woods,yra banks;addam hussaQcarlett johanssRistZlobodan milosevic,omeone,tepGuC;ay romano,eese witherspoQo1ush limbau0;gh;d stewart,naldinho,sario;a0ipV;lmUris hiltM;prah winfrOra;an,essiaen,itt romnNo0ubarek;m0thR;!my;bron james,e;anye west,iefer sutherland,obe bryaN;aime,effersFk rowli0;ng;alle ber0ulk hog3;ry;astBentlem1irl,rand0uy;fa2mo2;an;a0ella;thF;ff0meril lagasse,zekiel;ie;a0enzel washingt4ick wolf,ude;d0lt3nte;!dy;ar2lint1ous0ruz;in;on;dinal wols1son0;! palm5;ey;arack obama,oy,ro0;!ck,th2;dolf hitl1shton kutch1u0;nt;er|WeekDay¦fri4mon4s2t1wed0;!nesd4;hurs2ues2;at0un1;!urd1;!d0;ay0;!s|Date¦autumn,daylight9eom,one d8s5t2w0yesterd8;eek0int5;d6end;mr1o0;d4morrow;!w;ome 1tandard3umm0;er;d0point;ay; time|Time¦a6breakfast 5dinner5e3lunch5m2n0oclock,some5to7;i7o0;on,w;id4or1;od,ve0;ning;time;fternoon,go,ll day,t 0;ni0;ght|Holiday¦0:1Q;1:1P;a1Fb1Bc12d0Ye0Of0Kg0Hh0Di09june07kwanzaa,l04m00nYoVpRrPsFt9v6w4xm03y2;om 2ule;hasho16kippur;hit2int0Xomens equalit8; 0Ss0T;alentines3e2ictor1E;r1Bteran1;! 0;-0ax 0h6isha bav,rinityMu2; b3rke2;y 0;ish2she2;vat;a0Xe prophets birth0;a6eptember14h4imchat tor0Ut 3u2;kk4mmer T;a8p7s6valentines day ;avu2mini atzeret;ot;int 2mhain;a4p3s2valentine1;tephen1;atrick1;ndrew1;amadan,ememberanc0Yos2;a park1h hashana;a3entecost,reside0Zur2;im,ple heart 0;lm2ssovE; s04;rthodox 2stara;christma1easter2goOhoJn0C;! m07;ational 2ew years09;freedom 0nurse1;a2emorial 0lHoOuharram;bMr2undy thurs0;ch0Hdi gr2tin luther k0B;as;a2itRughnassadh;bour 0g baom2ilat al-qadr;er; 2teenth;soliU;d aJmbolc,n2sra and miraj;augurGd2;ependen2igenous people1;c0Bt1;a3o2;ly satur0;lloween,nukkUrvey mil2;k 0;o3r2;ito de dolores,oundhoW;odW;a4east of 2;our lady of guadalupe,the immaculate concepti2;on;ther1;aster8id 3lectYmancip2piphany;atX;al-3u2;l-f3;ad3f2;itr;ha;! 2;m8s2;un0;ay of the dead,ecemb3i2;a de muertos,eciseis de septiembre,wali;er sol2;stice;anad8h4inco de mayo,o3yber m2;on0;lumbu1mmonwealth 0rpus christi;anuk4inese n3ristmas2;! N;ew year;ah;a 0ian tha2;nksgiving;astillCeltaine,lack4ox2;in2;g 0; fri0;dvent,ll 9pril fools,rmistic8s6u2;stral4tum2;nal2; equinox;ia 0;cens2h wednes0sumption of mary;ion 0;e 0;hallows 6s2;ai2oul1t1;nt1;s 0;day;eve|Month¦aBdec9feb7j2mar,nov9oct1sep0;!t8;!o8;an3u0;l1n0;!e;!y;!u1;!ru0;ary;!em0;ber;pr1ug0;!ust;!il|Duration¦centur4d2hour3m0seconds,week3year3;i0onth2;llisecond1nute1;ay0ecade0;!s;ies,y|FirstName¦aEblair,cCdevBj8k6lashawn,m3nelly,re2sh0;ay,e0iloh;a,lby;g1ne;ar1el,org0;an;ion,lo;as8e0;ls7nyatta,rry;am0ess1;ie,m0;ie;an,on;as0heyenne;ey,sidy;lexis,ndra,ubr0;ey|LastName¦0:35;1:3C;2:3A;3:2Z;4:2F;a3Bb31c2Od2Ee2Bf25g1Zh1Oi1Jj1Dk16l0Ym0Mn0Io0Fp04rXsLtGvEwBxAy7zh5;a5ou,u;ng,o;a5eun2Uoshi1Jun;ma5ng;da,guc1Zmo27sh21zaQ;iao,u;a6eb0il5o3right,u;li3Bs2;gn0lk0ng,tanabe;a5ivaldi;ssilj37zqu1;a8h7i2Go6r5sui,urn0;an,ynisI;lst0Orr1Uth;at1Uomps2;kah0Unaka,ylor;aDchCeBhimizu,iAmi9o8t6u5zabo;ar1lliv2AzuD;a5ein0;l23rm0;sa,u3;rn4th;lva,mmo24ngh;mjon4rrano;midt,neid0ulz;ito,n6sa5to;ki;ch1dKtos,z;amAeag1Zi8o6u5;bio,iz,sC;b5dri1MgHj0Sme24osevelt,sZux;erts,ins2;c5ve0E;ci,hards2;ir1os;aDe9h7ic5ow20;as5hl0;so;a5illips;m,n1T;ders20et7r6t5;e0Nr4;ez,ry;ers;h21rk0t5vl4;el,te0J;baAg0Alivei00r5;t5w1O;ega,iz;a5eils2guy1Rix2owak,ym1E;gy,ka5var1K;ji5muV;ma;aDeBiAo7u5;ll0n5rr0Bssolini,ñ5;oz;lina,oJr5zart;al0Me5r0U;au,no;hhail4ll0;rci0s5y0;si;eVmmad4r5tsu07;in5tin1;!o;aBe7i5op1uo;!n5u;coln,dholm;fe6n0Qr5w0J;oy;bv5v5;re;mmy,rs14u;aAennedy,imu9le0Lo7u6wo5;k,n;mar,znets4;bay5vacs;asY;ra;hn,rl8to,ur,zl4;a9en8ha3imen1o5u3;h5nYu3;an5ns2;ss2;ki0Es0S;cks2nsse0D;glesi8ke7noue,shik6to,vano5;u,v;awa;da;as;aBe8it7o6u5;!a3b0ghNynh;a3ffmann,rvat;chcock,l0;mingw6nde5rM;rs2;ay;ns0ErrPs6y5;asCes;an4hi5;moI;a8il,o7r6u5;o,tierr1;ayli3ub0;m1nzal1;nd5o,rcia;hi;er9is8lor7o6uj5;ita;st0urni0;es;ch0;nand1;d6insteGsposi5vaK;to;is2wards;aBeAi8omin7u5;bo5rand;is;gu1;az,mitr4;ov;lgado,vi;nkula,rw6vi5;es,s;in;aEhAlark9o5;hKl5op0rbyn,x;em6li5;ns;an;!e;an7e6iu,o5ristensFu3we;i,ng,u3w,y;!n,on5u3;!g;mpb6rt0st5;ro;ell;aAe7ha3lanco,oyko,r5yrne;ooks,yant;ng;ck6ethov5nnett;en;er,ham;ch,h7iley,rn5;es,i0;er;k,ng;dCl8nd5;ers5r9;en,on,s2;on;eks6iy7var1;ez;ej5;ev;ams|MaleName¦0:CE;1:BK;2:C2;3:BS;4:B4;5:BZ;6:AT;7:9V;8:BC;9:AW;A:AO;B:8W;aB5bA9c98d88e7Hf6Zg6Hh5Wi5Ij4Lk4Bl3Rm2Pn2Eo28p22qu20r1As0Qt07u06v01wOxavi3yHzC;aCor0;cCh8Jne;hDkC;!a5Z;ar51e5Y;ass2i,oDuC;sEu25;nFsEusC;oCsD;uf;ef;at0g;aKeIiDoCyaAQ;lfgang,odrow;lCn1O;bEey,frBJlC;aA6iC;am,e,s;e8Aur;i,nde7sC;!l6t1;de,lDrr5yC;l1ne;lCt3;a94y;aFern1iC;cDha0nceCrg9Cva0;!nt;ente,t5B;lentin49n8Zughn;lyss4Msm0;aTeOhLiJoFrDyC;!l3ro8s1;av9ReCist0oy,um0;nt9Jv55y;bEd7YmCny;!as,mCoharu;aAYie,y;iBy;mCt9;!my,othy;adDeoCia7EomB;!do7O;!de9;dFrC;en8JrC;an8IeCy;ll,n8H;!dy;dgh,ic9Unn3req,ts46;aScotQeOhKiIoGpenc3tCur1Pylve8Jzym1;anEeCua7D;f0phAGvCwa7C;e59ie;!islaw,l6;lom1nA4uC;leyma8ta;dClBm1;!n6;aEeC;lCrm0;d1t1;h6Une,qu0Vun,wn,y8;aCbasti0k1Yl42rg41th,ymo9J;m9n;!tC;!ie,y;lDmCnti22q4Kul;!mAu4;ik,vato6X;aXeThe94iPoGuDyC;an,ou;b6NdDf9pe6SssC;!elAK;ol2Vy;an,bJcIdHel,geGh0landA4mFnEry,sDyC;!ce;coe,s;!a96nA;an,eo;l3Kr;e4Sg3n6oA5ri6A;co,ky;bAe9V;cCl6;ar5Qc5PhDkCo;!ey,ie,y;a87ie;gDid,ub5x,yCza;ansh,nT;g8XiC;na8Ts;ch60fa4lEmDndCpha4sh6Wul,ymo72;alA0ol2Cy;i9Jon;f,ph;ent2inC;cy,t1;aGeEhilDier64ol,reC;st1;!ip,lip;d9Crcy,tC;ar,e2W;b3Udra6Ht46ul;ctav2Wliv3m97rGsDtCum8Vw5;is,to;aDc8TvC;al54;ma;i,l4BvK;athKeIiEoC;aCel,l0ma0r2Y;h,m;cDg4i3KkC;h6Wola;holBkColB;!olB;al,d,il,ls1vC;il52;anCy;!a4i4;aXeUiLoGuDyC;l22r1;hamDr61staC;fa,p4I;ed,mG;dibo,e,hamEis1YntDsCussa;es,he;e,y;ad,ed,mC;ad,ed;cHgu4kFlEnDtchC;!e7;a7Aik;o04t1;e,olC;aj;ah,hCk6;a4eC;al,l;hDlv2rC;le,ri7v2;di,met;ck,hOlMmPnu4rIs1tEuricDxC;!imilian87we7;e,io;eo,hDiBtC;!eo,hew,ia;eCis;us,w;cEio,k81lDqu6Isha7tCv2;i2Jy;in,on;!el,oLus;achCcolm,ik;ai,y;amCdi,moud;adC;ou;aSeOiNlo2ToJuDyC;le,nd1;cFiEkCth3;aCe;!s;gi,s;as,iaC;no;g0nn6SrenEuCwe7;!iC;e,s;!zo;am,on4;a7Cevi,la4UnEoCst3vi;!nC;!a62el;!ny;mDnCr16ur4Vwr4V;ce,d1;ar,o4P;aJeEhaled,iCrist4Xu4Ay3D;er0p,rC;by,k,ollos;en0iFnCrmit,v2;!dDnCt5E;e10y;a7ri4P;r,th;na69rCthem;im,l;aZeRiPoEuC;an,liCst2;an,o,us;aqu2eKhnJnHrFsC;eDhCi7Due;!ua;!ph;dCge;an,i,on;!aCny;h,s,th4Z;!ath4Yie,nA;!l,sCy;ph;an,e,mC;!mA;d,ffHrEsC;sCus;!e;a5KemDmai8oCry;me,ni0Q;i6Wy;!e07rC;ey,y;cId5kHmGrEsDvi3yC;!d5s1;on,p3;ed,od,rCv4O;e51od;al,es,is1;e,ob,ub;k,ob,quC;es;aObrahNchika,gLkeKlija,nuJrHsEtCv0;ai,sC;uki;aCha0i6Hma4sac;ac,iaC;h,s;a,vinCw2;!g;k,nngu53;!r;nacCor;io;im;in,n;aLeGina4WoEuCyd57;be27gCmber4EsE;h,o;m3ra35sCwa3Z;se2;aFctEitEnDrC;be22m0;ry;or;th;bLlKmza,nJo,rEsDyC;a44d5;an,s0;lFo4FrEuCv6;hi41ki,tC;a,o;is1y;an,ey;k,s;!im;ib;aReNiMlenLoJrFuC;illerDsC;!tavo;mo;aEegCov3;!g,orC;io,y;dy,h58nt;nzaCrd1;lo;!n;lbe4Qno,ovan4S;ne,oErC;aCry;ld,rd4O;ffr6rge;bri4l5rCv2;la20r3Fth,y;aSeOiMlKorr0JrC;anEedCitz;!dAeCri25;ri24;cEkC;!ie,lC;in,yn;esKisC;!co,zek;etch3oC;yd;d4lConn;ip;deriEliDng,rnC;an02;pe,x;co;bi0di;ar00dVfrUit0lOmHnGo2rDsteb0th0uge8vCym5zra;an,ere2W;gi,iDnCrol,v2w2;est3Zie;c08k;och,rique,zo;aHerGiDmC;aGe2Q;lDrC;!h0;!io;s1y;nu4;be0Ad1iFliEmDt1viCwood;n,s;er,o;ot1Us;!as,j44sC;ha;a2en;!dAg32mFuDwC;a26in;arC;do;o0Tu0T;l,nC;est;aZePiMoFrEuDwCyl0;ay8ight;a8dl6nc0st2;ag0ew;minGnEri0ugDyC;le;!lB;!a29nCov0;e7ie,y;go,icC;!k;armuDeCll1on,rk;go;id;anJj0lbeImetri9nGon,rFsEvDwCxt3;ay8ey;en,in;hawn,mo09;ek,ri0G;is,nCv3;is,y;rt;!dC;re;lLmJnIrEvC;e,iC;!d;en,iEne7rCyl;eCin,yl;l2Wn;n,o,us;!e,i4ny;iCon;an,en,on;e,lB;as;a07e05hXiar0lMoHrFuDyrC;il,us;rtC;!is;aCistobal;ig;dy,lFnDrC;ey,neli9y;or,rC;ad;by,e,in,l2t1;aHeEiCyJ;fCnt;fo0Dt1;meDt9velaC;nd;nt;rEuDyC;!t1;de;enC;ce;aGeFrisDuC;ck;!tC;i0oph3;st3;d,rlCs;eCie;s,y;cCdric,s11;il;lFmer1rC;ey,lDro7y;ll;!os,t1;eb,v2;ar03eVilUlaToQrDuCyr1;ddy,rtJ;aKeFiEuDyC;an,ce,on;ce,no;an,ce;nDtC;!t;dDtC;!on;an,on;dDndC;en,on;!foCl6y;rd;bDrCyd;is;!by;i8ke;al,lA;nGrCshoi;at,nDtC;!r11;aCie;rd0M;!edict,iDjam2nA;ie,y;to;n6rCt;eCy;tt;ey;ar0Yb0Od0Kgust2hm0Hid5ja0FlZmXnPputsiOrFsaEuCya0ziz;gust9st2;us;hi;aJchIi4jun,maGnEon,tCy0;hCu07;ur;av,oC;ld;an,nd05;el;ie;ta;aq;dHgel00tC;hoFoC;i8nC;!iXy;ne;ny;reCy;!as,s,w;ir,mCos;ar;an,bePd5eJfGi,lFonEphonIt1vC;aNin;on;so,zo;an,en;onDrC;edK;so;c,jaFksandEssaFxC;!and3;er;ar,er;ndC;ro;rtC;!o;ni;en;ad,eC;d,t;in;aDoCri0vik;lfo;mCn;!a;dGeFraDuC;!bakr,lfazl;hCm;am;!l;allFel,oulaye,ulC;!lDrahm0;an;ah,o;ah;av,on|Verb¦awak9born,cannot,fr8g7h5k3le2m1s0wors9;e8h3;ake sure,sg;ngth6ss6;eep tabs,n0;own;as0e2;!t2;iv1onna;ight0;en|PhrasalVerb¦0:71;1:6P;2:7D;3:73;4:6I;5:7G;6:75;7:6O;8:6B;9:6C;A:5H;B:70;C:6Z;a7Gb62c5Cd59e57f45g3Nh37iron0j33k2Yl2Km2Bn29o27p1Pr1Es09tQuOvacuum 1wGyammerCzD;eroAip EonD;e0k0;by,up;aJeGhFiEorDrit52;d 1k2Q;mp0n49pe0r8s8;eel Bip 7K;aEiD;gh 06rd0;n Br 3C;it 5Jk8lk6rm 0Qsh 73t66v4O;rgeCsD;e 9herA;aRePhNiJoHrFuDype 0N;ckArn D;d2in,o3Fup;ade YiDot0y 32;ckle67p 79;ne66p Ds4C;d2o6Kup;ck FdEe Dgh5Sme0p o0Dre0;aw3ba4d2in,up;e5Jy 1;by,o6U;ink Drow 5U;ba4ov7up;aDe 4Hll4N;m 1r W;ckCke Elk D;ov7u4N;aDba4d2in,o30up;ba4ft7p4Sw3;a0Gc0Fe09h05i02lYmXnWoVpSquare RtJuHwD;earFiD;ngEtch D;aw3ba4o6O; by;ck Dit 1m 1ss0;in,up;aIe0RiHoFrD;aigh1LiD;ke 5Xn2X;p Drm1O;by,in,o6A;n2Yr 1tc3H;c2Xmp0nd Dr6Gve6y 1;ba4d2up;d2o66up;ar2Uell0ill4TlErDurC;ingCuc8;a32it 3T;be4Brt0;ap 4Dow B;ash 4Yoke0;eep EiDow 9;c3Mp 1;in,oD;ff,v7;gn Eng2Yt Dz8;d2o5up;in,o5up;aFoDu4E;ot Dut0w 5W;aw3ba4f36o5Q;c2EdeAk4Rve6;e Hll0nd GtD; Dtl42;d2in,o5upD;!on;aw3ba4d2in,o1Xup;o5to;al4Kout0rap4K;il6v8;at0eKiJoGuD;b 4Dle0n Dstl8;aDba4d2in52o3Ft2Zu3D;c1Ww3;ot EuD;g2Jnd6;a1Wf2Qo5;ng 4Np6;aDel6inAnt0;c4Xd D;o2Su0C;aQePiOlMoKrHsyc29uD;ll Ft D;aDba4d2in,o1Gt33up;p38w3;ap37d2in,o5t31up;attleCess EiGoD;p 1;ah1Gon;iDp 52re3Lur44wer 52;nt0;ay3YuD;gAmp 9;ck 52g0leCn 9p3V;el 46ncilA;c3Oir 2Hn0ss FtEy D;ba4o4Q; d2c1X;aw3ba4o11;pDw3J;e3It B;arrow3Serd0oD;d6te3R;aJeHiGoEuD;ddl8ll36;c16p 1uth6ve D;al3Ad2in,o5up;ss0x 1;asur8lt 9ss D;a19up;ke Dn 9r2Zs1Kx0;do,o3Xup;aOeMiHoDuck0;a16c36g 0AoDse0;k Dse34;aft7ba4d2forw2Ain3Vov7uD;nd7p;e GghtFnEsDv1T;ten 4D;e 1k 1; 1e2Y;ar43d2;av1Ht 2YvelD; o3L;p 1sh DtchCugh6y1U;in3Lo5;eEick6nock D;d2o3H;eDyA;l2Hp D;aw3ba4d2fSin,o05to,up;aFoEuD;ic8mpA;ke2St2W;c31zz 1;aPeKiHoEuD;nker2Ts0U;lDneArse2O;d De 1;ba4d2oZup;de Et D;ba4on,up;aw3o5;aDlp0;d Fr Dt 1;fDof;rom;in,oO;cZm 1nDve it;d Dg 27kerF;d2in,o5;aReLive Jloss1VoFrEunD; f0M;in39ow 23; Dof 0U;aEb17it,oDr35t0Ou12;ff,n,v7;bo5ft7hJw3;aw3ba4d2in,oDup,w3;ff,n,ut;a17ek0t D;aEb11d2oDr2Zup;ff,n,ut,v7;cEhDl1Pr2Xt,w3;ead;ross;d aEnD;g 1;bo5;a08e01iRlNoJrFuD;cDel 1;k 1;eEighten DownCy 1;aw3o2L;eDshe1G; 1z8;lFol D;aDwi19;bo5r2I;d 9;aEeDip0;sh0;g 9ke0mDrD;e 2K;gLlJnHrFsEzzD;le0;h 2H;e Dm 1;aw3ba4up;d0isD;h 1;e Dl 11;aw3fI;ht ba4ure0;eInEsD;s 1;cFd D;fDo1X;or;e B;dQl 1;cHll Drm0t0O;apYbFd2in,oEtD;hrough;ff,ut,v7;a4ehi1S;e E;at0dge0nd Dy8;o1Mup;o09rD;ess 9op D;aw3bNin,o15;aShPlean 9oDross But 0T;me FoEuntD; o1M;k 1l6;aJbIforGin,oFtEuD;nd7;ogeth7;ut,v7;th,wD;ard;a4y;pDr19w3;art;eDipA;ck BeD;r 1;lJncel0rGsFtch EveA; in;o16up;h Bt6;ry EvD;e V;aw3o12;l Dm02;aDba4d2o10up;r0Vw3;a0He08l01oSrHuD;bbleFcklTilZlEndlTrn 05tDy 10zz6;t B;k 9; ov7;anMeaKiDush6;ghHng D;aEba4d2forDin,o5up;th;bo5lDr0Lw3;ong;teD;n 1;k D;d2in,o5up;ch0;arKgJil 9n8oGssFttlEunce Dx B;aw3ba4;e 9; ar0B;k Bt 1;e 1;d2up; d2;d 1;aIeed0oDurt0;cFw D;aw3ba4d2o5up;ck;k D;in,oK;ck0nk0st6; oJaGef 1nd D;d2ov7up;er;up;r0t D;d2in,oDup;ff,ut;ff,nD;to;ck Jil0nFrgEsD;h B;ainCe B;g BkC; on;in,o5; o5;aw3d2o5up;ay;cMdIsk Fuction6; oD;ff;arDo5;ouD;nd;d D;d2oDup;ff,n;own;t D;o5up;ut|Modal¦c5lets,m4ought3sh1w0;ill,o5;a0o4;ll,nt;! to;ay,ight,ust;an,o0;uld|Adjective¦0:74;1:7J;2:7P;3:7I;4:7B;5:5B;6:4R;7:49;8:48;9:7G;A:60;B:72;C:6Z;D:6Y;a6Hb63c5Pd55e4Rf48g3Zh3Oi33j31k30l2Pm2En25o1Pp19quack,r0Zs0Ft08uPvMwEyear5;arp0eIholeHiGoE;man5oEu6A;d6Czy;despr73s5E;!sa7;eFlEste24;co1Gl o4J;!k5;aFiEola4A;b7Rce versa,ol53;ca2gabo61nilla;ltVnIpFrb58su4tterE;!moD; f32b1MpFsEti1F;ca7et,ide dLtairs;er,i3L;aObeco6Pconvin25deLeKfair,ivers4knJprecedXrHsFwE;iel1Yritt5X;i1TuE;pervis0specti3;eEu5;cognKgul6Fl6F;own;ndi3v5Rxpect0;cid0rE;!grou5MsE;iz0tood;b7ppeaKssu6EuthorE;iz0;i22ra;aIeGhough4NoFrE;i1oubl0;geth6p,rpC;en5OlEm4Yrr2Sst0;li3;boo,lEn;ent0;aWcVeThSiQmug,nobbi3DoOpNqueami3DtIuEymb62;bGi gener53pErprisi3;erEre0J;! dup6b,i27;du0seq4S;anda6SeHi0NrEy37;aightEip0; fEfE;or59;adfaDreotyp0;a4Xec2Eir1HlendCot on; call0le,mb6phist1VrEu0Vvi40;dCry;gnifica2nE;ce4Tg7;am2Oe6ocki3ut;cEda1em5lfi2Xni1Upa67re8;o1Er3U;at56ient26reec56;cr0me,ns serif;aLeHiFoE;buDtt4SuRy4;ghtEv4;!-27fA;ar,bel,condi1du61fres50lGpublic3UsEta2C;is46oE;lu1na2;e1Cuc44;bCciE;al,st;aOeMicayu8lacCopuliDrFuE;bl58mp0;eIiFoE;!b08fuBmi30p6;mFor,sEva1;ti8;a4Ue;ciBmE;a0Gi5I;ac20rEti1;fe9ma2Tplexi3v33;rEst;allelGtE;-tiEi4;me;!ed;bPffNkMld fashion0nLpKrg1Gth6utJvE;al,erE;!aGniFt,wE;eiErouE;ght;ll;do0Uer,g2Lsi45;en,posi1; boa5Fg2Jli8;!ay; gua5DbEli8;eat;eGsE;cEer0Gole1;e8u3J;d2Sse;ak0eLiKoEua4O;nIrFtE;ab7;thE;!eE;rn;chala2descri4Zstop;ght5;arby,cessa3Wighbor5xt;aMeKiHoEultip7;bi7derFlEnth5ot,st;dy;a1n;nEx0;iaEor;tu32;di4EnaEre;ci3;cEgenta,in,j02keshift,le,mmoth,ny,sculi8;ab2Yho;aNeIiFoEu13;uti12vi3;mFteraE;l,te;it0;ftHgEth4;al,eFitiE;ma1;nda3C;!-0B;nguCst,tt6;ap1Sind5no09;agg0uE;niNstifi0veni7;de4gno4Blleg4mRnGpso 1VrE;a1releE;va2; MaLbr0corKdIfluenSiSnHsGtE;a9enBoxE;ic36;a8i2R;a1er,oce2;iFoE;or;re9;deq3Jppr2Y;fEsitu,vitro;ro2;mIpE;arGerfe9oErop6;li1rtE;a2ed;ti4;eEi0Q;d2QnB;aJelIiGoEumdr3B;neDok0rrEs07ur5;if2S;ghfalut1OspE;an2Q;liZpfA;lHnGrE;d05roE;wi3;dy,gi3;f,low0;ainfAener2Jiga22lLoKraHuE;aFilEng ho;ty;rd0;cFtE;efAis;efA;ne,od;ea2Cob4;aTeNinMlLoGrE;a1SeEoz1J;e2Cq11tfA;oGrE; keeps,eEm6tuna1;g03ign;liE;sh;ag2Yue2;al,i1;dImFrE;ti7;a7ini8;ne;le; up;bl0i2lBr Eux,vori1;oEreac1E;ff;aNfficie2lMmiLnJre9there4veIxE;a9cess,peGtraFuE;be2Ll0H;!va1D;ct0rt;n,ryday; Ecouragi3ti0P;rou1sui1;ne2;abo22dPe17i1;g6sE;t,ygE;oi3;er;aUeMiGoErea14ue;mina2ne,ubE;le,tfA;dact1Afficu1NsFvE;erB;creGeas0gruntl0honeDordFtE;a2ress0;er5;et; KadpJfIgene1OliGrang0spe1OtFvoE;ut;ail0ermin0;be1Lca1ghE;tfA;ia2;an;facto;i5magEngeroYs0H;ed,i3;ly;ertaQhief,ivil,oGrE;aEowd0u0G;mp0v01z0;loMmKnFoi3rrEve0O;e9u1H;cre1grHsGtE;emEra0E;po0C;ta2;ue2;mer07pleE;te,x;ni4ss4;in;aOeKizarJlIoFrE;and new,isk,okO;gFna fiVttom,urgeoE;is;us;ank,iH;re;autifAhiFlov0nEst,yoF;eUt;nd;ul;ckFnkru0WrrE;en;!wards; priori,b0Mc0Jd09fraCg04h03lYma05ntiquXpTrNsLttracti06utheKvHwE;aFkE;wa0T;ke,re;ant garFerE;age;de;ntU;leep,tonisE;hi3;ab,bitHroGtiE;fiE;ci4;ga2;raE;ry;pEt;are2etiOrE;oprE;ia1;at0;arHcohFeEiLl,oof;rt;olE;ic;mi3;ead;ainDgressiFoniE;zi3;ve;st;id; LeJuIvE;aFerB;se;nc0;ed;lt;pt,qE;ua1;hoc,infinitE;um;cuFtu4u1;al;ra1;erOlNoLruKsFuE;nda2;e2oFtra9;ct;lu1rbi3;ng;te;pt;aEve;rd;aze,e;ra2;nt|Comparable¦0:41;1:4I;2:45;3:4B;4:3X;5:2Y;a4Ob44c3Od3De35f2Rg2Fh24i1Vj1Uk1Rl1Im1Cn16o14p0Tqu0Rr0IsRtKuIvFw7y6za12;ell27ou3;aBe9hi1Yi7r6;o3y;ck0Mde,l6n1ry,se;d,y;a6i4Mt;k,ry;n1Tr6sI;m,y;a7e6ulgar;nge4rda2xi3;gue,in,st;g0n6pco3Mse4;like0ti1;aAen9hi8i7ough,r6;anqu2Qen1ue;dy,g3Ume0ny,r09;ck,n,rs2R;d42se;ll,me,rt,s6wd47;te4;aVcarUeThRiQkin0GlMmKoHpGqua1HtAu7w6;eet,ift;b7dd15per0Hr6;e,re2J;sta2Ht5;aAe9iff,r7u6;pXr1;a6ict,o3;ig3Hn0W;a1ep,rn;le,rk;e24i3Hright0;ci2Aft,l7o6re,ur;n,thi3;emn,id;a6el0ooth;ll,rt;e8i6ow,y;ck,g37m6;!y;ek,nd3F;ck,l0mp5;a6iUort,rill,y;dy,ll0Zrp;cu0Tve0Txy;ce,ed,y;d,fe,int0l1Xv16;aBe9i8o6ude;mantic,o1Ksy,u6;gh,nd;ch,pe,tzy;a6d,mo0J;dy,l;gg7ndom,p6re,w;id;ed;ai2i6;ck,et;aFhoEi1SlCoBr8u6;ny,r6;e,p5;egna2ic7o6;fou00ud;ey,k0;li06or,te1D;a6easa2;in,nt;ny;in4le;dd,f6i0ld,ranR;fi11;aAe8i7o6;b5isy,rm16sy;ce,mb5;a6w;r,t;ive,rr02;aAe8ild,o7u6;nda1Ate;ist,o1;a6ek,llY;n,s0ty;d,tuR;aCeBi9o6ucky;f0Vn7o1Eu6ve0w18y0U;d,sy;e0g;g1Uke0tt5v6;e0i3;an,wd;me,r6te;ge;e7i6;nd;en;ol0ui1P;cy,ll,n6;sBt6;e6ima8;llege2r6;es7media6;te;ti3;ecu6ta2;re;aEeBiAo8u6;ge,m6ng1R;b5id;ll6me0t;ow;gh,l0;a6f04sita2;dy,v6;en0y;nd1Hppy,r6te4;d,sh;aGenFhDiClBoofy,r6;a9e8is0o6ue1E;o6ss;vy;at,en,y;nd,y;ad,ib,ooI;a2d1;a6o6;st0;t5uiY;u1y;aIeeb5iDlat,oAr8u6;ll,n6r14;!ny;aHe6iend0;e,sh;a7r6ul;get4mG;my;erce8n6rm,t;an6e;ciC;! ;le;ir,ke,n0Fr,st,t,ulA;aAerie,mp9sse7v6xtre0Q;il;nti6;al;ty;r7s6;tern,y;ly,th0;aFeCi9r7u6;ll,mb;u6y;nk;r7vi6;ne;e,ty;a6ep,nD;d6f,r;!ly;mp,pp03rk;aHhDlAo8r7u6;dd0r0te;isp,uel;ar6ld,mmon,ol,st0ward0zy;se;e6ou1;a6vW;n,r;ar8e6il0;ap,e6;sy;mi3;gey,lm8r6;e4i3;ful;!i3;aNiLlIoEr8u6;r0sy;ly;aAi7o6;ad,wn;ef,g7llia2;nt;ht;sh,ve;ld,r7un6;cy;ed,i3;ng;a7o6ue;nd,o1;ck,nd;g,tt6;er;d,ld,w1;dy;bsu9ng8we6;so6;me;ry;rd|Adverb¦a07by 05d01eYfShQinPjustOkinda,mMnJoEpCquite,r9s5t2up1very,w0Bye0;p,s; to,wards5;h1o0wiO;o,t6ward;en,us;everal,o0uch;!me1rt0; of;hXtimes,w07;a1e0;alS;ndomRthN;ar excellDer0oint blank; Mhaps;f3n0;ce0ly;! 0;ag00moU; courHten;ewJo0; longEt 0;onHwithstanding;aybe,eanwhiAore0;!ovB;! aboS;deed,steT;en0;ce;or2u0;l9rther0;!moH; 0ev3;examp0good,suF;le;n mas1v0;er;se;e0irect1; 1finite0;ly;ju7trop;far,n0;ow; CbroBd nauseam,gAl5ny2part,side,t 0w3;be5l0mo5wor5;arge,ea4;mo1w0;ay;re;l 1mo0one,ready,so,ways;st;b1t0;hat;ut;ain;ad;lot,posteriori|Expression¦a02b01dXeVfuck,gShLlImHnGoDpBshAu7voi04w3y0;a1eLu0;ck,p;!a,hoo,y;h1ow,t0;af,f;e0oa;e,w;gh,h0;! 0h,m;huh,oh;eesh,hh,it;ff,hew,l0sst;ease,z;h1o0w,y;h,o,ps;!h;ah,ope;eh,mm;m1ol0;!s;ao,fao;a4e2i,mm,oly1urr0;ah;! mo6;e,ll0y;!o;ha0i;!ha;ah,ee,o0rr;l0odbye;ly;e0h,t cetera,ww;k,p;\'oh,a0uh;m0ng;mit,n0;!it;ah,oo,ye; 1h0rgh;!em;la|Preposition¦\'o,-,aKbHcGdFexcept,fEinDmidPnotwithstandiQoBpRqua,sAt6u3vi2w0;/o,hereMith0;!in,oQ;a,s-a-vis;n1p0;!on;like,til;h0ill,owards;an,r0;ough0u;!oI;ans,ince,o that;\',f0n1ut;!f;!to;or,rom;espite,own,u3;hez,irca;ar1e0oAy;low,sides,tween;ri6;\',bo7cross,ft6lo5m3propos,round,s1t0;!op;! long 0;as;id0ong0;!st;ng;er;ut|Conjunction¦aEbAcuz,how8in caDno7o6p4supposing,t1vers5wh0yet;eth8ile;h0o;eref9o0;!uC;l0rovided that;us;r,therwi6; matt1r;!ev0;er;e0ut;cau1f0;ore;se;lthou1nd,s 0;far as,if;gh|Determiner¦aAboth,d8e5few,l3mu7neiCown,plenty,some,th2various,wh0;at0ich0;evB;at,e3is,ose;a,e0;!ast,s;a1i6l0nough,very;!se;ch;e0u;!s;!n0;!o0y;th0;er","conjugations":"t:ake,ook|:can,could,can,_|free:_,,,ing|puk:e,,,ing|ar:ise,ose,,,isen|babys:it,at|:be,was,is,am,been|:is,was,is,being|beat:_,,,ing,en|beg:in,an,,inning,un|ban:_,ned,,ning|bet:_,,,,_|bit:e,_,,ing,ten|ble:ed,d,,,d|bre:ed,d|br:ing,ought,,,ought|broadcast:_,_|buil:d,t,,,t|b:uy,ought,,,ought|cho:ose,se,,osing,sen|cost:_,_|deal:_,t,,,t|d:ie,ied,,ying|d:ig,ug,,igging,ug|dr:aw,ew,,,awn|dr:ink,ank,,,unk|dr:ive,ove,,iving,iven|:eat,ate,,eating,eaten|f:all,ell,,,allen|fe:ed,d,,,d|fe:el,lt|f:ight,ought,,,ought|f:ind,ound|fl:y,ew,,,own|bl:ow,ew,,,own|forb:id,ade|edit:_,,,ing|forg:et,ot,,eting,otten|forg:ive,ave,,iving,iven|fr:eeze,oze,,eezing,ozen|g:et,ot|g:ive,ave,,iving,iven|:go,went,goes,,gone|h:ang,ung,,,ung|ha:ve,d,s,ving,d|hear:_,d,,,d|hid:e,_,,,den|h:old,eld,,,eld|hurt:_,_,,,_|la:y,id,,,id|le:ad,d,,,d|le:ave,ft,,,ft|l:ie,ay,,ying|li:ght,t,,,t|los:e,t,,ing|ma:ke,de,,,de|mean:_,t,,,t|me:et,t,,eting,t|pa:y,id,,,id|read:_,_,,,_|r:ing,ang,,,ung|r:ise,ose,,ising,isen|r:un,an,,unning,un|sa:y,id,ys,,id|s:ee,aw,,eeing,een|s:ell,old,,,old|sh:ine,one,,,one|sho:ot,t,,,t|show:_,ed|s:ing,ang,,,ung|s:ink,ank|s:it,at|slid:e,_,,,_|sp:eak,oke,,,oken|sp:in,un,,inning,un|st:and,ood|st:eal,ole|st:ick,uck|st:ing,ung|:stream,,,,|str:ike,uck,,iking|sw:ear,ore|sw:im,am,,imming|sw:ing,ung|t:each,aught,eaches|t:ear,ore|t:ell,old|th:ink,ought|underst:and,ood|w:ake,oke|w:ear,ore|w:in,on,,inning|withdr:aw,ew|wr:ite,ote,,iting,itten|t:ie,ied,,ying|ski:_,ied|:boil,,,,|miss:_,,_|:act,,,,|compet:e,ed,,ing|:being,were,are,are|impl:y,ied,ies|ic:e,ed,,ing|develop:_,ed,,ing|wait:_,ed,,ing|aim:_,ed,,ing|spil:l,t,,,led|drop:_,ped,,ping|log:_,ged,,ging|rub:_,bed,,bing|smash:_,,es|egg:_,ed|suit:_,ed,,ing|age:_,d,s,ing|shed:_,_,s,ding|br:eak,oke|ca:tch,ught|d:o,id,oes|b:ind,ound|spread:_,_|become:_,,,,_|ben:d,,,,t|br:ake,,,,oken|burn:_,,,,ed|burst:_,,,,_|cl:ing,,,,ung|c:ome,ame,,,ome|cre:ep,,,,pt|cut:_,,,,_|dive:_,,,,d|dream:_,,,,t|fle:e,,,eing,d|fl:ing,,,,ung|got:_,,,,ten|grow:_,,,,n|hit:_,,,,_|ke:ep,,,,pt|kne:el,,,,lt|know:_,,,,n|leap:_,,,,t|len:d,,,,t|lo:ose,,,,st|prove:_,,,,n|put:_,,,,_|quit:_,,,,_|rid:e,,,,den|s:eek,,,,ought|sen:d,,,,t|set:_,,,,_|sew:_,,,,n|shake:_,,,,n|shave:_,,,,d|shut:_,,,,_|s:eat,,,,at|sla:y,,,,in|sle:ep,,,,pt|sn:eak,,,,uck|spe:ed,,,,d|spen:d,,,,t|sp:it,,,,at|split:_,,,,_|spr:ing,,,,ung|st:ink,unk,,,unk|strew:_,,,,n|sw:are,,,,orn|swe:ep,,,,pt|thrive:_,,,,d|undergo:_,,,,ne|upset:_,,,,_|w:eave,,,,oven|we:ep,,,,pt|w:ind,,,,ound|wr:ing,,,,ung","plurals":"addend|um|a,alga|e,alumna|e,alumn|us|i,appendi|x|ces,avocado|s,bacill|us|i,barracks|,beau|x,bus|es,cact|us|i,chateau|x,analys|is|es,diagnos|is|es,parenthes|is|es,prognos|is|es,synops|is|es,thes|is|es,child|ren,circus|es,clothes|,corp|us|ora,criteri|on|a,curricul|um|a,database|s,deer|,echo|es,embargo|es,epoch|s,f|oot|eet,gen|us|era,g|oose|eese,halo|s,hippopotam|us|i,ind|ex|ices,larva|e,lea|f|ves,librett|o|i,loa|f|ves,m|an|en,matri|x|ces,memorand|um|a,modul|us|i,mosquito|es,move|s,op|us|era,ov|um|a,ox|en,pe|rson|ople,phenomen|on|a,quiz|zes,radi|us|i,referend|um|a,rodeo|s,sex|es,shoe|s,sombrero|s,stomach|s,syllab|us|i,tableau|x,thie|f|ves,t|ooth|eeth,tornado|s,tuxedo|s,zero|s","patterns":{"Person":["master of #Noun","captain of the #Noun"]},"regex":{"HashTag":["^#[a-z]+"],"Gerund":["^[a-z]+n[\'’]$"],"PhoneNumber":["^[0-9]{3}-[0-9]{4}$","^[0-9]{3}[ -]?[0-9]{3}-[0-9]{4}$"],"Time":["^[012]?[0-9](:[0-5][0-9])(:[0-5][0-9])$","^[012]?[0-9](:[0-5][0-9])?(:[0-5][0-9])? ?(am|pm)$","^[012]?[0-9](:[0-5][0-9])(:[0-5][0-9])? ?(am|pm)?$","^[PMCE]ST$","^utc ?[+-]?[0-9]+?$","^[a-z0-9]*? o\'?clock$"],"Date":["^[0-9]{1,4}-[0-9]{1,2}-[0-9]{1,4}$","^[0-9]{1,4}/[0-9]{1,2}/[0-9]{1,4}$"],"Money":["^[-+]?[$€¥£][0-9]+(.[0-9]{1,2})?$","^[-+]?[$€¥£][0-9]{1,3}(,[0-9]{3})+(.[0-9]{1,2})?$"],"Value":["^[-+]?[$€¥£][0-9]+(.[0-9]{1,2})?$","^[-+]?[$€¥£][0-9]{1,3}(,[0-9]{3})+(.[0-9]{1,2})?$","^[0-9.]{1,2}[-–][0-9]{1,2}$"],"NumberRange":["^[0-9.]{1,4}(st|nd|rd|th)?[-–][0-9.]{1,4}(st|nd|rd|th)?$","^[0-9.]{1,2}[-–][0-9]{1,2}$"],"NiceNumber":["^[-+]?[0-9.,]{1,3}(,[0-9.,]{3})+(.[0-9]+)?$"],"NumericValue":["^[-+]?[0-9]+(.[0-9]+)?$","^.?[0-9]+([0-9,.]+)?%$"],"Percent":["^.?[0-9]+([0-9,.]+)?%$"],"Cardinal":["^.?[0-9]+([0-9,.]+)?%$"],"Fraction":["^[0-9]{1,4}/[0-9]{1,4}$"],"LastName":["^ma?c\'.*","^o\'[drlkn].*"]}}'},{}],209:[function(t,e,r){"use strict";var o=t("../subset/verbs/methods/conjugate/faster.js");e.exports=function(a){var i=this;return Object.keys(a).forEach(function(r){i.conjugations[r]=i.conjugations[r]||{},i.words[r]=i.words[r]||"Infinitive",Object.keys(a[r]).forEach(function(t){var e=a[r][t];i.conjugations[r][t]=e,i.words[e]=i.words[e]||t,i.cache.toInfinitive[a[r][t]]=r});var n=o(r,i);Object.keys(n).forEach(function(t){var e=n[t];!1===i.words.hasOwnProperty(e)&&(i.words[e]=t)})}),a}},{"../subset/verbs/methods/conjugate/faster.js":79}],210:[function(t,e,r){"use strict";e.exports=function(e){var r=this;return Object.keys(e).forEach(function(t){r.patterns[t]=e[t]}),e}},{}],211:[function(t,e,r){"use strict";e.exports=function(r){var n=this;return Object.keys(r).forEach(function(t){var e=r[t];n.plurals[t]=e,n.words[e]=n.words[e]||"Plural",n.words[t]=n.words[t]||"Singular",n.cache.toSingular[e]=t}),r}},{}],212:[function(t,e,r){"use strict";e.exports=function(e){var r=this;Object.keys(e).forEach(function(t){r.regex.push({reg:new RegExp(t,"i"),tag:e[t]})})}},{}],213:[function(t,e,r){"use strict";var a=t("../tags/addDownward");e.exports=function(r){var n=this;return Object.keys(r).forEach(function(t){var e=r[t];e.notA=e.notA||[],e.downward=e.downward||[],n.tags[t]=e}),a(this.tags),r}},{"../tags/addDownward":135}],214:[function(t,e,r){"use strict";var h=t("../term/methods/normalize/normalize").normalize,f=t("../subset/nouns/methods/pluralize"),m=t("../subset/verbs/methods/conjugate/faster.js"),d=t("../subset/adjectives/methods"),p=/ /;e.exports=function(l){var c=this;return Object.keys(l).forEach(function(t){var e=l[t];if(t=h(t).replace(/\s+/," ").replace(/[.\?,;\!]/g,""),c.words[t]=e,!0===p.test(t)){var r=t.split(p);c.cache.firstWords[r[0]]=!0}if("Singular"!==e)if("Infinitive"!==e)if("PhrasalVerb"!==e){if("Comparable"===e){var n=d.toComparative(t);n&&t!==n&&(c.words[n]="Comparative");var a=d.toSuperlative(t);a&&t!==a&&(c.words[a]="Superlative")}}else{var i=t.split(/ /),o=m(i[0],c);Object.keys(o).forEach(function(t){var e=o[t]+" "+i[1];c.words[e]="PhrasalVerb",c.cache.firstWords[o[t]]=!0})}else{var s=m(t,c);Object.keys(s).forEach(function(t){c.words[s[t]]=t})}else{var u=f(t,{});u&&u!==t&&(c.words[u]="Plural")}}),l}},{"../subset/adjectives/methods":11,"../subset/nouns/methods/pluralize":44,"../subset/verbs/methods/conjugate/faster.js":79,"../term/methods/normalize/normalize":149}],215:[function(t,e,r){"use strict";var n=t("../fns"),a=t("./_data"),i=t("./more-data"),o=t("../tags"),s=t("./unpack"),u=t("./addTags"),l=t("./addWords"),c=t("./addRegex"),h=t("./addConjugations"),f=t("./addPatterns"),m=t("./addPlurals"),d=t("./more-data/misc"),p=function(t,e){for(var r=Object.keys(e),n=0;n<r.length;n++)t[r[n]]=e[r[n]];return t},g=function(){this.words={},this.tags=o,this.regex=[],this.patterns={},this.conjugations={},this.plurals={},this.cache={firstWords:{},toInfinitive:{},toSingular:{}}};g.prototype.addTags=u,g.prototype.addWords=l,g.prototype.addRegex=c,g.prototype.addConjugations=h,g.prototype.addPlurals=m,g.prototype.addPatterns=f,g.prototype.clone=function(){var e=this,r=new g;return["words","firstWords","tagset","regex","patterns","conjugations","plurals"].forEach(function(t){e[t]&&(r[t]=n.copy(e[t]))}),r},g.prototype.plugin=function(t){(t=s(t)).tags&&this.addTags(t.tags),t.regex&&this.addRegex(t.regex),t.patterns&&this.addPatterns(t.patterns),t.conjugations&&this.addConjugations(t.conjugations),t.plurals&&this.addPlurals(t.plurals),t.words&&this.addWords(t.words)};var v=new g;v.plugin(a),v.addWords(d),i.forEach(function(t){p(v.words,t)}),e.exports={w:v,reBuild:function(){var e=new g;return e.plugin(a),e.addWords(d),i.forEach(function(t){p(e.words,t)}),e}}},{"../fns":3,"../tags":137,"./_data":208,"./addConjugations":209,"./addPatterns":210,"./addPlurals":211,"./addRegex":212,"./addTags":213,"./addWords":214,"./more-data":217,"./more-data/misc":219,"./unpack":223}],216:[function(t,e,r){"use strict";for(var n={Noun:["arc","al","exp","fy","pd","pl","plz","tce","bl","ma","ba","lit","ex","eg","ie","ca","cca","vs","etc","esp","ft","bc","ad","md","corp","col"],Organization:["dept","univ","assn","bros","inc","ltd","co","yahoo","joomla","jeopardy"],Place:["rd","st","dist","mt","ave","blvd","cl","ct","cres","hwy","ariz","cal","calif","colo","conn","fla","fl","ga","ida","ia","kan","kans","minn","neb","nebr","okla","penna","penn","pa","dak","tenn","tex","ut","vt","va","wis","wisc","wy","wyo","usafa","alta","ont","que","sask"],Month:["jan","feb","mar","apr","jun","jul","aug","sep","sept","oct","nov","dec"],Date:["circa"],Honorific:["adj","adm","adv","asst","atty","bldg","brig","capt","cmdr","comdr","cpl","det","dr","esq","gen","gov","hon","jr","llb","lt","maj","messrs","mister","mlle","mme","mr","mrs","ms","mstr","op","ord","phd","prof","pvt","rep","reps","res","rev","sen","sens","sfc","sgt","sir","sr","supt","surg"],Value:["no"]},a={},i=Object.keys(n),o=0;o<i.length;o++)for(var s=n[i[o]],u=0;u<s.length;u++)a[s[u]]=[i[o],"Abbreviation"];e.exports=a},{}],217:[function(t,e,r){"use strict";e.exports=[t("./abbreviations"),t("./irregularAdjectives").lexicon,t("./numbers").lexicon,t("./orgWords")]},{"./abbreviations":216,"./irregularAdjectives":218,"./numbers":220,"./orgWords":221}],218:[function(t,e,r){"use strict";var n={bad:"badly",best:"best",early:"early",fast:"fast",good:"well",hard:"hard",icy:"icily",idle:"idly",late:"late",latter:"latter",little:"little",long:"long",low:"low",male:"manly",public:"publicly",simple:"simply",single:"singly",special:"especially",straight:"straight",vague:"vaguely",well:"well",whole:"wholly",wrong:"wrong"},a={grey:"greyer",gray:"grayer",green:"greener",yellow:"yellower",red:"redder",good:"better",well:"better",bad:"worse",sad:"sadder",big:"bigger"},i={nice:"nicest",late:"latest",hard:"hardest",inner:"innermost",outer:"outermost",far:"furthest",worse:"worst",bad:"worst",good:"best",big:"biggest",large:"largest"},o=function(t,e,r){for(var n=Object.keys(e),a=0;a<n.length;a++)t[n[a]]="Comparable",void 0===t[e[n[a]]]&&(t[e[n[a]]]=r);return t},s=o({},i,"Superlative");s=o(s=o(s,a,"Comparative"),n,"Adverb"),e.exports={lexicon:s,toAdverb:n,toComparative:a,toSuperlative:i}},{}],219:[function(t,e,r){"use strict";e.exports={"20th century fox":"Organization","3m":"Organization","7 eleven":"Organization","7-eleven":"Organization",g8:"Organization","motel 6":"Organization",vh1:"Organization",q1:"Date",q2:"Date",q3:"Date",q4:"Date",records:"Plural","&":"Conjunction"}},{}],220:[function(t,e,r){"use strict";var a={ones:{zero:0,one:1,two:2,three:3,four:4,five:5,six:6,seven:7,eight:8,nine:9},teens:{ten:10,eleven:11,twelve:12,thirteen:13,fourteen:14,fifteen:15,sixteen:16,seventeen:17,eighteen:18,nineteen:19},tens:{twenty:20,thirty:30,forty:40,fourty:40,fifty:50,sixty:60,seventy:70,eighty:80,ninety:90},multiples:{hundred:100,thousand:1e3,million:1e6,billion:1e9,trillion:1e12,quadrillion:1e15,quintillion:1e18,sextillion:1e21,septillion:1e24}},i={ones:{zeroth:0,first:1,second:2,third:3,fourth:4,fifth:5,sixth:6,seventh:7,eighth:8,ninth:9},teens:{tenth:10,eleventh:11,twelfth:12,thirteenth:13,fourteenth:14,fifteenth:15,sixteenth:16,seventeenth:17,eighteenth:18,nineteenth:19},tens:{twentieth:20,thirtieth:30,fortieth:40,fourtieth:40,fiftieth:50,sixtieth:60,seventieth:70,eightieth:80,ninetieth:90},multiples:{hundredth:100,thousandth:1e3,millionth:1e6,billionth:1e9,trillionth:1e12,quadrillionth:1e15,quintillionth:1e18,sextillionth:1e21,septillionth:1e24}},o={},s={},u={};Object.keys(i).forEach(function(t){for(var e=Object.keys(i[t]),r=Object.keys(a[t]),n=0;n<r.length;n++)o[r[n]]=e[n],s[e[n]]=r[n],u[e[n]]=["Ordinal","TextValue"],u[r[n]]=["Cardinal","TextValue"],"multiples"===t&&(u[e[n]].push("Multiple"),u[r[n]].push("Multiple"))}),e.exports={toOrdinal:o,toCardinal:s,cardinal:a,ordinal:i,prefixes:{yotta:1,zetta:1,exa:1,peta:1,tera:1,giga:1,mega:1,kilo:1,hecto:1,deka:1,deci:1,centi:1,milli:1,micro:1,nano:1,pico:1,femto:1,atto:1,zepto:1,yocto:1,square:1,cubic:1,quartic:1},lexicon:u}},{}],221:[function(t,e,r){"use strict";e.exports=["administration","agence","agences","agencies","agency","airlines","airways","army","assoc","associates","association","assurance","authority","autorite","aviation","bank","banque","board","boys","brands","brewery","brotherhood","brothers","building society","bureau","cafe","caisse","capital","care","cathedral","center","central bank","centre","chemicals","choir","chronicle","church","circus","clinic","clinique","club","co","coalition","coffee","collective","college","commission","committee","communications","community","company","comprehensive","computers","confederation","conference","conseil","consulting","containers","corporation","corps","corp","council","crew","daily news","data","departement","department","department store","departments","design","development","directorate","division","drilling","education","eglise","electric","electricity","energy","ensemble","enterprise","enterprises","entertainment","estate","etat","evening news","faculty","federation","financial","fm","foundation","fund","gas","gazette","girls","government","group","guild","health authority","herald","holdings","hospital","hotel","hotels","inc","industries","institut","institute","institute of technology","institutes","insurance","international","interstate","investment","investments","investors","journal","laboratory","labs","liberation army","limited","local authority","local health authority","machines","magazine","management","marine","marketing","markets","media","memorial","mercantile exchange","ministere","ministry","military","mobile","motor","motors","musee","museum","news","news service","observatory","office","oil","optical","orchestra","organization","partners","partnership","people's party","petrol","petroleum","pharmacare","pharmaceutical","pharmaceuticals","pizza","plc","police","polytechnic","post","power","press","productions","quartet","radio","regional authority","regional health authority","reserve","resources","restaurant","restaurants","savings","school","securities","service","services","social club","societe","society","sons","standard","state police","state university","stock exchange","subcommittee","syndicat","systems","telecommunications","telegraph","television","times","tribunal","tv","union","university","utilities","workers"].reduce(function(t,e){return t[e]="Noun",t},{})},{}],222:[function(t,e,r){"use strict";var u=[null,"PastTense","PresentTense","Gerund","Participle"];e.exports=function(t){return t.split("|").reduce(function(t,e){var r=e.split(":"),n=r[0],a=r[1].split(","),i=n+a[0];"_"===a[0]&&(i=n),t[i]={};for(var o=1;o<u.length;o++){var s=r[0]+a[o];"_"===a[o]&&(s=r[0]),a[o]&&(t[i][u[o]]=s)}return t},{})}},{}],223:[function(t,e,r){"use strict";var n={words:t("efrt-unpack"),plurals:t("./plurals"),conjugations:t("./conjugations"),keyValue:t("./key-value")};e.exports=function(t){var e=t;return"string"==typeof t&&(e=JSON.parse(t)),e.words&&"string"==typeof e.words&&(e.words=n.words(e.words)),e.patterns&&(e.patterns=n.keyValue(e.patterns)),e.regex&&(e.regex=n.keyValue(e.regex)),e.plurals&&"string"==typeof e.plurals&&(e.plurals=n.plurals(e.plurals)),e.conjugations&&"string"==typeof e.conjugations&&(e.conjugations=n.conjugations(e.conjugations)),e}},{"./conjugations":222,"./key-value":224,"./plurals":225,"efrt-unpack":1}],224:[function(t,e,r){"use strict";e.exports=function(t){var e=Object.keys(t),n=!0;return e[0]&&"string"==typeof t[e[0]]&&(n=!1),e.reduce(function(e,r){return!0===n?t[r].forEach(function(t){e[t]?("string"==typeof e[t]&&(e[t]=[e[t]]),e[t].push(r)):e[t]=r}):e[r]=t[r],e},{})}},{}],225:[function(t,e,r){"use strict";e.exports=function(t){return t.split(/,/g).reduce(function(t,e){var r=e.split(/\|/g);return 3===r.length?t[r[0]+r[1]]=r[0]+r[2]:2===r.length?t[r[0]]=r[0]+r[1]:t[r[0]]=r[0],t},{})}},{}]},{},[4])(4)});</script> <script>window.__nlpCompromise=window.nlp,delete window.nlp;</script> <script>var __AvsAnSimple=function(a){function i(a){var e=parseInt(r,36)||0,o=e&&e.toString(36).length;a.article="."==r[o]?"a":"an",r=r.substr(1+o);for(var n=0;n<e;n++){var t=a[r[0]]={};r=r.substr(1),i(t)}}var r="2h.#2.a;i;&1.N;*4.a;e;i;o;/9.a;e;h1.o.i;l1./;n1.o.o;r1.e.s1./;01.8;12.1a;01.0;12.8;9;2.31.7;4.5.6.7.8.9.8a;0a.0;1;2;3;4;5;6;7;8;9;11; .22; .–.31; .42; .–.55; .,.h.k.m.62; .k.72; .–.82; .,.92; .–.8;<2.m1.d;o;=1.=1.E;@;A6;A1;A1.S;i1;r1;o.m1;a1;r1; .n1;d1;a1;l1;u1;c1.i1.a1.n;s1;t1;u1;r1;i1;a1;s.t1;h1;l1;e1;t1;e1.s;B2.h2.a1.i1;r1;a.á;o1.r1.d1. ;C3.a1.i1.s1.s.h4.a2.i1.s1;e.o1.i;l1.á;r1.o1.í;u2.i;r1.r1.a;o1.n1.g1.j;D7.a1.o1.q;i2.n1.a1.s;o1.t;u1.a1.l1.c;á1. ;ò;ù;ư;E7;U1;R.b1;o1;l1;i.m1;p1;e1;z.n1;a1;m.s1;p5.a1.c;e;h;o;r;u1.l1;o.w1;i.F11. ;,;.;/;0;1;2;3;4;5;6;71.0.8;9;Ae;B.C.D.F.I2.L.R.K.L.M.N.P.Q.R.S.T.B;C1;M.D;E2.C;I;F1;r.H;I3.A1;T.R1. ;U;J;L3.C;N;P;M;O1. ;P1;..R2.A1. ;S;S;T1;S.U2.,;.;X;Y1;V.c;f1.o.h;σ;G7.e1.r1.n1.e;h1.a3.e;i;o;i1.a1.n1.g;o2.f1. ;t1.t1. ;r1.i1.a;w1.a1.r1.r;ú;Hs. ;&;,;.2;A.I.1;2;3;5;7;B1;P.C;D;F;G;H1;I.I6;C.G.N.P.S1.D;T.K1.9;L;M1;..N;O2. ;V;P;R1;T.S1.F.T;V;e2.i1.r;r1.r1.n;o2.n6;d.e1.s;g.k.o2;l.r1;i1.f;v.u1.r;I3;I2;*.I.n1;d1;e1;p1;e1;n1;d2;e1;n1;c1;i.ê.s1;l1;a1;n1;d1;s.J1.i1.a1.o;Ly. ;,;.;1;2;3;4;8;A3. ;P;X;B;C;D;E2. ;D;F1;T.G;H1.D.I1.R;L;M;N;P;R;S1;m.T;U1. ;V1;C.W1.T;Z;^;a1.o1.i1.g;o1.c1.h1.a1;b.p;u1.s1.h1;o.ộ;M15. ;&;,;.1;A1;.1;S./;1;2;3;4;5;6;7;8;Ai;B.C.D.F.G.J.L.M.N.P.R.S.T.V.W.X.Y.Z.B1;S1;T.C;D;E3.P1;S.W;n;F;G;H;I4. ;5;6;T1;M.K;L;M;N;O1.U;P;Q;R;S;T1;R.U2. ;V;V;X;b1.u1.m;f;h;o2.D1.e.U1;..p1.3;s1.c;Ny. ;+;.1.E.4;7;8;:;A3.A1;F.I;S1.L;B;C;D;E3.A;H;S1. ;F1;U.G;H;I7.C.D1. ;K.L.N.O.S.K;L;M1;M.N2.R;T;P1.O1.V1./1.B;R2;J.T.S1;W.T1;L1.D.U1.S;V;W2.A;O1.H;X;Y3.C1.L;P;U;a1.s1.a1.n;t1.h;v;²;×;O5;N1;E.l1;v.n2;c1.e.e1.i;o1;p.u1;i.P1.h2.i1.a;o2.b2;i.o.i;Q1.i1.n1.g1.x;Rz. ;&;,;.1;J./;1;4;6;A3. ;.;F1;T.B1;R.C;D;E3. ;S1.P;U;F;G;H1.S;I2.A;C1. ;J;K;L1;P.M5;1.2.3.5.6.N;O2.H;T2;A.O.P;Q;R1;F.S4;,...?.T.T;U4;B.M.N.S.V;X;c;f1;M1...h2.A;B;ò;S11. ;&;,;.4.E;M;O;T1..3.B;D;M;1;3;4;5;6;8;9;A3. ;8;S2;E.I.B;C3.A1. ;R2.A.U.T;D;E6. ;5;C3;A.O.R.I1.F.O;U;F3;&.H.O1.S.G1;D.H3.2;3;L;I2. ;S1.O.K2.I.Y.L3;A2. ;.;I1. ;O.M3;A1. ;I.U1.R.N5.A.C3.A.B.C.E.F.O.O5. ;A1.I;E;S1;U.V;P7;A7;A.C.D.M.N.R.S.E1. ;I4;C.D.N.R.L1;O.O.U.Y.Q1. ;R;S1;W.T9.A1. ;C;D;F;I;L;M;S;V;U7.B.L.M.N.P.R.S.V;W1.R;X1.M;h1.i1.g1.a1.o;p1.i1.o1;n.t2.B;i1.c1.i;T4.a2.i2.g1.a.s1.c;v1.e1.s;e1.a1.m1.p;u1.i2.l;r;à;Um..1.N1..1.C;/1.1;11. .21.1;L1.T;M1.N;N4.C1.L;D2. .P.K;R1. .a;b2;a.i.d;g1.l;i1.g.l2;i.y.m;no. ;a1.n.b;c;d;e1;s.f;g;h;i2.d;n;j;k;l;m;n;o;p;q;r;s;t;u;v;w;p;r3;a.e.u1.k;s3. ;h;t1;r.t4.h;n;r;t;x;z;í;W2.P1.:4.A1.F;I2.B;N1.H.O1.V;R1.F1.C2.N.U.i1.k1.i1.E1.l1.i;X7;a.e.h.i.o.u.y.Y3.e1.t1.h;p;s;[5.A;E;I;a;e;_2._1.i;e;`3.a;e;i;a7; .m1;a1;r1. .n1;d2; .ě.p1;r1;t.r1;t1;í.u1;s1;s1;i1. .v1;u1;t.d3.a1.s1. ;e2.m1. ;r1. ;i2.c1.h1. ;e1.s1.e2.m;r;e8;c1;o1;n1;o1;m1;i1;a.e1;w.l1;i1;t1;e1;i.m1;p1;e1;z.n1;t1;e1;n1;d.s2;a1. .t4;a1; .e1; .i1;m1;a1;r.r1;u1.t.u1.p1. ;w.f3. ;M;y1.i;h9. ;,;.;C;a1.u1.t1;b.e2.i1.r1;a.r1.m1.a1.n;o4.m2.a1; .m;n8; .b.d.e3; .d.y.g.i.k.v.r1.s1. ;u1.r;r1. ;t1;t1;p1;:.i6;b1;n.e1;r.n2;f2;l1;u1;ê.o1;a.s1;t1;a1;l1;a.r1; .s1; .u.k1.u1. ;l3.c1.d;s1. ;v1.a;ma. ;,;R;b1.a.e1.i1.n;f;p;t1.a.u1.l1.t1.i1.c1.a1.m1.p1.i;×;n6. ;V;W;d1; .t;×;o8;c2;h1;o.u1;p.d1;d1;y.f1; .g1;g1;i.no. ;';,;/;a;b;c1.o;d;e2.i;r;f;g;i;l;m;n;o;r;s;t;u;w;y;z;–;r1;i1;g1;e.t1;r1.s;u1;i.r3. ;&;f;s9.,;?;R;f2.e.o.i1.c1.h;l1. ;p2.3;i1. ;r1.g;v3.a.e.i.t2.A;S;uc; ...b2.e;l;f.k2.a;i;m1;a1. .n3;a3; .n5.a;c;n;s;t;r1;y.e2; .i.i8.c2.o1.r1.p;u1.m;d1;i1.o;g1.n;l1.l;m1;o.n;s1.s;v1.o1;c.r5;a.e.i.l.o.s3. ;h;u1.r2;e.p3;a.e.i.t2.m;t;v.w1.a;xb. ;';,;.;8;b;k;l;m1;a.t;y1. ;y1.l;{1.a;|1.a;£1.8;À;Á;Ä;Å;Æ;É;Ò;Ó;Ö;Ü;à;á;æ;è;é1;t3.a;o;u;í;ö;ü1; .Ā;ā;ī;İ;Ō;ō;œ;Ω;α;ε;ω;ϵ;е;–2.e;i;ℓ;";return i(a),{raw:a,query:function(i){var r,e,o=a,n=0;do{e=i[n++]}while("\"‘’“”$'".indexOf(e)>=0);for(;;){if(r=o.article||r,!(o=o[e]))return r;e=i[n++]||" "}}}}({});</script> <script>let textTransformNames = [];
|
||
|
||
function __addNodeMethods(node) {
|
||
// REMEMBER TO UPDATE stringAndNumberModifications and arrayModifications if you add more methods
|
||
|
||
Object.defineProperty(node, "$odds", {get:__$oddsMethod, configurable:true});
|
||
Object.defineProperty(node, "getOdds", {get:__$oddsMethod, configurable:true});
|
||
|
||
Object.defineProperty(node, "getName", {get:function() { return this.$text; }, configurable:true});
|
||
Object.defineProperty(node, "getParent", {get:function() { return this.$parent; }, configurable:true});
|
||
|
||
// This is incorrect because it counts properties that have been added by the user at runtime with code like `list.foo = 10`
|
||
// Object.defineProperty(node, "getLength", {get:function() { return Object.keys(this).length; }, configurable:true});
|
||
|
||
Object.defineProperty(node, "getLength", {get:function() { return this.$children.length; }, configurable:true});
|
||
Object.defineProperty(node, "getRawListText", {get:function() { return this.$perchanceCode; }, configurable:true});
|
||
|
||
// Workaround for the problem of a node not being resolved (mainly for use in functions) (I put this in the execution properties of the proxy)
|
||
Object.defineProperty(node, "getSelf", {get:function() { return this; }, configurable:true});
|
||
Object.defineProperty(node, "getPropertyKeys", {get:function() { return this.$valueChildren.slice(0); }, configurable:true}); // deprecated, but staying for backwards-compat. use getPropertyNames instead
|
||
Object.defineProperty(node, "getPropertyNames", {get:function() { return this.$valueChildren.slice(0); }, configurable:true});
|
||
Object.defineProperty(node, "getChildNames", {get:function() { return this.$children.slice(0); }, configurable:true});
|
||
Object.defineProperty(node, "getFunctionNames", {get:function() { return this.$functionChildren.slice(0); }, configurable:true});
|
||
Object.defineProperty(node, "getAllKeys", {get:function() { return this.$allKeys.slice(0); }, configurable:true});
|
||
|
||
// Object.defineProperty(node, "isConsumable", {value:false, writable:true, configurable:true})
|
||
|
||
Object.defineProperty(node, "toString", {value:__toStringMethod, configurable:true});
|
||
|
||
// we need this otherwise if they have:
|
||
// num = {1-1000}
|
||
// and they type [num.toLocaleString()], the JS engine calls toString on the object (since that's the default thing to do with objects, I guess), which results in a string.
|
||
Object.defineProperty(node, "toLocaleString", {value:function(...args) {
|
||
let result = String(this.toString()); // String()-ing because apparently toString can return a number?? no time to look into it right now
|
||
if(String(Number(result)) === result) {
|
||
result = Number(result);
|
||
}
|
||
return result.toLocaleString(...args);
|
||
}, writable:true, configurable:true});
|
||
|
||
Object.defineProperty(node, "evaluateItem", {get:function() {
|
||
return this.valueOf();
|
||
}, configurable:true});
|
||
|
||
|
||
// TODO: add a setter method for $odds which changes the node data? wait, shouldn't $odds just return the string? or not?
|
||
|
||
// TODO: these need fixing (see funciton declaration for notes)
|
||
// Object.defineProperty(node, "$addChild", {get:$addChildMethod});
|
||
// Object.defineProperty(node, "$removeChild", {get:$removeChildMethod});
|
||
|
||
Object.defineProperty(node, "selectOne", {get:__selectOneMethod, configurable:true});
|
||
Object.defineProperty(node, "selectAll", {get:__selectAllMethod, configurable:true});
|
||
Object.defineProperty(node, "selectMany", {value:__selectManyMethod, writable:true, configurable:true});
|
||
Object.defineProperty(node, "selectUnique", {value:__selectUniqueMethod, writable:true, configurable:true});
|
||
|
||
Object.defineProperty(node, "joinItems", {value:__joinItemsMethod, writable:true, configurable:true});
|
||
|
||
Object.defineProperty(node, "sumItems", {get:function() {
|
||
return this.selectAll.reduce((a, v) => a+v.evaluateItem, 0);
|
||
}, configurable:true});
|
||
|
||
Object.defineProperty(node, "valueOf", {value:__valueOfMethod, writable:true, configurable:true});
|
||
|
||
//Object.defineProperty(node, "shuffleItems", {value:shuffleMethod, configurable:true});
|
||
|
||
// TEXT TRANSFORMS:
|
||
Object.defineProperty(node, "pluralForm", {get:__pluralFormMethod, configurable:true});
|
||
Object.defineProperty(node, "singularForm", {get:__singularFormMethod, configurable:true});
|
||
Object.defineProperty(node, "pastTense", {get:__pastTenseMethod, configurable:true});
|
||
Object.defineProperty(node, "presentTense", {get:__presentTenseMethod, configurable:true});
|
||
Object.defineProperty(node, "futureTense", {get:__futureTenseMethod, configurable:true});
|
||
Object.defineProperty(node, "negativeForm", {get:__negativeFormMethod, configurable:true});
|
||
// TODO**: should have seperate "soft" versions of sentence and title case which DON'T call toLowerCase on the whole string first? (i.e. to leave current capitalisations there)
|
||
Object.defineProperty(node, "sentenceCase", {get:__sentenceCaseMethod, configurable:true});
|
||
Object.defineProperty(node, "titleCase", {get:__titleCaseMethod, configurable:true});
|
||
Object.defineProperty(node, "lowerCase", {get:__lowerCaseMethod, configurable:true});
|
||
Object.defineProperty(node, "upperCase", {get:__upperCaseMethod, configurable:true});
|
||
Object.defineProperty(node, "replaceText", {value:__replaceTextMethod, configurable:true});
|
||
// REMEMBER: add text transform names here if you add new ones:
|
||
if(textTransformNames.length === 0) {
|
||
textTransformNames.push("pluralForm");
|
||
textTransformNames.push("singularForm");
|
||
textTransformNames.push("pastTense");
|
||
textTransformNames.push("presentTense");
|
||
textTransformNames.push("futureTense");
|
||
textTransformNames.push("negativeForm");
|
||
textTransformNames.push("sentenceCase");
|
||
textTransformNames.push("titleCase");
|
||
textTransformNames.push("lowerCase");
|
||
textTransformNames.push("upperCase");
|
||
textTransformNames.push("replaceText");
|
||
}
|
||
|
||
|
||
//Object.defineProperty(node, "createClone", {get:createCloneMethod, configurable:true});
|
||
Object.defineProperty(node, "consumableList", {get:__consumableListMethod, configurable:true});
|
||
|
||
Object.defineProperty(node, "createClone", {get:function() { return __duplicatePerchanceNode(this); }, configurable:true});
|
||
|
||
// Object.defineProperty(node, "ordinal", {get:ordinalMethod});
|
||
|
||
// Object.defineProperty(node, "$withArticle", {get:withArticleMethod});
|
||
|
||
// TODO: add the rest of the default methods for version 1 (including getters like ".itemCount" (which gets the length of the $children array))
|
||
// TODO: .hideOutput transform?
|
||
// TODO: .replaceText("blah","na") transform (alias for .replace() except it always replaces ALL occurances unless you use regex and not the global flag)
|
||
// TODO: add any newly added execution properties to the proxy executionProperties array (e.g. replaceText)
|
||
// TODO***: remember that you'll need to move the `apply`s along with the text transforms that have an `apply` (e.g. replaceText)
|
||
}
|
||
|
||
let __replaceTextMethod = function(needle, replacement) {
|
||
if(needle instanceof RegExp) {
|
||
return this.toString().replace(needle, replacement.toString());
|
||
} else {
|
||
//needle = new RegExp(needle.toString(), "g");
|
||
//return this.toString().replace(needle, replacement.toString());
|
||
return this.toString().split(needle.toString()).join(replacement.toString());
|
||
}
|
||
}
|
||
|
||
// let createCloneMethod = function() {
|
||
// // TODO*****: This would try to clone $moduleSpace, $parent, $root, etc.???????????????????!!!!!!!!!!!!!!!!
|
||
// // --> test by putting in debugger and testing `this.$parent === clone.parent`
|
||
// // --> need to temporarily remove properties which reference other node objects directly? then add them back after
|
||
// // At least it DOESN'T make copies of functions
|
||
// // I think I need to make my own cloner... either that or really make sure this is working like I expect
|
||
// let clone = cloner.deep.copy(this);
|
||
// if(!this.___isLocalCall) {
|
||
// return clone;
|
||
// } else {
|
||
//
|
||
// let proxiedThisRef;
|
||
// proxiedThisRef = new Proxy(clone, {
|
||
// // NOTE: if you edit this, edit the same one in evaluateSquareBlock
|
||
// get: function(target, property, receiver) {
|
||
// if(property === "$output") {
|
||
// return undefined;
|
||
// } else if(property === "___isLocalCall") {
|
||
// return true;
|
||
// } else {
|
||
//
|
||
// let desc = Object.getOwnPropertyDescriptor(target, property);
|
||
// if(!desc) {
|
||
// perchanceError(`The '${property}' property doesn't exist within '${target.getName}'.`, ctxInfo.declarationLineNumber);
|
||
// return;
|
||
// }
|
||
// if(desc.get) {
|
||
// return desc.get.bind(proxiedThisRef)();
|
||
// } else if(desc.value && typeof desc.value === 'function') {
|
||
// return desc.value.bind(proxiedThisRef);
|
||
// } else {
|
||
// return target[property];
|
||
// }
|
||
//
|
||
// }
|
||
// }
|
||
// });
|
||
//
|
||
// return proxiedThisRef;
|
||
//
|
||
// }
|
||
// };
|
||
|
||
let __consumableListMethod = function() {
|
||
|
||
|
||
// it's called consumable*List* because it only makes sense to call it on a list-oriented node
|
||
|
||
// let list = this.createClone;
|
||
// Object.defineProperty(list, "isConsumable", {value:true, configurable:true, writable:true}); // not $-prefixed because it should be publicly changable
|
||
// return list;
|
||
|
||
// If this node is wrapped in the $output-hider (See REF:kjhfw927f63ohwkgw82g in evaluateSquareBlock.js), then we unwrap it and do the unhiding ourself in the proxy we create below.
|
||
// This is needed due to this problem: https://www.reddit.com/r/perchance/comments/fx7exs/how_to_have_multiple_lists_point_to_the_same/fmxzccb/ Basically, if we have something like `$output = [this.consumableList.selectMany(3)]`, then, target[property] will be returned (in the below proxy's getter) *bound to the $output-hider proxy* rather than this one, and so there is no consumableList from the perspective of selectMany. So we make this proxy handle the $output hiding stuff. Remember than binding is different to proxying! This is some chef's kiss spaghetti
|
||
let thisRef = this;
|
||
let $outputShouldBeHidden = false;
|
||
if(thisRef.___$outputShouldBeHidden) {
|
||
thisRef = thisRef.___proxyTarget;
|
||
$outputShouldBeHidden = true;
|
||
}
|
||
|
||
let proxy = new Proxy(thisRef, {
|
||
alreadyConsumedItems:new Set(),
|
||
get: function(target, property) {
|
||
if(property === "selectOne") {
|
||
// NOTE: inline consumable lists are handled in the toStringMethod
|
||
let selectedNode = __selectOneMethod.bind(proxy)();
|
||
if(selectedNode && selectedNode.$nodeType) { // make sure it's a node (could be an error string)
|
||
this.alreadyConsumedItems.add(selectedNode);
|
||
}
|
||
return selectedNode;
|
||
} else if(property === "evaluateItem") {
|
||
return __valueOfMethod.bind(proxy)();
|
||
} else if(property === "getLength") {
|
||
if(Object.keys(target).includes("getLength")) return target["getLength"];
|
||
else return target.$children.length - this.alreadyConsumedItems.size;
|
||
// else return Object.keys(target).length - this.alreadyConsumedItems.size;
|
||
} else if(property === "$alreadyConsumedItems") {
|
||
return this.alreadyConsumedItems;
|
||
} else if(textTransformNames.includes(property)) {
|
||
return proxy.selectOne[property]; // added due to this problem: https://www.reddit.com/r/perchance/comments/7uw0sp/errors_with_consumablelist_and_uppercase_together/
|
||
} else if(property === "getSelf") {
|
||
return proxy;
|
||
} else if($outputShouldBeHidden && property === "$output") {
|
||
return undefined;
|
||
} else {
|
||
// TODO: strangely, the return value here seems to be automatically bound to this proxy.
|
||
// so it also handles toString and valueOf methods like we want it to.
|
||
// I think it's because in `foo().bar()`, bar is by default bound to the thing returned by foo?
|
||
return target[property];
|
||
}
|
||
},
|
||
});
|
||
|
||
return proxy;
|
||
|
||
};
|
||
|
||
|
||
let __valueOfMethod = function(key) {
|
||
let str = this.toString();
|
||
if(String(Number(str)) === str) {
|
||
return Number(str);
|
||
} else {
|
||
return str;
|
||
}
|
||
};
|
||
|
||
|
||
// let idMethod = function(key) {
|
||
//
|
||
// if(typeof key !== 'string') {
|
||
// key = key.toString();
|
||
// }
|
||
//
|
||
// // TODO***: (BIG ONE): clone `this` and set its toString method so it
|
||
// // always returns the $child string that was selected below BUT ALSO can
|
||
// // still have its sub-properties accessed. (i.e. the only difference between
|
||
// // the clone and the original is that the clone always returns a static string
|
||
// // when toString is called (instead of selecting a random child - or returning the
|
||
// // evaluated $value text in the case of a $value node))
|
||
// // BUT HERE'S THING THING: if a child node is selected and it's "the {cat|dog}", do
|
||
// // future requests to that id return "the {cat|dog}" or the EVALUATED version of
|
||
// // that text? So we can store either:
|
||
// // - the node itself
|
||
// // - the text of the node
|
||
// // - the *evaluated* text of the node
|
||
// // and return it next time that id is called again. Which one? The ideal one seems
|
||
// // to depend on the context:
|
||
// /*
|
||
//
|
||
// // here, the node one doesn't make sense, but the other two work fine
|
||
// animal
|
||
// dog
|
||
// cat
|
||
// pig
|
||
//
|
||
// // here, the node one doesn't make sense, and the other two behave differently.
|
||
// // it seems like storing the *evaluated* text would make the most sense in this case.
|
||
// sentence
|
||
// I'm {going|running} to the {shops|hotel}.
|
||
// That's a {great|silly|quaint} handbag you've got there.
|
||
// // and actually, I can't think of an example where storing the un-evaluated text would
|
||
// // make sense.
|
||
//
|
||
// NEW TACK: curly notation for the id thing because it will be so common:
|
||
// {animal#1} -> [animal.$id(1)]
|
||
// but wait - I still need to decide on id behavior...
|
||
// -----
|
||
// The cloning behaviour makes the most sense? Need to bite the bullet and spend a day perfecting this.
|
||
// It's an integral part of the last big trio (id/unique/remember)
|
||
//
|
||
//
|
||
// */
|
||
//
|
||
// if(this.$idStore[key]) {
|
||
// return this.$idStore[key];
|
||
// } else {
|
||
// let child = this.$child;
|
||
//
|
||
// // if its text is dynamic, we need to evaluate it (they expect the same text each time!).
|
||
// // if it's not, there's no need to evaluate it.
|
||
// // note that if it IS dynamic, then there won't be any child properties, so we can just store
|
||
// // and return a plain old string!
|
||
// let blocks = splitTextAtAllBlocks(child.$text);
|
||
// if(blocks.length > 1 || blocks[0][0] === "[" || blocks[0][0] === "{") {
|
||
// child = child.toString();
|
||
// }
|
||
//
|
||
// this.$idStore[key] = child;
|
||
// return this.$idStore[key];
|
||
// }
|
||
//
|
||
// };
|
||
// let setIdMethod = function(key) {
|
||
// if(this.$idStore[key]) {
|
||
// delete this.$idStore[key];
|
||
// }
|
||
// return this.$id(key);
|
||
// };
|
||
|
||
|
||
let __selectAllMethod = function() {
|
||
|
||
// This methos gets ALL items, regarless of whether they have odds == 0
|
||
// If one wants to exlude `odds==0` items: list.selectAll.filter(item => item.getOdds > 0)
|
||
|
||
let $output = this.$output;
|
||
if($output !== undefined) {
|
||
return [$output]; // make it an array because why not. (consistency is nice)
|
||
}
|
||
|
||
if(this.$nodeType === "value") {
|
||
let text = this.$value;
|
||
if(text[0] === "{" && text[text.length-1] === "}") {
|
||
let items = __splitUpCurlyOrBlock(text.substr(1, text.length-2));
|
||
if(items) { // i.e. if it's a valid curly OR block
|
||
return items;
|
||
} else {
|
||
__perchanceError(`You've called 'selectAll' on something that doesn't appear to be a list?`, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
return;
|
||
}
|
||
} else {
|
||
__perchanceError(`You've called 'selectAll' on something that doesn't appear to be a list?`, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
return;
|
||
}
|
||
}
|
||
|
||
let arr = [];
|
||
for(let key of this.$children) {
|
||
arr.push(this[key]);
|
||
}
|
||
arr.toString = function() { return this.join(""); }; // This makes sense, right? Who would selectAll, but then expect a single random item? That would be silly.
|
||
return arr;
|
||
};
|
||
|
||
|
||
|
||
|
||
let __selectOneMethod = function() {
|
||
|
||
const isConsumableList = !!this.$alreadyConsumedItems;
|
||
|
||
let consumedNodes = new Set();
|
||
if(isConsumableList) {
|
||
consumedNodes = this.$alreadyConsumedItems; // this is a property of the consumableList proxy handler that we expose
|
||
}
|
||
|
||
let $output = this.$output; // cache it so we don't "execute" it twice if it's something like `$output = [this.age++]`
|
||
if($output !== undefined) {
|
||
return $output;
|
||
}
|
||
|
||
if(this.$nodeType === "value") {
|
||
// I'm pretty sure we want to `toString` (evaulate) it because why would you call selectOne on a value node otherwise?
|
||
// Consider these two examples:
|
||
// height = {1-10}
|
||
// height
|
||
// {1-10}
|
||
// You might think we should treat the former the same way as the latter (i.e. NOT evaluate it), but that doesn't make sense in terms of the user's intention.
|
||
// I'm pretty sure I've made the right decision here but hopefully the beta testers will surface any mistakes in my reasoning.
|
||
let result = this.toString();
|
||
if(String(Number(result)) === result) return Number(result);
|
||
else return result;
|
||
}
|
||
|
||
let textNodes = [];
|
||
let oddsSum = 0;
|
||
let oddsArray = [];
|
||
|
||
for(let key of this.$children) {
|
||
let node = this[key];
|
||
if(!consumedNodes.has(node)) {
|
||
let odds = node.$odds; // remember, $odds is a getter and could be dynamic, so we musn't call it multiple times and expect the same result
|
||
|
||
// if it has odds of zero, leave it out - but don't consume it, because it hasn't been consumed (zero odds could be temporary, for example)
|
||
// EDIT: turns this doesn't really make sense for non-consumable lists (because you end up with problems like this: https://www.reddit.com/r/perchance/comments/co6msx/bug_list_name_being_included_in_output_of_list/)
|
||
// and it's not really that useful for cosumableLists either except to help people find bugs where their list ran out of non-zero-odds items. So I think
|
||
// due to the problems it causes with peoples' code it's not worth the trouble. So I'm commenting it out for now.
|
||
//if(odds === 0 && isConsumableList) continue;
|
||
|
||
if(odds < 0 || isNaN(odds)) {
|
||
__perchanceError(`The item on this line has the following odds: <code>${node.$oddsText}</code>. This has resulted in an odds value of <code>${odds}</code>, which is not valid. It should be a positive number.`, {declarationLineNumber:node.$declarationLineNumber, moduleName:node.$moduleName});
|
||
}
|
||
|
||
textNodes.push(node);
|
||
oddsSum += odds;
|
||
oddsArray.push(odds);
|
||
}
|
||
}
|
||
|
||
if(textNodes.length === 0) {
|
||
if(consumedNodes.size > 0) return `(no more items in the consumable '${this.$text}' list)`;
|
||
else {
|
||
let out = __evaluateText(this.$root, this.$parent, this.$text, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName}); // we need to return the text if no children, otherwise we can't do nice stuff like this: https://www.reddit.com/r/perchance/comments/6g1uqk/fixed_variables/dio2da4/
|
||
if(window.generatorLastEditTime > 1716337636385) { // May 22nd 2024 bugfix, ensures only generators edited after this time get it, to prevent breaking old generators that rely on the bug
|
||
out = __processEscapedCharacters(out);
|
||
}
|
||
return out;
|
||
}
|
||
// and we need to *evaluate* the text because otherwise we couldn't do `c = b.selectOne.selectOne` in this example: https://www.reddit.com/r/perchance/comments/6qqc4d/items_in_shorthand_lists_arent_always_stored/dl01lkv/
|
||
|
||
//else return `('${this.$text}' is not a list)`;
|
||
// don't throw error because it's okay for a node not to have children
|
||
//console.error(`Error trying to get child nodes of '${this.$text}' which was declared on line number ${this.$declarationLineNumber}.`);
|
||
// if(this.isConsumable) return `(no more items in the consumable '${this.$text}' list)`;
|
||
// else return `('${this.$text}' is not a list)`; // TODO***: return `this.$text` here since it's not consumable and has no children?
|
||
}
|
||
|
||
// choose random position in oddsSum range
|
||
let oddsSumStopPoint = oddsSum*Math.random();
|
||
let selectedTextNode = null;
|
||
let oddsSumForChoice = 0;
|
||
|
||
for(let i = 0; i < textNodes.length; i++) {
|
||
oddsSumForChoice += oddsArray[i];
|
||
if(oddsSumForChoice >= oddsSumStopPoint) {
|
||
selectedTextNode = textNodes[i];
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(selectedTextNode === null) {
|
||
__perchanceError(`This shouldn't happen! This may be a problem with the Perchance engine. Please report this bug to <a href='https://lemmy.world/c/perchance'>lemmy.world/c/perchance</a>. A text node couldn't be picked during a random selection in a node's .toString() function. Here's some extra details for the bug report: this.$text=${this.$text}; this.$children=${this.$children.join(",")}; this.$declarationLineNumber=${this.$declarationLineNumber}`, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
console.log(this, textNodes);
|
||
console.error("Returning first text node rather than random one to prevent crashing while debugging.");
|
||
return textNodes[0];
|
||
}
|
||
|
||
// if(this.isConsumable) {
|
||
// let text = selectedTextNode.$text;
|
||
// this.$children = this.$children.filter(c => c !== text);
|
||
// delete this[text];
|
||
// }
|
||
|
||
return selectedTextNode;
|
||
|
||
}
|
||
|
||
|
||
let __toStringMethod = function(opts={}) {
|
||
|
||
// NOTE: We can't call processEscapedCharacters on the text before returning it because this method gets called
|
||
// DURING the evaluateSquareBlock calls that are inside evaluateText, and so processEscapedCharacters would get
|
||
// called multiple times on the same text. We actually (sort of counterintuitively) want to keep all the backslashes
|
||
// in the input until just before the whole string is returned.
|
||
// I was previously doing this by calling processEscapedCharacters in the updateTemplatedNodes function, but the
|
||
// problem with that is that if you have something like onclick="outputEl.innerHTML = animal.description" it won't
|
||
// remove the backslashes from the animal.description text. I was previously solving that by using the MutationObserver
|
||
// stuff, but that still doesn't cut it, because when you grab the text from a Perchance node and manipulate it with JS,
|
||
// you obviously don't expect it to have the escape characters in it.
|
||
// --> WAIT. I haven't slept in way too long, but I have a crazy theory that we actually don't want to strip the backslashes
|
||
// when the text is "viewed" from JavaScript. JavaScript is the "engine" so it makes sense that we'd see the text in its
|
||
// most "raw" state - no processing at all. Oh, so I just need to make evaluateItem strip the backslashes??
|
||
// --> WAIT AGAIN: I don't think that makes sense. When we convert a node/item to a string, we expect it to just be a plain
|
||
// string. It's "out of perchance" at that point. It's just meant to be a plain old string. So I think the obvious thing
|
||
// to do here (regarding the above note about this being used in the evaluateText function - and wanting to preserve
|
||
// backslashes until right before the final string is returned from this function) is just to use a version of this method
|
||
// which specifically doesn't remove backslashes, right? Should this function just take an options object? Yep, I'm going
|
||
// with that.
|
||
|
||
// TODO***: use getOwnPropertyDescriptor to detect $output? since it could be defined and yet return undefined
|
||
// make sure you update other methods too
|
||
let $output = this.$output;
|
||
if($output !== undefined) {
|
||
$output = typeof $output === "number" ? $output.toString() : $output.toString({keepEscapes:opts.keepEscapes}); // only pass the keepEscapes object if it's not a number (because numbers expect a radix as the param of toString)
|
||
let result = __evaluateText(this.$root, this.$parent, $output, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
if(opts.keepEscapes) return result;
|
||
else return __processEscapedCharacters(result);
|
||
}
|
||
|
||
if(this.$nodeType === "value") {
|
||
if(typeof this.$value === "number") { return this.$value; }
|
||
else {
|
||
// if it's a consumableList and is plain inline notation like {1|2|3|4|...} with nothing before or after, then let's consume it
|
||
let text = this.$value;
|
||
if(this.$alreadyConsumedItems && text[0] === "{" && text[text.length-1] === "}") {
|
||
let items = __splitUpCurlyOrBlock(text.substr(1, text.length-2));
|
||
if(items) { // i.e. if it's a valid curly OR block
|
||
// remove already consumed items
|
||
items = items.filter(i => !this.$alreadyConsumedItems.has( __getTextOddsDetails(i).textWithoutOdds || i )); // "|| i" needed because getTextOddsDetails returns false if no odds details
|
||
if(items.length === 0) return `(inline consumable list '${this.$key}' has no more items)`;
|
||
// choose an item
|
||
let chosenItem = __chooseRandomTextByOdds(this.$root, this.$parent, items, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
// add the chosen item to $alreadyConsumedItems
|
||
this.$alreadyConsumedItems.add(chosenItem);
|
||
// return the chosen item
|
||
if(opts.keepEscapes) return chosenItem;
|
||
else return __processEscapedCharacters(chosenItem);
|
||
}
|
||
}
|
||
if(this.$alreadyConsumedItems) __perchanceError(`You tried to make this into a consumable list: <code>${__escapeHTMLSpecialChars(this.$key)} = ${__escapeHTMLSpecialChars(this.$value)}</code>, but for an inline item to be consumable, it must be of the format <code>a = {b|c|d}</code> and cannot have anything outside of the curly brackets (e.g. you could not make <code>a = {b|c|d}efg</code> consumable).`, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
let result = __evaluateText(this.$root, this.$parent, this.$value, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
if(opts.keepEscapes) return result;
|
||
else return __processEscapedCharacters(result);
|
||
}
|
||
}
|
||
|
||
// toString treats childless nodes differently to ones that have children (i.e. items that are themselves lists)
|
||
// this sounds like a terrible idea at first, but I've put a bit of thought into it and it seems like the best option
|
||
// so that newbies don't have to understand how the engine works just to simply do: [f = flower.selectOne]. The
|
||
// alternative would be to make them do [f = flower.selectOne.itemName] which is ridiculous.
|
||
// If you think about it, this approach actually makes a bit of sense. If `this` node is itself a list, then that's
|
||
// an important fundamental difference, and so a difference in behaviour isn't really too unexpected.
|
||
// What we're basically saying is that leaves are treated differently to branches. The awesome part about this
|
||
// approach is that it alls us to do `[a = animal.selectOne] ... [a.genus]` - i.e. we can access the *properties*
|
||
// of the selected animal. [a=animal.outputText] doesn't allow us to do this.
|
||
if(this.$children.length === 0) {
|
||
let result = __evaluateText(this.$root, this.$parent, this.$text, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
if(opts.keepEscapes) return result;
|
||
else return __processEscapedCharacters(result);
|
||
}
|
||
|
||
if(this.$children.length > 0) {
|
||
|
||
let child = this.selectOne;
|
||
if(typeof child === 'string') { // e.g., if it is an error message
|
||
return child;
|
||
}
|
||
let text = child.$text;
|
||
|
||
let result = __evaluateText(this.$root, child.$parent, text, {declarationLineNumber:child.$declarationLineNumber, moduleName:child.$moduleName});
|
||
if(opts.keepEscapes) return result;
|
||
else return __processEscapedCharacters(result);
|
||
|
||
}
|
||
|
||
};
|
||
|
||
|
||
// let addItemMethod = function(key) {
|
||
// this.$children.push(key);
|
||
// this[key] = undefined;
|
||
// console.log("THIS NEEDS FIXING! (see TODO, below this line)")
|
||
// // TODO: fix this? what if they want to add a child of the added child? needs to be a *proper* node?
|
||
// // TODO: implement $addChildren and $removeChildren methods ($addChild and $removeChild should really just be aliases of these)
|
||
// };
|
||
// let removeItemMethod = function(key) {
|
||
// this.$children.filter(k => k !== key);
|
||
// delete this[key];
|
||
// // TODO: verify that this works and makes sense
|
||
// };
|
||
|
||
let __$oddsMethod = function() {
|
||
|
||
if(this.$oddsText == '1') return 1;
|
||
if( String(Number(this.$oddsText)) === this.$oddsText ) return Number(this.$oddsText);
|
||
|
||
// NOTE: must use $oddsText odds rather than this.$odds, because this is the definition of $odds! (it'd be recursive)
|
||
if(typeof this.$oddsText !== 'string') {
|
||
__perchanceError(`This shouldn't happen. This may be a problem with the Perchance engine. Please report this bug to <a href='https://lemmy.world/c/perchance'>lemmy.world/c/perchance</a>. The odds property of this node isn't a string. Here's some extra details for the bug report: this.$text=${__escapeHTMLSpecialChars(this.$text)}; this.$children=${__escapeHTMLSpecialChars(this.$children.join(","))}; this.$declarationLineNumber=${__escapeHTMLSpecialChars(this.$declarationLineNumber)}; this.$oddsText=${__escapeHTMLSpecialChars(this.$oddsText)}`, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
return 1;
|
||
}
|
||
|
||
let evaluatedOdds = __oddsTextToNumber(this.$root, this.$parent, this.$oddsText, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
if(typeof evaluatedOdds === 'number') {
|
||
return evaluatedOdds;
|
||
} else {
|
||
// TODO: potentially convert strings to numbers using eval (if it is a number, obviously). The reason
|
||
// I'm not doing it yet is because I may do string->number conversions automatically across the whole system.
|
||
// i.e. in the evaluateSquareBlock function itself.
|
||
__perchanceError(`The '^' character is used to specify how likely an item is of being chosen during a random selection. This line appears to have a '^' character, but the text after that character (<b>${__escapeHTMLSpecialChars(this.$oddsText)}</b>) isn't a number, or didn't evaluate to a number. You're allowed to use square and curly bracket expressions to randomly/dynamically determine the odds, but these expressions must evaluate to a number. In this case your odds expression didn't result in a number.`, {declarationLineNumber:this.$declarationLineNumber, moduleName:this.$moduleName});
|
||
|
||
return 1;
|
||
}
|
||
|
||
};
|
||
|
||
// let shuffleMethod = function(numShuffles) {
|
||
//
|
||
// // TODO***: can't order object keys, so this method is useless on nodes (but useful for arrays and strings)
|
||
//
|
||
// if(numShuffles === undefined) {
|
||
//
|
||
// var array = this.$children;
|
||
// var currentIndex = array.length, temporaryValue, randomIndex;
|
||
// // While there remain elements to shuffle...
|
||
// while (0 !== currentIndex) {
|
||
// // Pick a remaining element...
|
||
// randomIndex = Math.floor(Math.random() * currentIndex);
|
||
// currentIndex -= 1;
|
||
// // And swap it with the current element.
|
||
// temporaryValue = array[currentIndex];
|
||
// array[currentIndex] = array[randomIndex];
|
||
// array[randomIndex] = temporaryValue;
|
||
// }
|
||
// array = array.map(c => this[c]); // map to actual node objects
|
||
// array.toString = function() { this.join(""); }
|
||
// return array;
|
||
//
|
||
// } else {
|
||
//
|
||
// let text = this.toString().split("");
|
||
// for(let i = 0; i < numShuffles; i++) {
|
||
// let i1 = Math.floor(text.length*Math.random());
|
||
// let i2 = Math.floor(text.length*Math.random());
|
||
// let c1 = text[i1];
|
||
// let c2 = text[i2];
|
||
// text[i1] = c2;
|
||
// text[i2] = c1;
|
||
// }
|
||
// return text.join("");
|
||
//
|
||
// }
|
||
//
|
||
// }
|
||
|
||
|
||
let __joinItemsMethod = function(str) {
|
||
|
||
let $output = this.$output;
|
||
if($output !== undefined) {
|
||
return $output.toString();
|
||
}
|
||
|
||
let arr = [];
|
||
for(let c of this.$children) {
|
||
arr.push(this[c].getName);
|
||
}
|
||
return arr.joinItems(str+"");
|
||
};
|
||
|
||
|
||
let __selectUniqueMethod = function(...a) {
|
||
return this.consumableList.selectMany(...a);
|
||
};
|
||
|
||
let __selectManyMethod = function(...a) {
|
||
|
||
let num;
|
||
if(a.length === 1) {
|
||
if(Array.isArray(a[0])) {
|
||
num = Number(a[0][Math.floor(Math.random()*a[0].length)]);
|
||
} else {
|
||
num = Number(a[0]);
|
||
}
|
||
} else if(a.length === 2) {
|
||
num = Number(a[0]) + Math.round(Math.random()*(a[1]-a[0]));
|
||
} else if(a.length > 2) {
|
||
num = Number(a[Math.floor(Math.random()*a.length)]);
|
||
}
|
||
if(isNaN(num) || typeof num !== 'number') {
|
||
if(a.length === 0) {
|
||
__perchanceError(`You didn't give the selectMany() function any inputs when you used it on the node with the text "${__escapeHTMLSpecialChars(this.$text || this)}". You need to give it at least one input so it knows how long the list/array should be.`, {moduleName:this.$moduleName});
|
||
} else {
|
||
__perchanceError(`There's a problem with the inputs that you provided to the "selectMany" function when you used it on the node with the text "${__escapeHTMLSpecialChars(this.$text || this)}". You have given it the following input${a.length == 1 ? "" : "s"}: <b>${__escapeHTMLSpecialChars(a.join("</b>, <b>"))}</b>. ${a.length == 1 ? "This" : "These"} input${a.length == 1 ? "" : "s"} should be numeric (i.e. ${a.length == 1 ? "it" : "they"} should be${a.length == 1 ? " a " : " "} number${a.length == 1 ? "" : "s"}).`, {moduleName:this.$moduleName});
|
||
}
|
||
return ["(syntax error)"];
|
||
}
|
||
let arr = [];
|
||
for(let i = 0; i < num; i++) {
|
||
arr.push(this.selectOne);
|
||
}
|
||
// overwrite default array behaviour (selects a random one)
|
||
// in the case where they don't specify a join() after the repeat:
|
||
arr.toString = function() { return this.join(""); };
|
||
return arr;
|
||
};
|
||
|
||
|
||
|
||
let __titleCaseMethod = function() {
|
||
return this.toString().split(' ').map((s) => (s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase())).join(' ');
|
||
};
|
||
let __sentenceCaseMethod = function() {
|
||
return this.toString().split(/([!?.]+)/g).map((s) => {
|
||
let i = s.search(/[a-zA-Z]/);
|
||
let a = s.slice(0, i);
|
||
let b = s.slice(i, i+1).toUpperCase();
|
||
let c = s.slice(i+1);
|
||
return a + b + c;
|
||
}).join("");
|
||
};
|
||
let __upperCaseMethod = function() {
|
||
//debugger;
|
||
return this.toString().toUpperCase();
|
||
};
|
||
let __lowerCaseMethod = function() {
|
||
return this.toString().toLowerCase();
|
||
};
|
||
|
||
!function(e,a){"function"==typeof require&&"object"==typeof exports&&"object"==typeof module?module.exports=a():"function"==typeof define&&define.amd?define(function(){return a()}):e.pluralize=a()}(this,function(){var e=[],a=[],i={},r={},s={};function o(e){return"string"==typeof e?new RegExp("^"+e+"$","i"):e}function t(e,a){return e===a?a:e===e.toLowerCase()?a.toLowerCase():e===e.toUpperCase()?a.toUpperCase():e[0]===e[0].toUpperCase()?a.charAt(0).toUpperCase()+a.substr(1).toLowerCase():a.toLowerCase()}function n(e,a){return e.replace(a[0],function(i,r){var s,o,n=(s=a[1],o=arguments,s.replace(/\$(\d{1,2})/g,function(e,a){return o[a]||""}));return t(""===i?e[r-1]:i,n)})}function u(e,a,r){if(!e.length||i.hasOwnProperty(e))return a;for(var s=r.length;s--;){var o=r[s];if(o[0].test(a))return n(a,o)}return a}function l(e,a,i){return function(r){var s=r.toLowerCase();return a.hasOwnProperty(s)?t(r,s):e.hasOwnProperty(s)?t(r,e[s]):u(s,r,i)}}function c(e,a,i,r){return function(r){var s=r.toLowerCase();return!!a.hasOwnProperty(s)||!e.hasOwnProperty(s)&&u(s,s,i)===s}}function h(e,a,i){return(i?a+" ":"")+(1===a?h.singular(e):h.plural(e))}return h.plural=l(s,r,e),h.isPlural=c(s,r,e),h.singular=l(r,s,a),h.isSingular=c(r,s,a),h.addPluralRule=function(a,i){e.push([o(a),i])},h.addSingularRule=function(e,i){a.push([o(e),i])},h.addUncountableRule=function(e){"string"!=typeof e?(h.addPluralRule(e,"$0"),h.addSingularRule(e,"$0")):i[e.toLowerCase()]=!0},h.addIrregularRule=function(e,a){a=a.toLowerCase(),e=e.toLowerCase(),s[e]=a,r[a]=e},[["I","we"],["me","us"],["he","they"],["she","they"],["them","them"],["myself","ourselves"],["yourself","yourselves"],["itself","themselves"],["herself","themselves"],["himself","themselves"],["themself","themselves"],["is","are"],["was","were"],["has","have"],["this","these"],["that","those"],["echo","echoes"],["dingo","dingoes"],["volcano","volcanoes"],["tornado","tornadoes"],["torpedo","torpedoes"],["genus","genera"],["viscus","viscera"],["stigma","stigmata"],["stoma","stomata"],["dogma","dogmata"],["lemma","lemmata"],["schema","schemata"],["anathema","anathemata"],["ox","oxen"],["axe","axes"],["die","dice"],["yes","yeses"],["foot","feet"],["eave","eaves"],["goose","geese"],["tooth","teeth"],["quiz","quizzes"],["human","humans"],["proof","proofs"],["carve","carves"],["valve","valves"],["looey","looies"],["thief","thieves"],["groove","grooves"],["pickaxe","pickaxes"],["passerby","passersby"]].forEach(function(e){return h.addIrregularRule(e[0],e[1])}),[[/s?$/i,"s"],[/[^\u0000-\u007F]$/i,"$0"],[/([^aeiou]ese)$/i,"$1"],[/(ax|test)is$/i,"$1es"],[/(alias|[^aou]us|t[lm]as|gas|ris)$/i,"$1es"],[/(e[mn]u)s?$/i,"$1s"],[/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i,"$1"],[/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i,"$1i"],[/(alumn|alg|vertebr)(?:a|ae)$/i,"$1ae"],[/(seraph|cherub)(?:im)?$/i,"$1im"],[/(her|at|gr)o$/i,"$1oes"],[/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i,"$1a"],[/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i,"$1a"],[/sis$/i,"ses"],[/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i,"$1$2ves"],[/([^aeiouy]|qu)y$/i,"$1ies"],[/([^ch][ieo][ln])ey$/i,"$1ies"],[/(x|ch|ss|sh|zz)$/i,"$1es"],[/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i,"$1ices"],[/\b((?:tit)?m|l)(?:ice|ouse)$/i,"$1ice"],[/(pe)(?:rson|ople)$/i,"$1ople"],[/(child)(?:ren)?$/i,"$1ren"],[/eaux$/i,"$0"],[/m[ae]n$/i,"men"],["thou","you"]].forEach(function(e){return h.addPluralRule(e[0],e[1])}),[[/s$/i,""],[/(ss)$/i,"$1"],[/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i,"$1fe"],[/(ar|(?:wo|[ae])l|[eo][ao])ves$/i,"$1f"],[/ies$/i,"y"],[/(dg|ss|ois|lk|ok|wn|mb|th|ch|ec|oal|is|ck|ix|sser|ts|wb)ies$/i,"$1ie"],[/\b(l|(?:neck|cross|hog|aun)?t|coll|faer|food|gen|goon|group|hipp|junk|vegg|(?:pork)?p|charl|calor|cut)ies$/i,"$1ie"],[/\b(mon|smil)ies$/i,"$1ey"],[/\b((?:tit)?m|l)ice$/i,"$1ouse"],[/(seraph|cherub)im$/i,"$1"],[/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i,"$1"],[/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i,"$1sis"],[/(movie|twelve|abuse|e[mn]u)s$/i,"$1"],[/(test)(?:is|es)$/i,"$1is"],[/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i,"$1us"],[/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i,"$1um"],[/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i,"$1on"],[/(alumn|alg|vertebr)ae$/i,"$1a"],[/(cod|mur|sil|vert|ind)ices$/i,"$1ex"],[/(matr|append)ices$/i,"$1ix"],[/(pe)(rson|ople)$/i,"$1rson"],[/(child)ren$/i,"$1"],[/(eau)x?$/i,"$1"],[/men$/i,"man"]].forEach(function(e){return h.addSingularRule(e[0],e[1])}),["adulthood","advice","agenda","aid","aircraft","alcohol","ammo","analytics","anime","athletics","audio","bison","blood","bream","buffalo","butter","carp","cash","chassis","chess","clothing","cod","commerce","cooperation","corps","debris","diabetes","digestion","elk","energy","equipment","excretion","expertise","firmware","flounder","fun","furniture","gallows","garbage","graffiti","hardware","headquarters","health","herpes","highjinks","homework","housework","information","jeans","justice","kudos","labour","literature","machinery","mackerel","mail","media","mews","moose","music","mud","manga","news","only","personnel","pike","plankton","pliers","police","pollution","premises","rain","research","rice","salmon","scissors","series","sewage","shambles","shrimp","software","staff","swine","tennis","traffic","transportation","trout","tuna","wealth","welfare","whiting","wildebeest","wildlife","you",/pok[eé]mon$/i,/[^aeiou]ese$/i,/deer$/i,/fish$/i,/measles$/i,/o[iu]s$/i,/pox$/i,/sheep$/i].forEach(h.addUncountableRule),h});
|
||
window.__pluralize396795627295786 = window.pluralize; // winning
|
||
delete window.pluralize;
|
||
|
||
let __pluralFormMethod = function() {
|
||
let input = this.toString();
|
||
return __pluralize396795627295786(input);
|
||
|
||
//let output = nlp(input).nouns().toPlural().out("text");
|
||
//return output === "" ? input : output; // don't add "s" by default because the lib should already do it, and sometimes plural is same as singular (e.g. furniture)
|
||
};
|
||
let __singularFormMethod = function() {
|
||
let input = this.toString();
|
||
return __pluralize396795627295786(input, 1);
|
||
|
||
// let output = nlp(input).nouns().toSingular().out("text");
|
||
// return output === "" ? input : output;
|
||
};
|
||
|
||
|
||
let nlpCompromiseAddedWords = {abolish:"Verb",abound:"Verb",abstract:"Verb",accent:"Verb",accomplish:"Verb",admonish:"Verb",alert:"Verb",ally:"Verb",appropriate:"Verb",astonish:"Verb",auction:"Verb",audition:"Verb",average:"Verb",awake:"Verb",award:"Verb",back:"Verb",backpedal:"Verb",banish:"Verb",bank:"Verb",bankrupt:"Verb",better:"Verb",bill:"Verb",blacklist:"Verb",bless:"Verb",blind:"Verb",bloody:"Verb",blossom:"Verb",board:"Verb",bob:"Verb",bombard:"Verb",bottle:"Verb",brave:"Verb",breakfast:"Verb",brief:"Verb",bus:"Verb",busy:"Verb",butcher:"Verb",butter:"Verb",cake:"Verb",calm:"Verb",captain:"Verb",care:"Verb",cash:"Verb",caution:"Verb",center:"Verb",cherish:"Verb",christen:"Verb",chronicle:"Verb",chuck:"Verb",circumvent:"Verb",clean:"Verb",clear:"Verb",club:"Verb",commission:"Verb",complete:"Verb",comply:"Verb",conceal:"Verb",condition:"Verb",content:"Verb",contrive:"Verb",cool:"Verb",correct:"Verb",corrupt:"Verb",critique:"Verb",cup:"Verb",dawn:"Verb",degenerate:"Verb",demolish:"Verb",deprive:"Verb",derive:"Verb",design:"Verb",diminish:"Verb",disable:"Verb",discard:"Verb",disregard:"Verb",don:"Verb",double:"Verb",down:"Verb",dry:"Verb",dull:"Verb",elaborate:"Verb",embellish:"Verb",empty:"Verb",engineer:"Verb",enlist:"Verb",equal:"Verb",erect:"Verb",exact:"Verb",faint:"Verb",fake:"Verb",fancy:"Verb",fine:"Verb",firm:"Verb",fish:"Verb",fit:"Verb",flatter:"Verb",flicker:"Verb",flourish:"Verb",fly:"Verb",ford:"Verb",forward:"Verb",foster:"Verb",foul:"Verb",free:"Verb",frequent:"Verb",fund:"Verb",furnish:"Verb",further:"Verb",garnish:"Verb",gossip:"Verb",grace:"Verb",grant:"Verb",ground:"Verb",group:"Verb",herald:"Verb",hoist:"Verb",hollow:"Verb",hope:"Verb",house:"Verb",hum:"Verb",humble:"Verb",ice:"Verb",impoverish:"Verb",indent:"Verb",index:"Verb",initial:"Verb",institute:"Verb",inventory:"Verb",knot:"Verb",last:"Verb",lavish:"Verb",lean:"Verb",light:"Verb",lobby:"Verb",long:"Verb",lower:"Verb",lunch:"Verb",mail:"Verb",man:"Verb",mark:"Verb",marshal:"Verb",mature:"Verb",mean:"Verb",mellow:"Verb",milk:"Verb",mimic:"Verb",mine:"Verb",model:"Verb",moderate:"Verb",motion:"Verb",mute:"Verb",narrow:"Verb",near:"Verb",nestle:"Verb",nick:"Verb",number:"Verb",nurse:"Verb",obscure:"Verb",oil:"Verb",open:"Verb",outlive:"Verb",overcrowd:"Verb",overdo:"Verb",overeat:"Verb",overflow:"Verb",overhaul:"Verb",overhear:"Verb",overheat:"Verb",overload:"Verb",overlook:"Verb",overpower:"Verb",overrule:"Verb",oversee:"Verb",overshadow:"Verb",oversleep:"Verb",overthrow:"Verb",overturn:"Verb",own:"Verb",panic:"Verb",part:"Verb",partition:"Verb",patent:"Verb",patrol:"Verb",pedal:"Verb",pepper:"Verb",perfect:"Verb",perish:"Verb",petition:"Verb",plant:"Verb",please:"Verb",ply:"Verb",police:"Verb",polish:"Verb",position:"Verb",post:"Verb",pound:"Verb",power:"Verb",press:"Verb",pressure:"Verb",prime:"Verb",pucker:"Verb",punish:"Verb",query:"Verb",quiz:"Verb",rain:"Verb",rally:"Verb",ration:"Verb",rear:"Verb",rebel:"Verb",rebound:"Verb",refurbish:"Verb",relish:"Verb",repeal:"Verb",replenish:"Verb",requisition:"Verb",research:"Verb",reserve:"Verb",rev:"Verb",revive:"Verb",right:"Verb",ring:"Verb",rival:"Verb",round:"Verb",salt:"Verb",sanction:"Verb",scent:"Verb",school:"Verb",secure:"Verb",separate:"Verb",service:"Verb",shut:"Verb",signal:"Verb",silhouette:"Verb",single:"Verb",slow:"Verb",smooth:"Verb",snicker:"Verb",snow:"Verb",sour:"Verb",space:"Verb",spare:"Verb",speed:"Verb",spike:"Verb",spiral:"Verb",spy:"Verb",square:"Verb",stable:"Verb",station:"Verb",steady:"Verb",steam:"Verb",stuff:"Verb",sue:"Verb",tame:"Verb",tan:"Verb",taper:"Verb",tarnish:"Verb",tender:"Verb",tense:"Verb",thin:"Verb",thunder:"Verb",till:"Verb",time:"Verb",top:"Verb",total:"Verb",trouble:"Verb",undercut:"Verb",underline:"Verb",undertake:"Verb",undervalue:"Verb",up:"Verb",upset:"Verb",utter:"Verb",vanish:"Verb",varnish:"Verb",void:"Verb",wade:"Verb",warm:"Verb",water:"Verb",weather:"Verb",wed:"Verb",welcome:"Verb",woo:"Verb",wound:"Verb"};
|
||
let __pastTenseMethod = function() {
|
||
let word = this.toString();
|
||
if(word === "hope" || word === "hopes" || word === "hoped" || word === "hoping") return "hoped";
|
||
if(word === "bill" || word === "bills" || word === "billed" || word === "billing") return "billed";
|
||
if(word === "dawn" || word === "dawns" || word === "dawned" || word === "dawning") return "dawned";
|
||
//return nlp(this.toString(), nlpCompromiseAddedWords).sentences().toPastTense().out("text")
|
||
let out = __nlpCompromise("They "+this.toString(), nlpCompromiseAddedWords).verbs().conjugate()[0];
|
||
return out ? out.PastTense : this.toString()+"ed";
|
||
};
|
||
let __futureTenseMethod = function() {
|
||
let word = this.toString();
|
||
if(word === "hope" || word === "hopes" || word === "hoped" || word === "hoping") return "will hope";
|
||
if(word === "bill" || word === "bills" || word === "billed" || word === "billing") return "will bill";
|
||
if(word === "dawn" || word === "dawns" || word === "dawned" || word === "dawning") return "will dawn";
|
||
//return nlp(this.toString(), nlpCompromiseAddedWords).sentences().toFutureTense().out("text")
|
||
let out = __nlpCompromise("They "+this.toString(), nlpCompromiseAddedWords).verbs().conjugate()[0];
|
||
return out ? out.FutureTense : this.toString()+"ed";
|
||
};
|
||
let __presentTenseMethod = function() {
|
||
let word = this.toString();
|
||
if(word === "hope" || word === "hopes" || word === "hoped" || word === "hoping") return "hopes";
|
||
if(word === "bill" || word === "bills" || word === "billed" || word === "billing") return "bills";
|
||
if(word === "dawn" || word === "dawns" || word === "dawned" || word === "dawning") return "dawns";
|
||
//return nlp(this.toString(), nlpCompromiseAddedWords).sentences().toPresentTense().out("text")
|
||
let out = __nlpCompromise("They "+this.toString(), nlpCompromiseAddedWords).verbs().conjugate()[0];
|
||
return out ? out.PresentTense : this.toString()+"ed";
|
||
};
|
||
|
||
let __negativeFormMethod = function() {
|
||
return __nlpCompromise(this.toString()).sentences().toNegative().out("text");
|
||
};
|
||
|
||
// let ordinalMethod = function() {
|
||
// return nlp.getOrdinal(this.toString());
|
||
// };
|
||
// let withArticleMethod = function() {
|
||
// return nlp.getWithArticle(this.toString());
|
||
// };</script> <script>function __evaluateSquareBlock(root, thisRef, expression, ctxInfo={}) {
|
||
|
||
// NOTE: if the `with` keyword ever gets actually deprecated (very, very unlikely - 2ality's
|
||
// article is a bit misleading I think), you can just craft up a function declaration with each
|
||
// of the root variables so they get passed in as the evaled function's arguments (simple!)
|
||
// new Function(param1, ..., paramN, funcBody) -> http://www.2ality.com/2014/01/eval.html
|
||
// only thing is: i need to make sure the getters are still triggered on the proxy when I grab the properties (why wouldn't they be?). hmm
|
||
// oh but also I don't want to trigger ALL of them (could be a couple of thousand params for every single square bloc executed...)
|
||
|
||
let originalExpression = expression;
|
||
expression = expression.trim();
|
||
//expression = prependReturnKeywordIfNeeded(expression);
|
||
//let evalJSCode = eval.bind(thisRef);
|
||
|
||
if(window.__throwErrorIfNonDirectListReferenceIsFoundDuringEvaluateSquareBlock) {
|
||
if(!__isValidJavaScriptIdentifier(expression)) {
|
||
throw new Error("this is a harmless error - it's just used to break out of the direct-node-linking process createPerchanceTree");
|
||
}
|
||
}
|
||
|
||
// **WITHIN a node**, we don't want references to `this` to result in "$output"
|
||
// Otherwise we're very limited in terms of how we can interact with "local" items (can't use selectOne, etc. EVEN IN `$output` (since it would reference itself no matter what))
|
||
// Note that we can't just temporarily set $output to undefined, because the square block that we're evaluating could reference another list which references THIS list and expects $output to work. We only want uses of `this` in this square block (and uses of `this` within chained methods like selectOne in this example: `[this.selectOne]` - hence the need to bind functions to this proxy)
|
||
// REF:kjhfw927f63ohwkgw82g
|
||
let proxiedThisRef = undefined;
|
||
if(Object.getOwnPropertyDescriptor(thisRef, "$output")) {
|
||
|
||
proxiedThisRef = new Proxy(thisRef, {
|
||
get: function(target, property) {
|
||
if(property === "$output") {
|
||
return undefined; // <-- we pretend that this list doesn't have an $output property so that node methods like toString don't use it.
|
||
} else if(property === "___$outputShouldBeHidden") {
|
||
return true; // this is a hack to tell the consumableList proxy to hide the $output property (since we can only bind a function to one of the proxies)
|
||
} else if(property === "___proxyTarget") {
|
||
return thisRef;
|
||
} else {
|
||
|
||
let desc = Object.getOwnPropertyDescriptor(target, property);
|
||
if(!desc) {
|
||
//perchanceError(`The '${property}' property doesn't exist within '${target.$text}'.`, ctxInfo.declarationLineNumber);
|
||
return undefined;
|
||
}
|
||
|
||
if(desc.get) {
|
||
return desc.get.bind(proxiedThisRef)(); // <-- need to bind to this proxy so that the $output property is hidden from all successively chained functions - e.g. this.consumableList.selectOne.toString()
|
||
} else if(desc.value && typeof desc.value === 'function') {
|
||
return desc.value.bind(proxiedThisRef);
|
||
} else {
|
||
return target[property];
|
||
}
|
||
|
||
}
|
||
}
|
||
});
|
||
|
||
}
|
||
|
||
try {
|
||
|
||
let tempHasHandlerHolder;
|
||
if(root.___isProxy) {
|
||
tempHasHandlerHolder = root.___proxyHandler.has;
|
||
root.___proxyHandler.has = window.__rootProxyHasHandler_Greedy.bind(root.___proxyHandler);
|
||
}
|
||
window.__currentEvaluateSquareBlockRoot = root; // this is for String.prototype.evaluateItem, etc. handlers because otherwise they have no way of accessing their root if they are from an *imported* generator.
|
||
let result = (function(){ return eval("with(root){"+expression+"}"); }).apply(proxiedThisRef || thisRef); // NOTE: we can't change this to `with(root.getSelf)` because we're using the proxy to make it so [thingThatDoesntExist] returns undefined rather than throwing a syntax error.
|
||
if(root.___isProxy) root.___proxyHandler.has = tempHasHandlerHolder; //.bind(root.___proxyHandler);
|
||
window.__currentEvaluateSquareBlockRoot = null;
|
||
|
||
if(result === undefined) {
|
||
__perchanceError(`The expression '[${__escapeHTMLSpecialChars(originalExpression)}]' returned nothing (<code>undefined</code>). You may be trying to reference a list, variable, or function that doesn't exist. Here are some common causes of this error: <ul><li>You tried to reference a list/variable that you haven't created. For example, if you wrote [animal], but there was no top-level list called "animal", then you would get this error. Note that names are <b>case-sensitive</b> - check your capitalization.</li><li>If you misspell a property/function name, then you'll get this error. For example "[noun.pluralFormm]" would produce this error because "pluralForm" has been misspelled.</li><li>If you try to access a property of an object that doesn't exist, or that evaluates to something which doesn't exist, then you'll get this error.</li></ul> These errors can sometimes be hard to debug, so after you've given it your best shot, please post a question over on the <a href="https://lemmy.world/c/perchance">perchance community</a> and a friendly community member will help you out :)`, ctxInfo);
|
||
return undefined;
|
||
} else {
|
||
if(typeof result === 'string' && String(Number(result)) === result) {
|
||
return Number(result);
|
||
} else {
|
||
return result;
|
||
}
|
||
}
|
||
} catch(e) {
|
||
if(window.__throwErrorIfNonDirectListReferenceIsFoundDuringEvaluateSquareBlock) {
|
||
throw new Error("ignore this");
|
||
}
|
||
if(e.message.toLowerCase().includes("call stack size")) {
|
||
__perchanceError(`There's a problem with the syntax of this expression: '[${__escapeHTMLSpecialChars(originalExpression)}]'. Here's the message that was returned when execution failed: <b>${__escapeHTMLSpecialChars(e.message.slice(0, 5000))}</b>. It may be that you've accidentally created an "infinite loop" by making a list reference itself, or something like that.`, ctxInfo);
|
||
} else if(e.message.toLowerCase().includes("token") && (originalExpression.includes("“") || originalExpression.includes("”"))) {
|
||
__perchanceError(`There's a problem with the syntax of this expression: '[${__escapeHTMLSpecialChars(originalExpression)}]'. Here's the message that was returned when execution failed: <b>${__escapeHTMLSpecialChars(e.message.slice(0, 5000))}</b>. It looks like you might be using "curly quotes" (like this: <code>“blah”</code>) instead of normal quotes (like this: <code>"blah"</code>)? Perchance requires that you use normal quotes for text inside square brackets (e.g. <code>[a = animal.selectOne,""]</code>).`, ctxInfo);
|
||
} else {
|
||
__perchanceError(`There's a problem with the syntax of this expression: '[${__escapeHTMLSpecialChars(originalExpression)}]'. Here's the message that was returned when execution failed: <b>${__escapeHTMLSpecialChars(e.message)}</b>. Here are some common mistakes: <ul><li>you tried to reference a variable/list that you haven't created</li><li>list names are case-sensitive: "[animal]" is different to [Animal], and you should use underscores in list names instead of spaces</li></ul>`, ctxInfo);
|
||
}
|
||
return "(syntax error)";
|
||
}
|
||
}
|
||
|
||
// function prependReturnKeywordIfNeeded(expression) {
|
||
// // if single line without return statement, add it
|
||
// if(/\n/.test(expression) || /(^|\s|;|\}|\{|\)|\()return\s/.test(expression)) {
|
||
// return expression;
|
||
// } else {
|
||
// return "return "+expression;
|
||
// }
|
||
// }
|
||
|
||
|
||
// function expressionHasSemiColon(text) {
|
||
//
|
||
// let escaped = false;
|
||
// let inJSExprString1 = false;
|
||
// let inJSExprString2 = false;
|
||
// let inJSExprString3 = false;
|
||
// let inRegExp = false;
|
||
//
|
||
// for(let i = 0; i < text.length; i++) {
|
||
// if(i !== 0) {
|
||
// if(text[i-1] !== "\\") { escaped = false; }
|
||
// }
|
||
// if(text[i] === "\\") { escaped = !escaped; }
|
||
//
|
||
// ////////////////////////////////////
|
||
// // skip regexp //
|
||
// ////////////////////////////////////
|
||
// if(!inRegExp && !inJSExprString1 && !inJSExprString2 && !inJSExprString3 && text[i] === "/") { inRegExp = true; continue; }
|
||
// if(inRegExp && text[i] !== "/") { continue; }
|
||
// if(inRegExp && !escaped && text[i] === "/") { inRegExp = false; continue; }
|
||
//
|
||
//
|
||
// ////////////////////////////////////
|
||
// // skip strings //
|
||
// ////////////////////////////////////
|
||
// if(!inJSExprString1 && !inRegExp && text[i] === "\"") { inJSExprString1 = true; continue; }
|
||
// if(inJSExprString1 && !escaped && text[i] !== "\"") { continue; }
|
||
// if(inJSExprString1 && !escaped && text[i] === "\"") { inJSExprString1 = false; continue; }
|
||
//
|
||
// if(!inJSExprString2 && !inRegExp && text[i] === "'") { inJSExprString2 = true; continue; }
|
||
// if(inJSExprString2 && !escaped && text[i] !== "'") { continue; }
|
||
// if(inJSExprString2 && !escaped && text[i] === "'") { inJSExprString2 = false; continue; }
|
||
//
|
||
// if(!inJSExprString3 && !inRegExp && text[i] === "`") { inJSExprString3 = true; continue; }
|
||
// if(inJSExprString3 && !escaped && text[i] !== "`") { continue; }
|
||
// if(inJSExprString3 && !escaped && text[i] === "`") { inJSExprString3 = false; continue; }
|
||
//
|
||
// if(!inJSExprString3 && !escaped && text[i] === "`") {
|
||
//
|
||
// if(!inJSExprString1 && !inJSExprString2 && !inJSExprString3 && !inRegExp) {
|
||
//
|
||
// }
|
||
//
|
||
// }
|
||
//
|
||
// return false;
|
||
//
|
||
// }</script> <script>// Heads up: This code is extremely messy and hacked together. Many comments are outdated.
|
||
|
||
let NODE_ODDS_INDICATOR_CHARACTER = "^";
|
||
|
||
window.__rootProxyHasHandler; // <-- gets set after rootProxy creation
|
||
window.__rootProxyHasHandler_Greedy = function(target, prop) {
|
||
if(prop in window) {
|
||
if(prop in this.executeChain(target, this.capturedCalls)) {
|
||
return true;
|
||
} else {
|
||
return false; // don't be so greedy that we steal window's props even when `window` has it and `root` doesn't.
|
||
}
|
||
} else {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
// window.globalProxyLoopCount = 0;
|
||
// function proxyLoopCountResetLoop() {
|
||
// window.globalProxyLoopCount = 0;
|
||
// setTimeout(proxyLoopCountResetLoop, 1000);
|
||
// }
|
||
// proxyLoopCountResetLoop();
|
||
|
||
function __createPerchanceTree(text, moduleName, backupModuleName /*<-- this is for the hacky node creation function*/, doNotPreprocess) {
|
||
|
||
const functionStartTime = Date.now();
|
||
|
||
/*
|
||
There are two main steps in creating the tree:
|
||
1. We split up the text into lines and collect all the data we need about each line (e.g. odds, line number, etc.) and tidy it up as necessary (e.g. .trim() it, or remove it completely if it's a comment). Then we group sets of lines that are below a function header into said function header. We create all the parent/child hierarchy links along the way.
|
||
2. We turn all that node data into a neat "perchance tree" which has the properties required to make the DSL work nicely, and we attach all the perchance methods to each node. Then we return the root node in this tree.
|
||
*/
|
||
|
||
// remove inline comments
|
||
let lines = text.replace(/\r/g,"").split("\n");
|
||
const commentRegex = /\/\//;
|
||
for(let i = 0; i < lines.length; i++) {
|
||
if(!commentRegex.test(lines[i])) continue; // <-- just an optimisation
|
||
lines[i] = __stripCommentFromLine(lines[i]);
|
||
}
|
||
|
||
// *trim* EMPTY lines (otherwise whitespace can throw indentation error in next step)
|
||
// we need to keep blank lines so line numbers are preserved. they're removed in a bit
|
||
lines = lines.map(text => /[^\s]/.test(text) ? text : text.trim());
|
||
|
||
// mixed spaces and tabs -> only tabs
|
||
for(let i = 0; i < lines.length; i++) {
|
||
let normed = __normaliseLineIndentsToTabs(lines[i]);
|
||
if(normed === false) {
|
||
__perchanceError(`There appears to be an indenting error on this line near this text: "${__escapeHTMLSpecialChars(lines[i].substr(0,30))}". Perchance lists should be indented with either one tab or two spaces (per nesting level). If you want to have a space before a list item, then you should start the item with "\\s" (backslash + "s") which will be converted into a space (you can read more about this in the <a href="/tutorial">tutorial</a>).`, {declarationLineNumber:i+1, moduleName});
|
||
return;
|
||
} else {
|
||
lines[i] = normed;
|
||
}
|
||
}
|
||
|
||
// make lines objects
|
||
for(let i = 0; i < lines.length; i++) {
|
||
lines[i] = {
|
||
text: lines[i],
|
||
indents: lines[i].search(/[^\t]/), //index of first non-tab
|
||
lineNumber:i+1, // plus one because line num start at 1 by convention
|
||
children:[],
|
||
parent: null,
|
||
// REMEMBER: if you add anything here you need to add it to root line bject and line objects created in inline declarations
|
||
}
|
||
lines[i].text = lines[i].text.trim(); //trim away indents and end whitespace
|
||
}
|
||
|
||
// remove blank lines, but keep track of them via a reference from the line above (which works fine for successive blank lines), so we can add them back for function bodies (since e.g. in multi-line string the blank lines matter)
|
||
lines = lines.filter((l, i) => {
|
||
if(l.text === "") {
|
||
if(lines[i-1]) lines[i-1].blankLineBelow = l;
|
||
return false;
|
||
} else {
|
||
return true;
|
||
}
|
||
});
|
||
|
||
// create parent-child hierarchy
|
||
let root = {
|
||
text:"<root>",
|
||
indents:-1,
|
||
lineNumber:-1,
|
||
children:[],
|
||
parent: null,
|
||
nodeType: "text",
|
||
odds: "1",
|
||
perchanceCode:"",
|
||
//expressionArray: ["<root>"],
|
||
};
|
||
let indentOwners = {0:root}; // maps # indents of current line to correct parent
|
||
for(let i = 0; i < lines.length; i++) {
|
||
let line = lines[i];
|
||
let indents = line.indents;
|
||
if(indentOwners[indents]) {
|
||
// this is child of indentOwners[indents]:
|
||
indentOwners[indents].children.push(line);
|
||
line.parent = indentOwners[indents];
|
||
// this becomes owner of next indent level:
|
||
indentOwners[indents+1] = line;
|
||
// and *no one* owns the indent level after that:
|
||
indentOwners[indents+2] = undefined;
|
||
} else {
|
||
__perchanceError(`There appears to be an indenting error on this line near this text: "${__escapeHTMLSpecialChars(line.text.substr(0,30))}". Perchance lists should be indented with either one tab or two spaces. If you want to have a space before a list item, then you should start the item with "\\s" (backslash + "s") which will be converted into a space (you can read more about this in the <a href="/tutorial">tutorial</a>).`, {declarationLineNumber:line.lineNumber, moduleName});
|
||
return;
|
||
}
|
||
}
|
||
|
||
// for each node, get the perchance text required to create it.
|
||
for(let i = 0; i < lines.length; i++) {
|
||
// for each line (ordered top to bottom)...
|
||
lines[i].perchanceCode = lines[i].text;
|
||
let j = 0;
|
||
let parent = lines[i].parent;
|
||
let ancestor = parent;
|
||
// append this line's text to *all* ancestors of this line (with appropriate indentation):
|
||
while(1) {
|
||
|
||
if(ancestor.parent === null) ancestor.perchanceCode += `${ancestor.perchanceCode ? "\n" : ""}` + lines[i].text; // handle case where ancestor === root node
|
||
else ancestor.perchanceCode += "\n" + " ".repeat(lines[i].indents - ancestor.indents) + lines[i].text;
|
||
|
||
// EDIT: we also need to add blank lines back in because they matter e.g. for multi-line strings in function bodies:
|
||
let blankLine = lines[i].blankLineBelow;
|
||
while(blankLine) {
|
||
ancestor.perchanceCode += "\n";
|
||
blankLine = blankLine.blankLineBelow;
|
||
}
|
||
|
||
ancestor = ancestor.parent;
|
||
if(!ancestor) break;
|
||
|
||
if(j++ > 100000) {
|
||
__perchanceError(`Some sort of looping/recursion error has occurred. Please make a post on the forum (lemmy.world/c/perchance) so I can take a look at this. Thanks!`, {moduleName});
|
||
return;
|
||
}
|
||
|
||
}
|
||
}
|
||
root.perchanceCode = text;
|
||
|
||
// check for variable names wrapped in square brackets when they're already within a square block:
|
||
const unnecessarySquareBracketsRegex = /([^\\]|^)\[([^\]]*?[^a-zA-Z0-9_$\]]|)\[[a-zA-Z0-9_$.]+?\][^\]]*?\]/;
|
||
// above regex explained:
|
||
// - we need the [^a-zA-Z_$\]] part (character right before inner square brackets must not be a variable-name character) because we don't want to show a warning for `[myList[key]]`, for example.
|
||
// - we need the dot in [a-zA-Z_$.]+ because we of course want to be able to detect and warn about something like `[a > 7 ? [list.subProp] : "blah"]`
|
||
// - this doesn't handle escaping properly (because the preceding backslash could itself be escaped), and doesn't properly handle the fact that square brackets could occur within strings/regex/etc. that are within the outer square block
|
||
const singleEqualsInDynamicOddsRegex = /\^\[[^\]]*[^=!<>]=[^=>][^\]]*\]\s*$/;
|
||
const singleEqualsInIfElseConditionRegex = /\[if\s*\([^\)]*[^=><!]=[^=>][^\)]*\)\s*\{/;
|
||
for(let i = 0; i < lines.length; i++) {
|
||
if(lines[i].text.length > 5000) continue;
|
||
if(lines[i].text.indexOf("[") === -1) continue; // <-- just an optimisation
|
||
|
||
// unnecessary square brackets:
|
||
if(lines[i].text.indexOf("\"") !== -1 || lines[i].text.indexOf("'") !== -1 || lines[i].text.indexOf("'") !== -1) {
|
||
if(lines[i].text.match(unnecessarySquareBracketsRegex)) { // don't use .test() --> https://stackoverflow.com/a/21373261/11950764
|
||
// try removing quoted parts to see if it's still a match (very hacky, but it's not a huuge deal if it causes us to miss some - it's better than false positives):
|
||
let newText = lines[i].text;
|
||
newText = newText.replace(/".*[^\\]?"/g, `""`);
|
||
newText = newText.replace(/`.*[^\\]?`/g, "``");
|
||
newText = newText.replace(/'.*[^\\]?'/g, `''`);
|
||
if(newText.match(unnecessarySquareBracketsRegex)) { // if it still matches, then it's ~likely a true positive.
|
||
window.codeWarningsArray.push({lineNumber:lines[i].lineNumber, generatorName:moduleName, warningId:"square-brackets-wrapping-variable-name-within-square-block"});
|
||
}
|
||
}
|
||
} else {
|
||
if(lines[i].text.match(unnecessarySquareBracketsRegex)) {
|
||
window.codeWarningsArray.push({lineNumber:lines[i].lineNumber, generatorName:moduleName, warningId:"square-brackets-wrapping-variable-name-within-square-block"});
|
||
}
|
||
}
|
||
|
||
if(lines[i].text.match(singleEqualsInIfElseConditionRegex)) {
|
||
window.codeWarningsArray.push({lineNumber:lines[i].lineNumber, generatorName:moduleName, warningId:"single-equals-in-if-else-condition"});
|
||
}
|
||
|
||
// single equals in dynamic odds
|
||
if(lines[i].text.indexOf("^[") === -1) continue; // <-- just an optimisation
|
||
if(lines[i].text.match(singleEqualsInDynamicOddsRegex)) {
|
||
window.codeWarningsArray.push({lineNumber:lines[i].lineNumber, generatorName:moduleName, warningId:"single-equals-in-dynamic-odds"});
|
||
}
|
||
}
|
||
|
||
// get node data for functions (pack all details into header node and remove children)
|
||
// note that we need to handle functions first because otherwise lines of js will be
|
||
// classed as other node types
|
||
for(let i = 0; i < lines.length; i++) {
|
||
let funcHeaderDetails = __getFunctionHeaderDetails(lines[i].text);
|
||
if(funcHeaderDetails) {
|
||
lines[i].nodeType = "function";
|
||
|
||
lines[i].functionName = funcHeaderDetails.name;
|
||
lines[i].functionArgs = funcHeaderDetails.args; // <-- array of arg names
|
||
lines[i].functionIsAsync = funcHeaderDetails.isAsync;
|
||
// recursively collect all children, grandchildren, etc into one flat array:
|
||
let children = lines[i].children;
|
||
let j = 0;
|
||
while(1) {
|
||
if(j >= children.length) { break; }
|
||
let c = children[j];
|
||
children.splice(j+1, 0, ...c.children); // must put them in correct pos
|
||
j++;
|
||
}
|
||
// remove children/grandchildren/... from lines array:
|
||
for(let c of children) {
|
||
lines = lines.filter(l => l !== c);
|
||
}
|
||
|
||
// concat children/grandchildren/... with newlines and add to functionBody property
|
||
lines[i].functionBody = children.map(l => {
|
||
let text = l.text;
|
||
|
||
// add black lines back in since they matter for e.g. multi-line strings:
|
||
let blankLine = l.blankLineBelow;
|
||
while(blankLine) {
|
||
text += "\n";
|
||
blankLine = blankLine.blankLineBelow;
|
||
}
|
||
|
||
return text;
|
||
}).join("\n");
|
||
|
||
// remove children
|
||
lines[i].children = [];
|
||
}
|
||
}
|
||
|
||
// get node data for inline functions
|
||
const functionNodeRegex = /=>/;
|
||
for(let i = 0; i < lines.length; i++) {
|
||
if(lines[i].nodeType) continue;
|
||
if(!functionNodeRegex.test(lines[i].text)) continue; // <-- just an optimisation
|
||
let inlineFuncDetails = __getInlineFunctionDetails(lines[i].text);
|
||
if(inlineFuncDetails) {
|
||
lines[i].nodeType = "function";
|
||
|
||
// inline functions shouldn't have children
|
||
if(lines[i].children.length > 0) {
|
||
__perchanceError(`It appears that you've tried to give an inline function children (child items). At this point, inline functions are not allowed to have children (though I could change this in the future if people need this feature). There's also the possibility that you accidentally created an inline function. Inline functions have the form: <b>functionName(input1, input2, ...) => functionBody</b>. If you'd like to use "=" in a literal sense, put a backslash character right before it like this: "\\=".`, {declarationLineNumber:lines[i].lineNumber, moduleName});
|
||
return;
|
||
}
|
||
|
||
lines[i].functionName = inlineFuncDetails.name;
|
||
lines[i].functionArgs = inlineFuncDetails.args; // <-- array of arg names
|
||
lines[i].functionBody = inlineFuncDetails.body;
|
||
lines[i].functionIsAsync = inlineFuncDetails.isAsync;
|
||
}
|
||
}
|
||
|
||
|
||
// TODO: process other node-types (list with args) here
|
||
|
||
|
||
const unescapedEqualsSignSpecialCharsRegex = /[!"\#%&'()*+,.\/:;<>?@\[\\\]^‘{|}~]/;
|
||
const unescapedEqualsSignHtmlElement = /<[a-zA-Z]+ /;
|
||
const unescapedEqualsSignUrl = /https?:\/\/[^ ]+\?/;
|
||
|
||
const primitiveNodeRegex = /=/;
|
||
let ignoreEqualsSignWarnings = false;
|
||
let reenableEqualsSignWarningsAtIndentLevel = null;
|
||
for(let i = 0; i < lines.length; i++) {
|
||
if(reenableEqualsSignWarningsAtIndentLevel !== null && lines[i].indents <= reenableEqualsSignWarningsAtIndentLevel) {
|
||
ignoreEqualsSignWarnings = false;
|
||
reenableEqualsSignWarningsAtIndentLevel = null;
|
||
}
|
||
|
||
if(lines[i].nodeType) continue;
|
||
if(!primitiveNodeRegex.test(lines[i].text)) continue; // <-- just an optimisation
|
||
|
||
let details = __getPrimitiveNodeDetails(lines[i].text);
|
||
if(details) {
|
||
// NOTE: We've discovered an inline/"primitive" thing, but here's the thing:
|
||
// If it's not a direct reference (i.e. value !== "[...]" or "{...}")
|
||
// but it DOES contain square/curly block(s), then we need to make it
|
||
// into a normal node with details.value as a child.
|
||
// See marker odj29hfi3j0d2kj0hx24f for the handling of $value nodes.
|
||
// The reason we need to do this is because if we had ``output = [prefix]-blah` (for example)
|
||
// then we couldn't call `output.selectMany(3)` on it if it was a $value node.
|
||
// Basically, the fact that I want to be able to create "direct references" with
|
||
// value nodes means a bunch of mucking around trying to make everything else work
|
||
// as expected.
|
||
// let blocks = splitTextAtAllBlocks(details.value);
|
||
// if(blocks.length > 1) {
|
||
// lines[i].nodeType = "text";
|
||
// lines[i].text = details.key;
|
||
// //lines[i].expressionArray = [details.key];
|
||
// let child = {
|
||
// text: details.value,
|
||
// indents: lines[i].indents+1,
|
||
// lineNumber:lines[i].lineNumber,
|
||
// children:[],
|
||
// parent: lines[i],
|
||
// nodeType:"text",
|
||
// odds:"1",
|
||
// //expressionArray: splitTextAtSquareBlocks(details.value),
|
||
// }
|
||
// lines[i].children.push(child);
|
||
// lines.splice(i+1, 0, child);
|
||
// } else {
|
||
lines[i].nodeType = "primitiveKeyValue";
|
||
lines[i].primitiveKey = details.key;
|
||
lines[i].primitiveValue = details.value;
|
||
|
||
if(!ignoreEqualsSignWarnings && typeof details.value === "string" && details.value.startsWith("[this.getRawListText")) {
|
||
ignoreEqualsSignWarnings = true;
|
||
reenableEqualsSignWarningsAtIndentLevel = lines[i].indents-1;
|
||
}
|
||
|
||
if(!ignoreEqualsSignWarnings) {
|
||
// NOTE: these if conditions have seemingly-redundant .includes(...) at the start as an optimization - may actually slow things down though, haven't tested
|
||
// warn if key contains space AND previous line was a normal item in the same list. So users can avoid this warning by putting all their properties (that have spaces in their key) at the top of the list.
|
||
if(details.key.trim().includes(" ") && lines[i-1] && lines[i-1].primitiveKey === undefined && lines[i-1].indents === lines[i].indents) {
|
||
window.codeWarningsArray.push({lineNumber:lines[i].lineNumber, generatorName:moduleName, warningId:"unescaped-equals-sign"});
|
||
} else if(details.key.includes("<") && unescapedEqualsSignHtmlElement.test(details.key) && (details.value.trim().startsWith(`"`) || details.value.trim().startsWith(`'`))) { // also warn if it looks like e.g. <img src="..."
|
||
window.codeWarningsArray.push({lineNumber:lines[i].lineNumber, generatorName:moduleName, warningId:"unescaped-equals-sign"});
|
||
} else if(details.key.includes("?") && unescapedEqualsSignUrl.test(details.key)) { // also warn if it looks like e.g. https://example.com?foo=bar
|
||
window.codeWarningsArray.push({lineNumber:lines[i].lineNumber, generatorName:moduleName, warningId:"unescaped-equals-sign"});
|
||
}
|
||
}
|
||
/* else if(unescapedEqualsSignSpecialCharsRegex.test(details.key)) { // also warn if key has weird/special characters. This catches e.g. <img src="..." even if it's the first item in the list (which would prevent above case from catching it)
|
||
window.codeWarningsArray.push({lineNumber:lines[i].lineNumber, generatorName:moduleName, warningId:"unescaped-equals-sign"});
|
||
}*/
|
||
//}
|
||
}
|
||
|
||
}
|
||
|
||
// extract all the node data (odds, expression array) for plain old text nodes
|
||
const oddsDetailsRegex = /\^/;
|
||
for(let i = 0; i < lines.length; i++) {
|
||
if(lines[i].nodeType) continue;
|
||
if(!oddsDetailsRegex.test(lines[i].text)) { // <-- just an optimisation
|
||
lines[i].odds = "1"; // as string because all the others are strings - system is built to take strings and interpret them as expresions/numbers
|
||
} else {
|
||
// extract and remove odds stuff first:
|
||
let oddsDetails = __getTextOddsDetails(lines[i].text);
|
||
let odds, textWithoutOdds;
|
||
if(oddsDetails) {
|
||
lines[i].nodeType = "text";
|
||
lines[i].odds = oddsDetails.odds;
|
||
lines[i].text = oddsDetails.textWithoutOdds.trim(); // <-- NOTE: spaces between end of text and odds notation are ignored in lists! thus we trim. (not in curly "or" blocks though)
|
||
} else {
|
||
lines[i].odds = "1"; // as string because all the others are strings - system is built to take strings and interpret them as expresions/numbers
|
||
}
|
||
}
|
||
|
||
lines[i].nodeType = "text";
|
||
// let arr = splitTextAtSquareBlocks(lines[i].text);
|
||
// if(arr) {
|
||
// lines[i].nodeType = "text";
|
||
// lines[i].expressionArray = arr;
|
||
// // if((lines[i].expressionArray.length > 1 || (lines[i].expressionArray.length === 1 && lines[i].expressionArray[0][0] === "[")) && lines[i].children.length > 0) {
|
||
// // console.error(`Error on line number ${lines[i].lineNumber}. Lines with random variables shouldn't have children.`);
|
||
// // return;
|
||
// // }
|
||
// }
|
||
|
||
// if(oddsDetails && !arr) {
|
||
// perchanceError(`It seems that you've got a '^' character where it shouldn't be. The '^' character is a special one that allows you to specify how likely a node is of being selected. This "odds notation" should not be present on functions or other non-text nodes because they aren't a part of the group which is randomly selected from (they are special children). If you want to use the odds character ("^") literally (i.e. not to declare likelihood), then you can put a backslash character before it like so: \\^`, lines[i].lineNumber);
|
||
// return;
|
||
// }
|
||
|
||
}
|
||
|
||
// // warn for unclassified lines and then set nodeType as "text"
|
||
// for(let i = 0; i < lines.length; i++) {
|
||
// if(!lines[i].nodeType) {
|
||
// perchanceError(`For some reason this line could not be classified properly. There may be something wrong with your syntax of this line, or it may be a bug with the Perchance engine. If you think that there's a bug, please report it here: <a href="http://reddit.com/r/perchance">reddit.com/r/perchance</a>. That would be very much appreciated! :)`, lines[i].lineNumber);
|
||
// lines[i].nodeType = "text";
|
||
// lines[i].expressionArray = [lines[i].text];
|
||
// }
|
||
// }
|
||
|
||
|
||
// next up, construct the actual perchance node tree.
|
||
// first create a node for each line
|
||
// then connect up parent/children
|
||
//
|
||
// we also the perchance methods including the .toString() function to each node.
|
||
// the toString function is where the magic happens. calling
|
||
// [myrootvar] will just return the myrootvar variable. when this
|
||
// gets joined to a string, `myrootvar.toString()` is called which
|
||
// recursively resolves it into an actual string value, taking into
|
||
// account odds and other expressions (in expressionArrays) that it
|
||
// finds along the way
|
||
|
||
|
||
// 1. convert lines to perchance nodes
|
||
let allNodes = [];
|
||
lines.unshift(root);
|
||
for(let i = 0; i < lines.length; i++) {
|
||
|
||
lines[i].node = {};
|
||
|
||
lines[i].node[Symbol.for("node data")] = { // TODO: why use symbol? just put it in a non-enumerable $data property? then fix up all references to it? TODO: can this be deleted after we're done creating tree?
|
||
parentNode:null,
|
||
childNodes:[],
|
||
root:root,
|
||
declarationLineNumber: lines[i].lineNumber,
|
||
odds: null,
|
||
};
|
||
|
||
// make default function properties writable (not needed because we use simple objects now)
|
||
// Object.defineProperty(lines[i].node, "name", {writable:true});
|
||
// Object.defineProperty(lines[i].node, "length", {writable:true});
|
||
|
||
// NOTE TO SELF: Object.defineProperty seems to cause some bad performance slow-downs, but I'm pretty sure
|
||
// we need to make these properties non-enumerable - at least, I think that was the original idea. Might be worth
|
||
// thinking about this at some point because the perf gains are definitely significant if you can somehow avoid defineProperty.
|
||
|
||
Object.defineProperty(lines[i].node, "$root", {value:root.node, writable:true, configurable:true});
|
||
Object.defineProperty(lines[i].node, "$declarationLineNumber", {value:lines[i].lineNumber, writable:true, configurable:true});
|
||
Object.defineProperty(lines[i].node, "$moduleName", {value:moduleName, writable:true, configurable:true});
|
||
Object.defineProperty(lines[i].node, Symbol.toPrimitive, {value:function(hint) {
|
||
return this.valueOf();
|
||
// if(hint === "default" || hint === "string") {
|
||
// return this.toString();
|
||
// } else {
|
||
// return this.valueOf();
|
||
// }
|
||
}, writable:true, configurable:true});
|
||
|
||
// add $valueChildren array which contains all children of type 'value' so we can get the "properties" of a node (for stuff like 'generateInstance' plugin or build-in feature)
|
||
Object.defineProperty(lines[i].node, "$valueChildren", {value:[], writable:true, configurable:true});
|
||
|
||
// this is used in isFunctionNode in the proxy stuff:
|
||
Object.defineProperty(lines[i].node, "$functionChildren", {value:[], writable:true, configurable:true});
|
||
|
||
Object.defineProperty(lines[i].node, "$allKeys", {value:[], writable:true, configurable:true});
|
||
Object.defineProperty(lines[i].node, "$allKeysSet", {value:new Set(), writable:true, configurable:true});
|
||
|
||
Object.defineProperty(lines[i].node, "$perchanceCode", {value:lines[i].perchanceCode, writable:true, configurable:true});
|
||
|
||
__addNodeMethods(lines[i].node);
|
||
|
||
allNodes.push(lines[i].node);
|
||
|
||
}
|
||
|
||
// 2. fill in parent/child references:
|
||
for(let i = 0; i < lines.length; i++) {
|
||
let node = lines[i].node;
|
||
let nodeData = node[Symbol.for("node data")];
|
||
if(i === 0) { // i.e. if root - (since root has no parent)
|
||
nodeData.parentNode = null;
|
||
Object.defineProperty(node, "$parent", {value:null, writable:true, configurable:true});
|
||
} else {
|
||
nodeData.parentNode = lines[i].parent.node;
|
||
Object.defineProperty(node, "$parent", {value:lines[i].parent.node, writable:true, configurable:true}); // <-- give it a public reference to its parent that *isn't* enumerable
|
||
}
|
||
nodeData.childNodes = lines[i].children.map(line => line.node);
|
||
}
|
||
|
||
// 3. fill in the rest of the node details depending on the node type
|
||
let alreadyWarnedAboutDuplicateTopLevelListNameCount = 0;
|
||
for(let i = 0; i < lines.length; i++) {
|
||
let node = lines[i].node;
|
||
let nodeData = lines[i].node[Symbol.for("node data")];
|
||
|
||
// add normal text nodes
|
||
if(lines[i].nodeType === "text") {
|
||
nodeData.type = "text";
|
||
nodeData.odds = lines[i].odds;
|
||
//nodeData.expressionArray = lines[i].expressionArray;
|
||
|
||
Object.defineProperty(lines[i].node, "$nodeType", {value:"normal", writable:true, configurable:true});
|
||
Object.defineProperty(lines[i].node, "$oddsText", {value:lines[i].odds, writable:true, configurable:true});
|
||
|
||
Object.defineProperty(lines[i].node, "$text", {value:lines[i].text, writable:true, configurable:true}); // <-- give it a public reference to its text that *isn't* enumerable
|
||
if(node.$parent) { // i.e. if not root
|
||
let key = node.$text;
|
||
// while(node.$parent[key] !== undefined) {// if there's already one called this, add {|} (hacky, but I think it's fine since they're just text nodes?)
|
||
while(node.$parent.$allKeysSet.has(key)) { // if there's already one called this, add {|} (hacky, but I think it's fine since they're just text nodes?)
|
||
key += "{|}";
|
||
|
||
if(alreadyWarnedAboutDuplicateTopLevelListNameCount < 3 && node.$parent.$parent === null) {
|
||
window.codeWarningsArray.push({lineNumber:lines[i].lineNumber, generatorName:moduleName, warningId:"duplicate-top-level-list-name"});
|
||
alreadyWarnedAboutDuplicateTopLevelListNameCount++;
|
||
}
|
||
}
|
||
node.$parent[key] = node; // not via defineProperty, therefore it's enumerable
|
||
nodeData.parentNode.$allKeys.push(key);
|
||
nodeData.parentNode.$allKeysSet.add(key);
|
||
}
|
||
|
||
}
|
||
|
||
// add user-defined functions
|
||
if(lines[i].nodeType === "function") {
|
||
nodeData.type = "function";
|
||
nodeData.functionName = lines[i].functionName;
|
||
nodeData.functionArgs = lines[i].functionArgs;
|
||
nodeData.functionBody = lines[i].functionBody;
|
||
nodeData.functionIsAsync = lines[i].functionIsAsync;
|
||
//let withStr = `window.root.$imports.includes("${moduleName}") ? window.root.$imports[window.root.$imports.indexOf("${moduleName}")] : window.root`;
|
||
let moduleRefStr = `window.moduleSpace["${moduleName || backupModuleName}"]`;
|
||
let finalFunctionBody = `
|
||
let tempHasHandlerRememberer927394 = ${moduleRefStr}.___proxyHandler.has;
|
||
${moduleRefStr}.___proxyHandler.has = window.__rootProxyHasHandler; /* .bind(${moduleRefStr}.___proxyHandler); */
|
||
|
||
|
||
${nodeData.functionArgs.map(a => __isValidJavaScriptIdentifier(a) ? `if(${a} && ${a}.getSelf) ${a} = ${a}.getSelf;` : '').join("")}
|
||
|
||
// make a proxy for the module so we can "exclude" this function's inputs from the "with" statement.
|
||
// this allows us to have inputs that are the same name as module globals and they won't be "overwritten" by those globals.
|
||
// I had to add the Number stuff because my numbers were acting funny after messing with their prototype: https://stackoverflow.com/questions/52580398/why-doesnt-new-arraynew-number3-produce-an-array-of-length-3 (edit: originally had just !isNaN(a), but I had to add the toPrecision and $nodeType type stuff because isNaN was executing valueOf on list objects/nodes, which obviously causes trouble)
|
||
let moduleRefProxy = new Proxy(${moduleRefStr}.___proxyTarget.obj, {
|
||
get: function(target, name) {
|
||
if(false) {} // <-- just to make the next line easier to write
|
||
${nodeData.functionArgs.map(a => { a = a.split("=")[0]; if(a.startsWith("...")) { a = a.slice(3); } return `else if (name === "${a}") { return typeof ${a} !== "undefined" && typeof ${a} !== "object" && !${a}.$nodeType && ${a}.toPrecision && ${a}.toExponential && !isNaN(${a}) ? Number(${a}) : ${a}; }` }).join("\n")}
|
||
/*else if (name === "b") { return 10; }*/
|
||
else { return target[name]; }
|
||
}
|
||
});
|
||
|
||
let returnValue;
|
||
with(moduleRefProxy) {
|
||
let root = ${moduleRefStr}.___proxyTarget.obj; // <-- because for some reason 'root' was referencing window.root (which is different to this modules root if this is an imported module) 💕
|
||
returnValue = (${nodeData.functionIsAsync ? "async " : ""}function(${nodeData.functionArgs.join(",")}) {
|
||
${nodeData.functionBody}
|
||
}).apply(this, [${nodeData.functionArgs.join(",")}]);
|
||
}
|
||
|
||
${moduleRefStr}.___proxyHandler.has = tempHasHandlerRememberer927394;
|
||
return returnValue;
|
||
`;
|
||
try {
|
||
if(nodeData.functionIsAsync) {
|
||
// Note: I don't think we actually need to make the "outer" function async, since it will always return a promise (made by the inner async function). But doing it anyway in case people try to write code like `myCoolFunction.constructor.name === "AsyncFunction"` or something.
|
||
let AsyncFunction = (async function () {}).constructor;
|
||
nodeData.functionRef = new AsyncFunction(nodeData.functionArgs.join(","), finalFunctionBody).bind(nodeData.parentNode);
|
||
} else {
|
||
nodeData.functionRef = new Function(nodeData.functionArgs.join(","), finalFunctionBody).bind(nodeData.parentNode);
|
||
}
|
||
} catch(e) {
|
||
console.error(e);
|
||
__perchanceError(`There appears to be a syntax error in the function called '${nodeData.functionName}'. Here's the error message: "${e.message}".`, {declarationLineNumber:lines[i].lineNumber, moduleName});
|
||
throw new Error(e);
|
||
}
|
||
//nodeData.parentNode[nodeData.functionName] = new Function(nodeData.functionArgs.join(","), nodeData.functionBody).bind(nodeData.parentNode);
|
||
Object.defineProperty(lines[i].node, "$nodeType", {value:"function", writable:true, configurable:true});
|
||
Object.defineProperty(nodeData.parentNode, nodeData.functionName, {value:nodeData.functionRef, writable:true, configurable:true});
|
||
Object.defineProperty(lines[i].node, "$text", {value:nodeData.functionName, writable:true, configurable:true});
|
||
Object.defineProperty(lines[i].node, "$function", {value:nodeData.functionRef, writable:true, configurable:true});
|
||
|
||
nodeData.parentNode.$functionChildren.push(lines[i].functionName);
|
||
nodeData.parentNode.$allKeys.push(lines[i].functionName);
|
||
nodeData.parentNode.$allKeysSet.add(lines[i].functionName);
|
||
|
||
}
|
||
|
||
if(lines[i].nodeType === "primitiveKeyValue") {
|
||
nodeData.type = "primitiveKeyValue";
|
||
nodeData.primitiveKey = lines[i].primitiveKey;
|
||
nodeData.primitiveValue = lines[i].primitiveValue;
|
||
// NOTE: it appears that then we write "[apple*10]" where apple={1|2|3}, JS implicitely calls toString on apple (even though it's a multiplication operation). so we don't need to worry about implementing valueOf
|
||
//node.$value = lines[i].primitiveValue;
|
||
//node.$key = lines[i].primitiveKey;
|
||
let value = lines[i].primitiveValue;
|
||
|
||
// if it's just plain text, process escaped characters (remove backslashes)
|
||
// EDIT: NO! That's a terrible idea. Why remove escaped characters?! If you do, `output = \[wassup\]` throws an error (obviously). Was there a reason I previously thought this was a good idea?
|
||
if(typeof value === 'string') {
|
||
let split = __splitTextAtAllBlocks(value, {declarationLineNumber:lines[i].lineNumber});
|
||
if(typeof value === 'string' && split.length === 1 && split[0][0] !== "[" && split[0][0] !== "{") { // only need to check start bracket because it it exists, then it is unescaped, then the last character *must* be a closing bracket (since splitted text array has length of 1) else the first bracket would be unclosed
|
||
//value = processEscapedCharacters(value);
|
||
Object.defineProperty(lines[i].node, "$isPlainPrimitive", {value:true, writable:true, configurable:true});
|
||
}
|
||
} else if(typeof value === "number" || typeof value === "boolean") {
|
||
Object.defineProperty(lines[i].node, "$isPlainPrimitive", {value:true, writable:true, configurable:true});
|
||
} else {
|
||
throw new Error("unknown primitive type??");
|
||
}
|
||
|
||
Object.defineProperty(lines[i].node, "$value", {value:value, writable:true, configurable:true});
|
||
Object.defineProperty(lines[i].node, "$key", {value:lines[i].primitiveKey, writable:true, configurable:true});
|
||
//Object.defineProperty(nodeData.parentNode, lines[i].primitiveKey, {value:node, writable:true, configurable:true});
|
||
|
||
// Just to be helpful:
|
||
if(typeof nodeData.primitiveValue === "string" && nodeData.parentNode === nodeData.root.node && nodeData.primitiveKey === "$output" && nodeData.primitiveValue.substr(1, nodeData.primitiveValue.length-2).trim() === "this") {
|
||
__perchanceError("The generator called <code><a href='/"+moduleName+"#edit'>"+moduleName+"</a></code> has <code>$output</code> set to <code>[this]</code>. Perchance does this by default, so this line should be removed. That is, if you don't specify a top-level <code>$output</code> (the list you want to export) for your generator, then Perchance will export your <i>whole hierarchy</i>.", {declarationLineNumber:nodeData.declarationLineNumber, moduleName});
|
||
return;
|
||
}
|
||
|
||
Object.defineProperty(nodeData.parentNode, lines[i].primitiveKey, {
|
||
get:function() {
|
||
// MARKER:odj29hfi3j0d2kj0hx24f
|
||
if(node.$isPlainPrimitive) {
|
||
// When a user writes `thing.prop` we want them to be able to access the proper string (with escape chars removed), but the problem
|
||
// is that we use this same getter in the evaluateText process, and we definitely don't want to remove escapes during that process
|
||
// because it gets recursively evaluated so we'd be removing backslashes and evaluating blocks that should be evaluated. The toString
|
||
// method also had this problem, but I solved it by passing in a {keepEscapes:true} object when it is used in the evaluateText process,
|
||
// but since this is a getter, we can't pass in arguments, so I've used mega hax to do it (use global var). See the evaluateText function
|
||
// file for the actual location where this var is altered. It should always be false except for when it is used during the evaluateText process.
|
||
if(typeof node.$value === "string" && !window.__primitiveValueGetterKeepEscapesYolo) return __processEscapedCharacters(node.$value);
|
||
else return node.$value;
|
||
}
|
||
if(typeof node.$value === 'number') {
|
||
return node.$value;
|
||
} else if(typeof node.$value === 'string') {
|
||
|
||
// EDIT: (7th Aug 2019), realised due to [this post](https://www.reddit.com/r/perchance/comments/cmlfqh/imported_expression_returns_undefined/)
|
||
// that they can have something like:
|
||
// name = BATMAN
|
||
// $output
|
||
// n = ["[name]"]
|
||
// and the IMPORTING generator's `name` variable will be used instead, since we're only resolving the first "layer" of square brackets. If the
|
||
// getter returns a string, I'm pretty sure it should be a FULLY RESOLVED string (otherwise why resolve the first layer at all?). If you really do
|
||
// want to pass around unresolved strings, then you're probably a pro and you know how to use functions and stuff.
|
||
// example:
|
||
// imported: https://perchance.org/imported-2324234#edit
|
||
// importer: https://perchance.org/importing-93845793#edit
|
||
let ctxInfo = {declarationLineNumber:node.$declarationLineNumber, moduleName:node.$moduleName};
|
||
let splitted = __splitTextAtAllBlocks(node.$value, ctxInfo);
|
||
if(splitted.length === 1) {
|
||
if(splitted[0][0] === "[" /*&& splitted[0][splitted[0].length-1] === "]"*/) {
|
||
// we don't want to evaluateText on this because it'll be coerced into a string (we want to preserve "direct" references)
|
||
let expression = node.$value.substr(1,node.$value.length-2);
|
||
let result = __evaluateSquareBlock(node.$root, node.$parent, expression, ctxInfo);
|
||
while(1) {
|
||
if(typeof result === "string") {
|
||
// if it is a single square block, we need to preserve direct references to other nodes - if not we can just evaluateText
|
||
let newSplitted = __splitTextAtAllBlocks(result, ctxInfo);
|
||
if(newSplitted.length === 1 && newSplitted[0][0] === "[") {
|
||
let expression = result.substr(1,result.length-2);
|
||
result = __evaluateSquareBlock(node.$root, node.$parent, expression, ctxInfo);
|
||
} else if(newSplitted.length === 1 && /^\{import:[a-z0-9\-]+\}$/.test(newSplitted[0])) {
|
||
let moduleName = result.slice(8, -1);
|
||
let moduleRoot = window.moduleSpace[moduleName].getSelf;
|
||
return moduleRoot.hasOwnProperty("$output") ? moduleRoot.$output : moduleRoot;
|
||
} else {
|
||
// it's definitely not one lone square block, so it's definitely not a direct reference and thus we can just resolve it to plain text:
|
||
result = __evaluateText(node.$root, node.$parent, result, ctxInfo);
|
||
// if(window.generatorLastEditTime > 1716337636385) { // May 22nd 2024 bugfix, ensures only generators edited after this time get it, to prevent breaking old generators that rely on the bug
|
||
// out = __processEscapedCharacters(out);
|
||
// }
|
||
if(localStorage.test2974296 === "sfsdfdsdfss4") { // above bugfix causes issues with many generators, so this is for testing
|
||
result = __processEscapedCharacters(result);
|
||
}
|
||
break;
|
||
}
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
return result;
|
||
} else if(splitted[0][0] === "{" /*&& splitted[0][splitted[0].length-1] === "}"*/) {
|
||
//let expression = node.$value.substr(1,node.$value.length-2);
|
||
//return __evaluateCurlyBlock(node.$root, node.$parent, expression, {declarationLineNumber:node.$declarationLineNumber});
|
||
//return "{"+expression+"}";
|
||
// ---
|
||
// return node; // for square blocks we evaluate it to get a direct reference, but there's no need for this with curly blocks (we let toString do the evalation)
|
||
// EDIT: (read above 7th Aug 2019 realisation - we need to do the evaluation ourselves so that it's evaluated within THIS generator's scope (in terms of `this` and global variables)):
|
||
// return evaluateText(node.$root, node.$parent, node.$value, {declarationLineNumber:node.$declarationLineNumber});
|
||
// EDIT AGAIN: NOPE! Luckily, this is a *node*, not a string, so the future toString will keep the correct context. If we evaluateText here, then you end up not being able to make
|
||
// a consumableList from an "inline" list like `icecreamflavor = {chocolate|vanilla|pistachio}` because `icecreamflavor` immediately resolves to one of the flavours as reported here: https://www.reddit.com/r/perchance/comments/co6msx/bug_list_name_being_included_in_output_of_list/ewgjzmm/
|
||
if(/^\{import:[a-z0-9\-]+\}$/.test(splitted[0])) {
|
||
let moduleName = splitted[0].slice(8, -1);
|
||
// return window.moduleSpace[moduleName].getSelf.$output;
|
||
let moduleRoot = window.moduleSpace[moduleName].getSelf;
|
||
return moduleRoot.hasOwnProperty("$output") ? moduleRoot.$output : moduleRoot;
|
||
} else {
|
||
return node;
|
||
}
|
||
} else {
|
||
// // plain text (no curly or square blocks) - LATER: why do we need to evaluate it then? not necessary?
|
||
//return evaluateText(node.$root, node.$parent, node.$value, {declarationLineNumber:node.$declarationLineNumber});
|
||
return __processEscapedCharacters(node.$value); // <-- WAIT - this will never occur?? The if(node.$isPlainPrimitive) above will catch all plain text nodes.
|
||
}
|
||
} else {
|
||
// we've found a non-direct reference that's not plain text.
|
||
// we need to return the *actual node* because otherwise if we have `output = [prefix]-blah` (for example)
|
||
// then we couldn't call `output.selectMany(3)` on it because `output` would be a plain string (like "pseudo-blah", for example).
|
||
// note that when used on $value nodes, selectOne will just return the node itself
|
||
return node;
|
||
// var n = node.createClone;
|
||
// n.$nodeType = "text";
|
||
// Object.defineProperty(lines[i].node, "$text", {value:n.$value, writable:true, configurable:true});
|
||
// Object.defineProperty(lines[i].node, "$oddsText", {value:"1", writable:true, configurable:true});
|
||
// delete n.$key;
|
||
// delete n.$value;
|
||
// return n;
|
||
}
|
||
|
||
} else if(typeof node.$value === 'boolean') {
|
||
return node.$value;
|
||
} else {
|
||
//console.error("Something went wrong? $value should be either a number, string, or boolean, right?");
|
||
return node.$value; // June 11th 2019: It's a direct reference to another node, or a reference to an objext or something. (I thought I was tyding direct references up somewhere else, but that wouldn't cut it anyway because they can change the value now that there's a setter (e.g. to a POJO or whatever))
|
||
}
|
||
},
|
||
set:function(v) { // June 11th 2019: Added this setter - why wasn't it set already? If it's not set then we can't change it and we get problems like this: https://www.reddit.com/r/perchance/comments/bz2smn/one_of_the_example_generator_is_broken_i_think_i/
|
||
node.$value = v;
|
||
return v;
|
||
},
|
||
configurable:true,
|
||
});
|
||
|
||
Object.defineProperty(lines[i].node, "$nodeType", {value:"value", writable:true, configurable:true});
|
||
Object.defineProperty(lines[i].node, "$text", {value:lines[i].primitiveKey, writable:true, configurable:true});
|
||
|
||
nodeData.parentNode.$valueChildren.push(lines[i].primitiveKey);
|
||
nodeData.parentNode.$allKeys.push(lines[i].primitiveKey);
|
||
nodeData.parentNode.$allKeysSet.add(lines[i].primitiveKey);
|
||
}
|
||
|
||
}
|
||
|
||
// add $children property to each node (an array of all of the keys of the node's non-primitive, non-function children that are leaf nodes (i.e. that are themselves childless))
|
||
// TODO: final confirmation: this should be just the keys, right? or would it be more useful to people as nodes? what are use cases of this property? [animal.$children] - actually yeah, it makes sense that it returns a key - if it returned an object then a random child of THAT object would be chosen!
|
||
for(let node of allNodes) {
|
||
let keys = Object.keys(node).filter(k => node[k].$nodeType === 'normal').sort((k1,k2) => node[k1].$declarationLineNumber-node[k2].$declarationLineNumber); // filter out primitives and sort by the actual order of the list
|
||
Object.defineProperty(node, "$children", {value:keys, writable:true, configurable:true});
|
||
}
|
||
|
||
// // error if any of the **direct children of root** aren't valid javascript identifiers.
|
||
// // this is necessary for two reasons:
|
||
// // 1. calling [else] will throw an error - but [thing.else] will not
|
||
// // 2. calling [my list] will throw an error - but [thing["my list"]] will not
|
||
// let warnLineNumbers = [];
|
||
// for(let key of root.node.$children) {
|
||
// if(!isValidJavaScriptIdentifier(key)) {
|
||
// warnLineNumbers.push( root.node[key].$declarationLineNumber );
|
||
// }
|
||
// }
|
||
// if(warnLineNumbers.length > 0) {
|
||
// if(warnLineNumbers.length > 10) {
|
||
// warnLineNumbers = warnLineNumbers.slice(1,9);
|
||
// warnLineNumbers.push("...");
|
||
// }
|
||
// console.warn(`Warning at line number${(warnLineNumbers.length > 1 ? "s" : "")+" "+warnLineNumbers.join(", ")}. All *top-level* items must only include letters, numbers and underscore characters (no spaces or special characters). They also must not start with a number. They also must not be any of these "reserved" names: break, do, instanceof, typeof, case, else, new, var, catch, finally, return, void, continue, for, switch, while, debugger, function, this, with, default, if, throw, delete, in, try class, enum, extends, super, const, export, import, implements, interface, let, package, private, protected, public, static, yield`);
|
||
// }
|
||
|
||
// TODO: add module name to all errors, or print module name when you catch errors
|
||
// TODO: add "need help?" link to all errors that links to community (reddit, probably)
|
||
|
||
// extract import statements:
|
||
let importedModuleNamesArray = [];
|
||
__ignorePerchanceErrors = true;
|
||
for(let line of lines) {
|
||
if(line.nodeType === 'function' || line.node.$isPlainPrimitive) continue;
|
||
let names = __collectImportedModuleNamesFromText(line.text);
|
||
importedModuleNamesArray.push(...names);
|
||
}
|
||
__ignorePerchanceErrors = false;
|
||
Object.defineProperty(root.node, "$imports", {value:[...new Set(importedModuleNamesArray)], writable:true, configurable:true});
|
||
|
||
|
||
Object.defineProperty(root.node, "$allNodes", {value:allNodes, writable:true, configurable:true});
|
||
|
||
|
||
|
||
// for(let node of allNodes) {
|
||
// if(node.$constructorFunction.prototype !== undefined) {debugger;}
|
||
// Object.defineProperties(node.$constructorFunction.prototype, Object.getOwnPropertyDescriptors(node));
|
||
// }
|
||
|
||
const allowedDollarVariables = ["$output", "$preprocess"];
|
||
for(let node of root.node.$allNodes) {
|
||
if(node.$nodeType === "value" && node.$text[0] === "$" && !allowedDollarVariables.includes(node.$text)) {
|
||
__perchanceError(`There's a problem with the '${moduleName}' generator. You've created a property with a name that starts with "$". This is highly discouraged because dollar-sign variables are reserved for special features such as $output and $preprocess. New features that are added to Perchance in the future may use other dollar-sign variable names and these may conflict with your variable-name choice and thus cause errors.`, {declarationLineNumber:node.$declarationLineNumber, moduleName});
|
||
continue;
|
||
}
|
||
let nodeName = node.$text;
|
||
// I use `moduleName !== null` here to hackily exclude the name check if this run of createPerchanceTree is due to a call of the createClone function (the only case where no module name is allowed). In this case it's fine for top-level nodes to have names to be invalid JS identifiers, because they aren't referencable as if they were global variables.
|
||
// Note that if this is a call to createClone, then `root` isn't the "real" root and is discarded once we've created the clone.
|
||
if(moduleName !== null && node.$parent === root.node && (!__isValidJavaScriptIdentifier(nodeName) || node.$text === "update")) {
|
||
__perchanceError(`There's a problem with the '${moduleName}' generator. You've created a top-level list called "<b>${__escapeHTMLSpecialChars(node.$text)}</b>", which is not allowed. Unfortunately top-level list names are subject to some strict rules:<ul><li>They must not contain any spaces</li><li>They must only contain letters (lower or upper case), numbers and underscores ("_")</li><li>They must not begin with a number</li><li>They must not be any of the following special "reserved" names: update, do, if, in, for, let, new, try, var, case, else, enum, eval, null, this, true, void, with, await, break, catch, class, const, false, super, throw, while, yield, delete, export, import, public, return, static, switch, typeof, default, extends, finally, package, private, continue, debugger, function, arguments, interface, protected, implements, instanceof</li></ul> Sorry for the inconvenience! These rules may seem strange, but they're needed to make the more advanced features of the perchance engine work.`, {declarationLineNumber:node.$declarationLineNumber, moduleName});
|
||
}
|
||
}
|
||
|
||
|
||
|
||
let fn = function(){};
|
||
fn.obj = root.node;
|
||
let rootProxy = new Proxy(fn, {
|
||
capturedCalls: [],
|
||
executionProperties: [
|
||
"toString",
|
||
"valueOf",
|
||
Symbol.hasInstance,
|
||
Symbol.isConcatSpreadable,
|
||
Symbol.iterator,
|
||
Symbol.match,
|
||
Symbol.prototype,
|
||
Symbol.replace,
|
||
Symbol.search,
|
||
Symbol.species,
|
||
Symbol.split,
|
||
Symbol.toPrimitive,
|
||
Symbol.toStringTag,
|
||
Symbol.unscopables,
|
||
Symbol.for,
|
||
Symbol.keyFor,
|
||
"selectMany",
|
||
"selectOne",
|
||
"selectAll",
|
||
"getSelf",
|
||
"getName",
|
||
"$imports",
|
||
"$allNodes",
|
||
"$odds",
|
||
"$text",
|
||
"$value",
|
||
"$key",
|
||
"$nodeType",
|
||
"$oddsText",
|
||
"$declarationLineNumber",
|
||
"$moduleName",
|
||
"$root",
|
||
"$parent",
|
||
"$children",
|
||
"isConsumable",
|
||
"consumableList",
|
||
"createClone",
|
||
"evaluateItem",
|
||
"joinItems",
|
||
//"listName",
|
||
// TODO: add new items here whenever you add any new special properties
|
||
],
|
||
organiseCalls: function(capturedCalls) {
|
||
// CAREFUL: do not move `apply`s away from their correct `get`
|
||
let textTransforms = [];
|
||
let nonTextTransforms = [];
|
||
let inApplyChain = false;
|
||
for(let i = 0; i < capturedCalls.length; i++) {
|
||
let call = capturedCalls[i];
|
||
if(call.type === "get" && textTransformNames.includes(call.name)) {
|
||
// if(i+1 < capturedCalls.length && capturedCalls[i+1].type === "apply") {
|
||
// perchanceError(`Tried to call a text transform '${call.name}' as a function/method. Text transforms like ${call.name}, pluralForm and titleCase are not functions. They shouldn't be followed by a pair brackets.`);
|
||
// }
|
||
textTransforms.push(call);
|
||
inApplyChain = true; // any `apply`s after this text transform must be moved with it
|
||
|
||
} else if(call.type === "apply" && inApplyChain) {
|
||
textTransforms.push(call);
|
||
} else {
|
||
nonTextTransforms.push(call);
|
||
inApplyChain = false;
|
||
}
|
||
}
|
||
let organisedCalls = [];
|
||
organisedCalls.push(...nonTextTransforms);
|
||
organisedCalls.push(...textTransforms);
|
||
// TODO***: should text transforms be applied before joinItems?
|
||
return organisedCalls;
|
||
},
|
||
executeChain: function(target, calls) {
|
||
let result = target.obj;
|
||
|
||
// let disable$output = false;
|
||
// if(calls.map(c=>c.name).includes("disable$output")) {
|
||
// debugger;
|
||
// disable$output = true;
|
||
// }
|
||
|
||
if(calls.length === 0) {
|
||
return target.obj;
|
||
}
|
||
|
||
// move text transforms to end (importantly, this method doesn't change the this.capturedCalls array - it returns a new one)
|
||
let capturedCalls = this.organiseCalls(calls);
|
||
|
||
let lastResult, secondLastResult;
|
||
for(let i = 0; i < capturedCalls.length; i++) {
|
||
let call = capturedCalls[i];
|
||
|
||
secondLastResult = lastResult; // needed for `apply` (since LAST result is the actual function, and not the object/thing that it's being being called from)
|
||
lastResult = result;
|
||
|
||
if(call.type === "get") {
|
||
result = result[call.name];
|
||
if(result === undefined && i === 0) {
|
||
result = window[call.name]; // try to fallback to global `window` if there's no list/function/property found - e.g. if they did [Math.min(hp, 100)] - "Math" is not a list
|
||
}
|
||
} else if(call.type === "apply") {
|
||
// in my case the `this` variable should be the thing that the method is being called from
|
||
// (this is done by default with getters)
|
||
result = result.apply(secondLastResult, call.args);
|
||
} else {
|
||
console.error("How could this be?");
|
||
}
|
||
|
||
if(result === undefined) {
|
||
// we DON'T return an error message because they may just want to check if the property exists.
|
||
return undefined;
|
||
}
|
||
|
||
// Remember that `result` could be a Proxy (imagine `$output = [noun.pluralForm]` - root.$output is a proxy with `noun` and `pluralForm` in the capturedCalls array (because $value nodes are evaluated when called (using a `get` handler))).
|
||
// If it IS a proxy, we want to append this proxy's capturedCalls array to the new one and execute it:
|
||
if(result.___isProxy) {
|
||
let leftOverCalls = capturedCalls.slice(i+1);
|
||
let allCalls = [...result.___proxyHandler.capturedCalls, ...leftOverCalls];
|
||
// TODO: just to confirm, we don't need to pass along secondLastResult do we? What if they called `apply` twice in a row? It's an edge case that might be annoying to debug later on
|
||
return this.executeChain(result.___proxyTarget, allCalls);
|
||
}
|
||
|
||
}
|
||
return result;
|
||
},
|
||
userDefinedNonNodePropertyIds: {},
|
||
getUserDefinedNonNodePropertyId: function(property, calls) {
|
||
|
||
// In case you're wondering what on earth is going on here:
|
||
// We need to get the proxy to return properies that the USER has set with scripts (in square blocks, functions, etc.).
|
||
// So we need to keep track of when they add their own properties to `root`.
|
||
// That way, when the proxy gets a `get` request for one of these "non-node" properties, it can return it straight up.
|
||
// Basically, any properties added to root AFTER compilation will always be returned in get requests (rather than returning a proxy).
|
||
|
||
// This will probably cause memory leaks if they're setting properties on root with dynamically generated names?
|
||
|
||
let seperator = "_{9287234632<<prop-id-call-seperator>>4632877592}_";
|
||
let id = "root";
|
||
for(let call of calls) {
|
||
if(call.type === "apply") {
|
||
return false;
|
||
}
|
||
id += seperator + call.name;
|
||
}
|
||
id += seperator + property;
|
||
return id;
|
||
},
|
||
isUserDefinedNonNodeProperty: function(property, calls) {
|
||
return this.userDefinedNonNodePropertyIds[ this.getUserDefinedNonNodePropertyId(property, calls) ] === true;
|
||
},
|
||
isFunctionNode: function(target, capturedCalls, property) {
|
||
|
||
// If `property` is referencing a function node of target.obj, then we want to
|
||
// return that function (not a proxy). That's why we need this function (we use it in the `get` handler)
|
||
|
||
// if there are `apply`s in the capturedCalls, return false, since a function node can only be a
|
||
// direct `get` chain from the root node (this is just an optimisation)
|
||
for(let c of capturedCalls) {
|
||
if(c.type === 'apply') return false;
|
||
}
|
||
|
||
let root = target.obj;
|
||
|
||
// NOTE: we don't need to worry about user-defined non-node properties, because we detect them in the `get` trap
|
||
// NOTE: remember, all nodes are functions, so be careful with your typeof logic (not used here anyway)
|
||
let ref = root;
|
||
for(let c of capturedCalls) {
|
||
if(ref.$children.includes(c.name)) ref = ref[c.name];
|
||
else return false;
|
||
}
|
||
if(ref.$functionChildren.includes(property)) return true; // the call path DOES reference a function node
|
||
else return false;
|
||
|
||
// OLD APPROACH: I have no idea why I was doing the reverse-lookup thing in this old approach. To get around proxy "looping" stuff???
|
||
// // Here's what we do:
|
||
// // 1. if there are `apply`s in the capturedCalls, return false, since a function node can only be a
|
||
// // direct `get` chain from the root node (this is just an optimisation)
|
||
// // 2. For each occurrance of `property` in root.$allNodes that is a `value` or `function` node, trace
|
||
// // back up the $parent chain, checking at each stage that it matches the capturedCalls `get` names
|
||
// // in reverse order. If you get back to root, run the capturedCalls on root and see if it's a function.
|
||
// // If it is, return true. Otherwise continue.
|
||
// // 3. If no matches, return false.
|
||
//
|
||
//
|
||
// for(let c of capturedCalls) {
|
||
// if(c.type === 'apply') return false;
|
||
// }
|
||
//
|
||
// let root = target.obj;
|
||
//
|
||
// for(let node of root.$allNodes) {
|
||
// if(node.$text !== property) continue;
|
||
// if(node.$nodeType !== 'value' && node.$nodeType !== 'function') continue;
|
||
//
|
||
// // so we know it's a value or function node, and we know the `property` matches its name.
|
||
// // now we need to check if the node's ancestry chain back to root matches the capturedCalls array
|
||
//
|
||
// let traceNode = node.$parent;
|
||
// for(let i = capturedCalls.length-1; i >= 0; i--) {
|
||
// if(capturedCalls[i].name !== traceNode.$text) break;
|
||
// traceNode = traceNode.$parent;
|
||
// }
|
||
//
|
||
// if(traceNode === root) { // found a full path/ancestry match
|
||
// // now we just need to check if it's a function:
|
||
// let ref = root;
|
||
// for(let c of capturedCalls) { ref = ref[c.name]; }
|
||
// // i replaced the below two commented out lines with the third to help solve some `get` loops happening in the proxy with this.isFunctionNode
|
||
// // ref = ref[property]; // the final `get`
|
||
// // if(typeof ref === 'function') return true; // found a function node!!!
|
||
// if(ref.$functionChildren.includes(property)) return true; // found a function node!!!
|
||
// }
|
||
//
|
||
// }
|
||
//
|
||
// return false;
|
||
|
||
},
|
||
isGetterProperty: function(target, property) {
|
||
let desc = Object.getOwnPropertyDescriptor(target.obj, property);
|
||
return desc && desc.get;
|
||
},
|
||
get: function(target, property, receiver) {
|
||
|
||
// commenting this out for now in favor of the perchance.org/my-generator#debugFreeze approach
|
||
// if(window.globalProxyLoopCount > 10000000) {
|
||
// throw new Error("It seems like you've got an infinite loop somewhere in your code. Are you referencing a list name within a child of that list, such that it creates an infinite loop?");
|
||
// }
|
||
// window.globalProxyLoopCount++;
|
||
|
||
|
||
if(property === "___isProxy") { return true; }
|
||
if(property === "___proxyTarget") { return target; }
|
||
if(property === "___proxyHandler") { return this; }
|
||
// if(property === "___addExecutionPath") {
|
||
// let last = this.capturedCalls[this.capturedCalls.length-1];
|
||
// this.capturedCalls.pop();
|
||
// this.userDefinedNonNodePropertyIds[ this.getUserDefinedNonNodePropertyId(last, this.capturedCalls) ] = true;
|
||
// }
|
||
|
||
//if(this.isGetterProperty(target, property) || this.executionProperties.includes(property) || this.isUserDefinedNonNodeProperty(property, this.capturedCalls) || this.isFunctionNode(target, this.capturedCalls, property)) {
|
||
if(true) { // testing out resolving all `get`s (QUESTION: was the only reason why we needed proxies for stuff like `pluralAnimalList = [animal.pluralForm]`? because that's really not needed anyway, and I don't think it's even possible in perchance's current state)
|
||
|
||
let result = this.executeChain(target, this.capturedCalls);
|
||
|
||
// if(typeof result === 'string' || typeof result === 'number')
|
||
// return result;
|
||
|
||
if(result === undefined) {
|
||
if(property === Symbol.toPrimitive) {
|
||
return function() { return undefined; }
|
||
} else {
|
||
__perchanceError(`the list/variable <code>${this.capturedCalls.map(c=>c.name).join("→")}</code> doesn't seem to exist in the <code>${target.obj.$moduleName}</code> generator.`, {moduleName:target.obj.$moduleName});
|
||
// if(property === Symbol.toPrimitive) return function() { return "(error)"; }
|
||
return "(error)";
|
||
}
|
||
}
|
||
|
||
let finalResult = result[property];
|
||
if(typeof finalResult === 'function' && !finalResult.___isProxy) {
|
||
finalResult = finalResult.bind(result);
|
||
}
|
||
return finalResult;
|
||
|
||
} else {
|
||
// need to return new proxy
|
||
let newHandler = {};
|
||
Object.assign(newHandler, this);
|
||
newHandler.capturedCalls = this.capturedCalls.slice(0);
|
||
|
||
newHandler.capturedCalls.push({type:"get", name:property});
|
||
let np = new Proxy(target, newHandler)
|
||
return np;
|
||
}
|
||
},
|
||
apply: function(target, thisArg, args) {
|
||
// // return a new proxy:
|
||
// let newHandler = {};
|
||
// Object.assign(newHandler, this);
|
||
// newHandler.capturedCalls = this.capturedCalls.slice(0);
|
||
// // add arguments to last call that was captured
|
||
// newHandler.capturedCalls.push({type:"apply", args});
|
||
// let np = new Proxy(target, newHandler);
|
||
// return np;
|
||
|
||
// i commented out the above code and added this because we always want functions to resolve immediately. otherwise we get this problem (see comment in bottom left): https://i.imgur.com/SY9MOt8.png -- as another example, people needed to write [a = dice("1d6").selectOne] instead of just [a = dice("1d6")]
|
||
// maybe I should make exceptions for joinItems and those other inbuilt functions?
|
||
this.capturedCalls.push({type:"apply", args});
|
||
return this.executeChain(target, this.capturedCalls);
|
||
},
|
||
set: function(target, property, value, receiver) {
|
||
// resolve it if it's a proxy (to prevent infinite loops when you do something like [abc=abc] (where abc is an already-defined top-level node), since that would set abc to its own proxy, so when you resolve it, it would resolve to the proxy, and the loop continues)
|
||
if(value && value.___isProxy) {
|
||
value = value.___proxyHandler.executeChain(value.___proxyTarget, value.___proxyHandler.capturedCalls);
|
||
}
|
||
|
||
let obj = this.executeChain(target, this.capturedCalls);
|
||
if(typeof obj !== 'object') {
|
||
__perchanceError(`You tried to set <code>${__escapeHTMLSpecialChars(this.capturedCalls.map(c=>c.name).join("."))}</code> to <code>${__escapeHTMLSpecialChars(value)}</code>, but it appears that <code>${__escapeHTMLSpecialChars(this.capturedCalls.map(c=>c.name).join("."))}</code> does not exist, or some other strange error has occurred.`);
|
||
return;
|
||
}
|
||
Object.defineProperty(obj, property, {value, writable:true, configurable:true}); // importantly we're executing defineProperty on an actual object, NOT a proxy
|
||
this.userDefinedNonNodePropertyIds[ this.getUserDefinedNonNodePropertyId(property, this.capturedCalls) ] = true;
|
||
return value;
|
||
},
|
||
isExtensible: function(target) { return Object.isExtensible(this.executeChain(target, this.capturedCalls)); },
|
||
preventExtensions: function(target) { return Object.preventExtensions(this.executeChain(target, this.capturedCalls)); },
|
||
getOwnPropertyDescriptor: function(target, prop) { return Object.getOwnPropertyDescriptor(this.executeChain(target, this.capturedCalls), prop); },
|
||
defineProperty: function(target, property, descriptor) { return Object.defineProperty(this.executeChain(target, this.capturedCalls), property, descriptor); },
|
||
has: function(target, prop) { return (prop in this.executeChain(target, this.capturedCalls)); },
|
||
deleteProperty: function(target, property) { return delete this.executeChain(target, this.capturedCalls)[property]; },
|
||
ownKeys: function(target) { return Reflect.ownKeys(this.executeChain(target, this.capturedCalls)); }
|
||
});
|
||
window.__rootProxyHasHandler = rootProxy.___proxyHandler.has;
|
||
|
||
// add this module to modulespace now otherwise our functions won't work for the direct-reference checks
|
||
// yolo
|
||
window.moduleSpace[moduleName] = rootProxy;
|
||
|
||
// EDIT: don't need this any more now that we've got isFunctionNode?
|
||
// make user-defined functions execute immediately upon being called (i.e. don't return a proxy)
|
||
// for(let i = 0; i < allNodes.length; i++) {
|
||
// if(allNodes[i].$nodeType === "function") {
|
||
// let node = allNodes[i];
|
||
// // we found a function, now lets build a call chain to it
|
||
// let calls = [];
|
||
// while(node.$parent) {
|
||
// calls.unshift(node.$parent.$text);
|
||
// node = node.$parent;
|
||
// }
|
||
// calls.shift(); // remove "<root>"
|
||
// let chain = [rootProxy];
|
||
// for(let c of calls) {
|
||
// chain.push(chain[chain.length-1][c]); // did it weirdly like this to prevent proxy setter being called
|
||
// }
|
||
// chain = chain[chain.length-1]; // the last element is the completed chain
|
||
// chain[allNodes[i].$text] = allNodes[i].$function; // EDIT: this calls the proxy setter and adds a "userDefinedNonNodeProperty" - was that the prupose?
|
||
// }
|
||
// }
|
||
|
||
|
||
// tie direct references to the actual nodes. e.g.:
|
||
// animal = [african_animal]
|
||
// $output = [person]
|
||
// so rather than [animal] and [$output] being $value nodes, they'll directly reference [aftican_animal] and [person].
|
||
// this is mainly needed to make $output behaviour sane.
|
||
for(let node of allNodes) {
|
||
if(node.$nodeType === "value" && !node.$isPlainPrimitive) {
|
||
let blocks = __splitTextAtAllBlocks(node.$value, {declarationLineNumber:node.$declarationLineNumber, moduleName:node.$moduleName});
|
||
if(blocks.length === 1 && blocks[0][0] === "[" && blocks[0][blocks[0].length-1] === "]") {
|
||
let expression = node.$value.substr(1,node.$value.length-2);
|
||
|
||
// only create link if they're DIRECTLY referencing another list:
|
||
if(__isValidJavaScriptIdentifier(expression)) {
|
||
// intermediate values can be non-direct references, and we don't want to e.g. execute `[a++]`, so we make sure that if __evaluateSquareBlock comes across something like that in a multi-step "indirection chain", it aborts
|
||
window.__throwErrorIfNonDirectListReferenceIsFoundDuringEvaluateSquareBlock = true; // epic
|
||
try {
|
||
__ignorePerchanceErrors = true; // it may fail because it could reference a function that hasn't been linked yet (i have no idea what's going on)
|
||
let refNode = __evaluateSquareBlock(root.node, node.$parent, expression, {declarationLineNumber:node.$declarationLineNumber, moduleName:node.$moduleName});
|
||
__ignorePerchanceErrors = false;
|
||
|
||
if(refNode && refNode.$nodeType /*|| Array.isArray(refNode)*/) { // did it not abort, and did it resolve to a node?
|
||
node.$parent[node.$text] = refNode;
|
||
}
|
||
} catch(e) {}
|
||
delete window.__throwErrorIfNonDirectListReferenceIsFoundDuringEvaluateSquareBlock;
|
||
}
|
||
|
||
// NOTE: curly IMPORT blocks get tied to their actual module after all imports are compiled (in iframe html)
|
||
|
||
// TODO**: does all this work by default now because of the new proxy approach? can I remove this part all together?
|
||
|
||
// TODO***: we need to pre-evaluate $output so it's a *direct* reference to the thing it references,
|
||
// but if we do that with other $value nodes, things can get messy:
|
||
//
|
||
// person
|
||
// name = [name.selectOne]
|
||
//
|
||
// `person.name` will always be same node!!
|
||
// if we call update it stays the same
|
||
// if we do [a = new person], the selection remains the same
|
||
// etc. - tonnes of problems
|
||
// here's why we WANT to be able to do this in the first place:
|
||
// person
|
||
// name = [name.selectOne]
|
||
// gender = [this.name.gender]
|
||
//
|
||
// note that we can already do this sort of thing:
|
||
//
|
||
// person
|
||
// age = {1-100}
|
||
// isAdult = [this.age > 18]
|
||
//
|
||
// potential solution: only pre-evaluate it if it's a direct reference to another node
|
||
// (just like $output always is).
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
// give each node an id:
|
||
for(let i = 0; i < allNodes.length; i++) {
|
||
Object.defineProperty(allNodes[i], "$id", {value:i, writable:true, configurable:true});
|
||
}
|
||
|
||
|
||
|
||
// fix up $root references so they point to proxy instead of actual node
|
||
// also remove node data symbol stuff
|
||
// TODO***: what about $parent references - should they be proxied too?
|
||
for(let i = 0; i < allNodes.length; i++) {
|
||
Object.defineProperty(allNodes[i], "$root", {value:rootProxy, writable:true, configurable:true});
|
||
delete allNodes[i][Symbol.for("node data")];
|
||
}
|
||
|
||
// at the moment, this is mainly so that other users don't get confused about strange syntax - they can easily see there's a preprocessor,
|
||
// but in the future I may speed up preprocessing by just grabbing the function from the top, compiling that, and then running the code through it.
|
||
// (instead of compiling the whole thing just to get the $preprocess function, as is happening now.) EDIT: oh, don't forget they can *import* preprocessor too!
|
||
if(root.node.$preprocess && root.node.$allNodes[1].$text !== "$preprocess") {
|
||
__perchanceError(`The special <code>$preprocess</code> function must be placed above all your other lists - at the very top of the Perchance code editor.`, {moduleName});
|
||
return;
|
||
}
|
||
|
||
if(root.node.$preprocess && !doNotPreprocess) {
|
||
let preprocess;
|
||
if(typeof root.node.$preprocess === 'function') {
|
||
preprocess = root.node.$preprocess;
|
||
} else {
|
||
if(!root.node.$preprocess.$value && root.node.$preprocess.$allKeys.includes("$preprocess")) return __perchanceError(`Looks like you've imported the '${root.node.$preprocess.$moduleName}' generator for use as a preprocessor, but the preprocessor should be defined as the <code>$output</code> in '${root.node.$preprocess.$moduleName}', rather than as <code>$preprocess</code>.`, {moduleName});
|
||
if(!root.node.$preprocess.$value.startsWith("{import:")) return __perchanceError(`The special <code>$preprocess</code> property must be defined as a function, or an imported function.`, {moduleName});
|
||
let preprocessorName = root.node.$preprocess.$value.slice(8, -1);
|
||
let module = window.moduleSpace[preprocessorName];
|
||
if(!module) {
|
||
__perchanceError(`The preprocessor '${preprocessorName}' could not be found?`, {moduleName});
|
||
return;
|
||
}
|
||
if(!module.$output || !module.$output.$nodeType === "function") return __perchanceError(`The '${preprocessorName}' was imported into '${moduleName}' as a preprocessor function, but the <code>$output</code> of '${preprocessorName}' doesn't exist or is not a function?`, {moduleName});
|
||
preprocess = module.$output;
|
||
}
|
||
let newInputText = preprocess(root.perchanceCode);
|
||
return __createPerchanceTree(newInputText, moduleName, backupModuleName, true);
|
||
}
|
||
|
||
console.log(`${moduleName} init: ${Date.now()-functionStartTime}ms`);
|
||
|
||
return rootProxy;
|
||
//return root.node;
|
||
|
||
|
||
// notes:
|
||
// TODO: remove todos that are already done...
|
||
// TODO: primitive declarations using "=" and update toString so it ignores primitive-valued properties
|
||
// TODO: in toString: add {a|b|c} notation handling (recusive)
|
||
// TODO: add array handling: we just treat ["a", "b^2", "c"] like {a|b^2|c} when Array.toString() is called (use the same back-end function)
|
||
|
||
// TODO: if we across duplicate sibling nodes, what do we do? just make the latter overwrite the prior? add the odds together?
|
||
|
||
}
|
||
|
||
|
||
// this is very hacky...
|
||
function __duplicatePerchanceNode(originalNode) {
|
||
originalNode = originalNode.getSelf;
|
||
|
||
// NOTE: node will be unreferencable from parent (since the node to be duplicated already holds that key).
|
||
// I think this is fine? They can always add it to the parent if some weird situation required that.
|
||
|
||
let root = __createPerchanceTree(originalNode.$perchanceCode, null, originalNode.$moduleName);
|
||
root = root.getSelf; // get target object, not proxy
|
||
|
||
for(let node of root.$allNodes) {
|
||
if(node === root) continue;
|
||
node.$id = originalNode.$root.getSelf.$allNodes.length;
|
||
originalNode.$root.getSelf.$allNodes.push(node);
|
||
|
||
node.$root = originalNode.$root.getSelf;
|
||
node.$moduleName = originalNode.$moduleName;
|
||
// I think this is causing some problems when it tries to get a node of a "directly linked" property:
|
||
//node.$declarationLineNumber = getCorrespondingOriginalNode(node).$declarationLineNumber;
|
||
}
|
||
|
||
// function getCorrespondingOriginalNode(clonedNode) {
|
||
// let propertyChain = [];
|
||
// let n = clonedNode;
|
||
// while(n.$parent) { // get chain up to cloned root
|
||
// propertyChain.unshift(n.$text);
|
||
// n = n.$parent;
|
||
// }
|
||
// n = originalNode.$parent.getSelf
|
||
// while(propertyChain.length) { // evaluate chain from original node's parent
|
||
// n = n[propertyChain[0]];
|
||
// propertyChain.shift();
|
||
// }
|
||
// return n;
|
||
// }
|
||
|
||
let node = root[originalNode.$text];
|
||
node.$parent = originalNode.$parent.getSelf;
|
||
|
||
return node;
|
||
|
||
}
|
||
|
||
|
||
// This function is PUBLIC - i.e. available for people to use in their generators
|
||
function createPerchanceTree(text) {
|
||
|
||
let root = __createPerchanceTree(text, null, "<null>"); // <null> is a special value for nodes that technically don't belong to any module
|
||
root = root.getSelf; // get target object, not proxy
|
||
|
||
return root;
|
||
}
|
||
|
||
|
||
function __escapeHTMLSpecialChars(unsafe) {
|
||
return unsafe.toString()
|
||
.replace(/&/g, "&")
|
||
.replace(/</g, "<")
|
||
.replace(/>/g, ">")
|
||
.replace(/"/g, """)
|
||
.replace(/'/g, "'");
|
||
}
|
||
|
||
function __collectImportedModuleNamesFromText(text) {
|
||
let blocks = __splitTextAtAllBlocks(text);
|
||
let moduleNames = [];
|
||
for(let b of blocks) {
|
||
if(b[0] === "{") {
|
||
let match = /^\{import:([a-z0-9\-]+)\}$/.exec(b);
|
||
if(match && match.length > 1) {
|
||
moduleNames.push( /^\{import:([a-z0-9\-]+)\}$/.exec(b)[1] );
|
||
} else {
|
||
moduleNames.push( ...__collectImportedModuleNamesFromText( b.substr(1, b.length-2) ) );
|
||
}
|
||
}
|
||
}
|
||
return [...new Set(moduleNames)];
|
||
}
|
||
|
||
// function evaluateTextAsNumber(rootNode, thisRef, text, ctxInfo) {
|
||
// // NOTE: This function is NOT for evaluating odds expressions!
|
||
// // NOTE: this only returns the number if it can be "exactly" converted
|
||
// // into a number - it doesn't evaluate the string's mathematical operators
|
||
// // or anything like that. It only returns if text === String(Number(text))
|
||
// // because that mean indicates that the deliberately typed a number, and even if
|
||
// // they didn't, the toString conversion that occurs when this number is output
|
||
// // will give **exacttly the same result anyway**.
|
||
// let value = __evaluateText(rootNode, thisRef, text, ctxInfo);
|
||
// if(value === String(Number(value))) {
|
||
// return Number(value);
|
||
// } else {
|
||
// return false;
|
||
// }
|
||
// }
|
||
|
||
function __evaluateText(rootNode, thisRef, text, ctxInfo, previousEvaluationText) {
|
||
|
||
// IMPORTANT: Some curly functions may "return themselves" i.e. {a} may return "{a}" rather than "a" or "an" - this
|
||
// behaviour is allowable because evaluateText is called recursively until no unescaped curly/square blocks
|
||
// exist. The reason curly functions may do this is because parts of their arguments (the two strings either side of
|
||
// "{a}" in the case of the "{a}" function) may not have been evaluated yet, and it may rely on those parts having
|
||
// been evaluated. e.g. in the text "{a} [animal] is over there", {a} must wait until [animal] has been evaluated.
|
||
// ALSO NOTE: previousEvaluationText is needed because (for example) if we evaluate "created {a}", there's nothing after {a} for
|
||
// us to detemrine whether we should use "a" or "an". But "created {a}" is still valid because they could be using it
|
||
// as part of a larger sentence. If `text` evaluates to `previousEvaluationText`, then we just return it rather than
|
||
// recuring infinitely.
|
||
// ALSO NOTE: I had to change this so that instead of [passing through once and then checking if there are any unevaluated blocks that would
|
||
// require another pass-over], it does the recursion *within* the loop - otherwise things get executed out of order (e.g. assignment of
|
||
// variables and stuff). The user expects their variable assignments to happen in the order that the final output text is printed in.
|
||
// Edit: Oh, but I still need to recurse at the end, because some curly blocks like {a} may only be executable once all the blocks are
|
||
// joined together into one string.
|
||
// ALSO NOTE: This function DOESN'T call processEscapedCharacters on the output. That must be called on the result.
|
||
|
||
var bracketRegex = /[\[\]{}]/; // note: this is used further down too
|
||
|
||
if(!bracketRegex.test(text)) return text; // if it has no brackets, nothing needs evaluating
|
||
|
||
var blocks = __splitTextAtAllBlocks(text, ctxInfo);
|
||
// iterate through and evaluate each block
|
||
var evaluatedBlocks = [];
|
||
var block, leftBlocks, rightBlocks;
|
||
for(let i = 0; i < blocks.length; i++) {
|
||
block = blocks[i];
|
||
leftBlocks = blocks.slice(0,i);
|
||
rightBlocks = blocks.slice(i+1);
|
||
|
||
if(block[0] === "{") {
|
||
|
||
let input = block.substr(1,block.length-2);
|
||
let result = __evaluateCurlyBlock(rootNode, thisRef, input, leftBlocks, rightBlocks, ctxInfo);
|
||
|
||
if(result && (typeof result === "object" || typeof result === "function") && result.$nodeType) {
|
||
// This could be a Perchance node due to import blocks. See note below the `__evaluateSquareBlock` call below for explanation.
|
||
result = result.toString({keepEscapes:true});
|
||
} else {
|
||
result = result + "";
|
||
}
|
||
|
||
// the first few conditions here are just performance optimisations:
|
||
if(result !== block && bracketRegex.test(result) && (result[0] === "[" || result[0] === "{" || __splitTextAtAllBlocks(result).length > 1)) {
|
||
result = __evaluateText(rootNode, thisRef, result, ctxInfo, result);
|
||
}
|
||
evaluatedBlocks.push(result);
|
||
|
||
} else if(block[0] === "[") {
|
||
|
||
let input = block.substr(1,block.length-2);
|
||
window.__primitiveValueGetterKeepEscapesYolo = true; // see MARKER:odj29hfi3j0d2kj0hx24f for explanation
|
||
let result = __evaluateSquareBlock(rootNode, thisRef, input, ctxInfo);
|
||
window.__primitiveValueGetterKeepEscapesYolo = false;
|
||
|
||
if(result && (typeof result === "object" || typeof result === "function") && result.$nodeType) {
|
||
// If it's a Perchance node, we keep the escape characters, since if we remove them here, then we would unescape square/curly character (for example) and
|
||
// then they'd get executed (in the code that follows this block) even though that's obviously not what the user wants. See the comments at the top of the toString
|
||
// function for more context.
|
||
result = result.toString({keepEscapes:true});
|
||
} else {
|
||
result = result + "";
|
||
}
|
||
|
||
// the first few conditions here are just performance optimisations:
|
||
if(result !== block && bracketRegex.test(result) && (result[0] === "[" || result[0] === "{" || __splitTextAtAllBlocks(result).length > 1)) {
|
||
result = __evaluateText(rootNode, thisRef, result, ctxInfo, result);
|
||
}
|
||
evaluatedBlocks.push(result);
|
||
|
||
} else {
|
||
evaluatedBlocks.push(block);
|
||
}
|
||
}
|
||
|
||
if(previousEvaluationText === evaluatedBlocks.join("")) return previousEvaluationText; // see note at top of this function for explanation
|
||
|
||
// if there's anything but plain text (i.e. if there's any curly/square blocks), recurse
|
||
var b, completelyEvaluated = true;
|
||
for(let i = 0; i < evaluatedBlocks.length; i++) {
|
||
b = evaluatedBlocks[i];
|
||
if(!bracketRegex.test(b)) continue;
|
||
//if(b === undefined) { b = evaluatedBlocks[i] = "(not found)"; }
|
||
if(b[0] === "[" || b[0] === "{" || __splitTextAtAllBlocks(b).length > 1) {
|
||
completelyEvaluated = false;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(!completelyEvaluated) {
|
||
return __evaluateText(rootNode, thisRef, evaluatedBlocks.join(""), ctxInfo, evaluatedBlocks.join(""));
|
||
} else {
|
||
return evaluatedBlocks.join("");
|
||
}
|
||
|
||
}
|
||
|
||
function __processEscapedCharacters(text) {
|
||
|
||
//TODO***: when they have an item like `\ hello \` and they repeat it like [item][item][item]... you end up with `hello \ hello \ hello \ ...` because the two backslashes join up.
|
||
// I think this is pretty easy: if there's an unescaped backslash on the end, remove it when you create the node.
|
||
// If there's one at the start and it's just escaping a space, then remove that backslash too.
|
||
|
||
// TODO***: allow them to escape forward slashes?
|
||
// TODO***: empty character "\e"?
|
||
|
||
// look for input characters that follow an unescaped backslash
|
||
// and replace them with the output character and remove the backslash
|
||
|
||
let escapableCharacters = [
|
||
{input:"=", output:"="},
|
||
{input:"{", output:"{"},
|
||
{input:"}", output:"}"},
|
||
{input:"[", output:"["},
|
||
{input:"]", output:"]"},
|
||
{input:"^", output:"^"},
|
||
{input:"|", output:"|"},
|
||
{input:"n", output:"\n"},
|
||
{input:"t", output:"\t"},
|
||
{input:"s", output:" "},
|
||
];
|
||
|
||
let escaped = false;
|
||
for(let i = 0; i < text.length; i++) {
|
||
if(i !== 0) {
|
||
if(text[i-1] !== "\\") {
|
||
escaped = false;
|
||
}
|
||
}
|
||
|
||
if(text[i] === "\\") {
|
||
if(escaped) { // handle the special case of the backslash character:
|
||
escaped = false;
|
||
text = text.substr(0, i-1) + "\\" + text.substr(i+1);
|
||
i--;
|
||
} else {
|
||
|
||
if(i === text.length-1) {
|
||
return text.substr(0, text.length-1); // if last character is an unescaped backslash, return text without it
|
||
} else {
|
||
escaped = true;
|
||
}
|
||
|
||
}
|
||
continue;
|
||
}
|
||
|
||
if(escaped) {
|
||
for(let e of escapableCharacters) {
|
||
if(text[i] === e.input) {
|
||
text = text.substr(0, i-1) + e.output + text.substr(i+1);
|
||
i--;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
return text;
|
||
|
||
}
|
||
|
||
function __evaluateCurlyBlock(rootNode, thisRef, block, leftBlocks, rightBlocks, ctxInfo) {
|
||
|
||
// `block` is a string of the *contents* of the curly block
|
||
for(let fn of __curlyFunctions) {
|
||
// note that recursion can occur here since some curly functions may neet to
|
||
// resolve their arguments to plain text. So they'll call evaluatedText, which
|
||
// will call this function (if curly brackets are found), and so the loop loops.
|
||
let evaluatedBlock = fn(rootNode, thisRef, block, leftBlocks, rightBlocks, ctxInfo);
|
||
if(evaluatedBlock !== false) {
|
||
if(typeof evaluatedBlock === 'string' && String(Number(evaluatedBlock)) === evaluatedBlock) {
|
||
return Number(evaluatedBlock);
|
||
} else {
|
||
return evaluatedBlock;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(block === "s") {
|
||
__perchanceError(`Your curly block "<code>{${__escapeHTMLSpecialChars(block)}}</code>" doesn't appear to have the correct syntax. It is meant to be used for something like <code>I have {1-3} [fruit]{s}</code>. Notice that there needs to be a number preceding the <code>[fruit]</code> block. If you just want the plural of <code>[fruit]</code> then you can use <code>[fruit.pluralForm]</code>.`, {declarationLineNumber:ctxInfo.declarationLineNumber, moduleName:ctxInfo.moduleName});
|
||
} else {
|
||
__perchanceError(`Your curly block "<code>{${__escapeHTMLSpecialChars(block)}}</code>" doesn't appear to have the correct syntax. Curly brackets (these ones: {}) are special characters in Perchance. They're used to do all sorts of fancy stuff which you can learn about in the <a href="/tutorial">tutorial</a>. If you didn't intend to use a special function, and instead just wanted to actually use curly brackets as literal characters, then you can put a backslash character before them like so: \\{...\\}`, {declarationLineNumber:ctxInfo.declarationLineNumber, moduleName:ctxInfo.moduleName});
|
||
}
|
||
return "(invalid curly block)";
|
||
|
||
}
|
||
|
||
// function evaluateCurlylessBlock(rootNode, text) {
|
||
// // TODO: allow passing in the declarationLineNumber and other details to this function?
|
||
// let arr = splitTextAtSquareBlocks(text);
|
||
// let resultText = "";
|
||
// for(let e of arr) {
|
||
// if(e[0] === "[") {
|
||
// let jsExpr = e.substr(1, e.length-2);
|
||
// resultText += evaluateSquareBlock(rootNode, rootNode, jsExpr, {declarationLineNumber:null});
|
||
// } else {
|
||
// resultText += e;
|
||
// }
|
||
// }
|
||
// return resultText;
|
||
// }
|
||
|
||
function __getTextOddsDetails(text, ctxInfo={}) {
|
||
// JUST returns text on either side of unescaped "^" that is in a TEXT block, with some minor validation (just to help users debug)
|
||
|
||
let blocks = __splitTextAtAllBlocks(text, ctxInfo);
|
||
let blockI = 0;
|
||
let charI = 0;
|
||
let overallI = 0;
|
||
let currentBlock = blocks[0];
|
||
let inText = null;
|
||
function inTextBlock(checkI) {
|
||
// NOTE: we hold the state outside of the function so that we can start from where we left off
|
||
if(overallI > checkI) {
|
||
// start again if previous check state is past the current one
|
||
blockI = 0;
|
||
charI = 0;
|
||
overallI = 0;
|
||
currentBlock = blocks[0];
|
||
inText = null;
|
||
}
|
||
|
||
while(true) {
|
||
|
||
if(blockI > blocks.length-1) {
|
||
console.error("The checkI value (index to be checked to see if it's within a TEXT block) seems to be greater than the length of the whole text.");
|
||
return false;
|
||
}
|
||
|
||
// skip block if checkI doesn't occur within it
|
||
if(charI === 0) {
|
||
if(overallI + blocks[blockI].length-1 < checkI) {
|
||
overallI += blocks[blockI].length; //don't subtract 1 because that would put overallI at last character of current block - we want it to be at the first character of nect block
|
||
charI = 0; // not necessary since it already is zero, but just for expliciteness
|
||
blockI++; // only increase block index after adding block size to overallI
|
||
continue;
|
||
}
|
||
}
|
||
|
||
if(charI === 0) {
|
||
if(blocks[blockI][0] === "[" || blocks[blockI][0] === "{") {
|
||
inText = false;
|
||
} else {
|
||
inText = true;
|
||
}
|
||
}
|
||
|
||
if(overallI === checkI) {
|
||
return inText;
|
||
}
|
||
|
||
if(charI === blocks[blockI].length-1) { // if we've reached the end of a block
|
||
overallI++;
|
||
blockI++;
|
||
charI = 0;
|
||
} else {
|
||
charI++;
|
||
overallI++;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
//text = text.trim(); // <-- I commented this out because inline OR notation like { a ^1| b ^2} would return "a " or "b " instead or " a " or " b "
|
||
let escaped = false;
|
||
for(let i = 0; i < text.length; i++) {
|
||
if(i !== 0) {
|
||
if(text[i-1] !== "\\") { escaped = false; }
|
||
}
|
||
if(text[i] === "\\") { escaped = !escaped; }
|
||
|
||
if(!escaped && text[i] === NODE_ODDS_INDICATOR_CHARACTER && inTextBlock(i)) {
|
||
let odds = text.substr(i+1).trim();
|
||
|
||
// tiny bit of validation, just to help out users, but definitely not an full validation (which would be basically impossible to do, since we'd need to simulate every possible combination of potentially huge programs)
|
||
if(!/[!0-9\[\{]/.test(odds[0])) {
|
||
__perchanceError(`There is a problem with this odds declaration: "<b>${__escapeHTMLSpecialChars(odds)}</b>" (the full text of the line with the error is "${__escapeHTMLSpecialChars(text)}"). The text after the "^" character defines the chance that that item will be selected (the higher the number the greater the chance). Odds declarations should only contain numbers, mathematical/logical operators, and are also allowed to have curly and square bracket blocks which will evaluate to number characters (these will be computed on-the-fly). If you'd like to use the "^" character literally (i.e. not to declare odds), you need to put a backslash character before it like so: "\\^"`, ctxInfo);
|
||
return false;
|
||
}
|
||
|
||
return {
|
||
odds,
|
||
textWithoutOdds: text.substr(0,i), // don't trim() - allow caller to decide, since different notations have difference whitespace preferences
|
||
};
|
||
}
|
||
}
|
||
|
||
return false;
|
||
|
||
}
|
||
|
||
function __oddsTextToNumber(rootNode, thisRef, text, ctxInfo={}) {
|
||
|
||
// optimisations:
|
||
if(text === "1") { // default value:
|
||
return 1;
|
||
} else if(!/[^0-9]/.test(text)) { // all digits:
|
||
return Number(text);
|
||
} else if(String(Number(text)) === text) {
|
||
return Number(text);
|
||
} else {
|
||
|
||
// complex expressions:
|
||
|
||
// NOTE: there's an important distinction between converting primitive declarations to numbers,
|
||
// and converting odds declarations to numbers. We only convert primitive declarations to
|
||
// numbers if Number.toString() would return the same string anyway. On the other hand, odds
|
||
// declarations can contain strings with math symbols
|
||
let evaluatedText = __evaluateText(rootNode, thisRef, text, ctxInfo);
|
||
|
||
if(evaluatedText === "false") evaluatedText = "0";
|
||
else if(evaluatedText === "true") evaluatedText = "1";
|
||
|
||
// TODO: check that this works
|
||
if(/[^0-9\/*&|%!.\(\)e\-]/.test(evaluatedText)) {
|
||
__perchanceError(`Your odds declaration: "<b>${__escapeHTMLSpecialChars(text)}</b>", evaluated to: "<b>${__escapeHTMLSpecialChars(evaluatedText)}</b>" which contains characters that aren't allowed in odds declarations. The text after the "^" character defines the chance that that item will be selected (the higher the number the greater the chance). Odds declarations should only contain numbers, mathematical/logical operators, and are also allowed to have curly and square bracket blocks which will evaluate to number characters (these will be computed on-the-fly). If you'd like to use the "^" character literally (i.e. not to declare odds), you need to put a backslash character before it like so: "\\^"`, ctxInfo);
|
||
return false;
|
||
}
|
||
let num = false;
|
||
try { num = eval(evaluatedText); } catch(e) {/* no need to catch */}
|
||
return num;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
function __splitTextAtSquareBlocks(text, ctxInfo={}) {
|
||
|
||
if(!text.includes("[") && !text.includes("]")) return [text];
|
||
|
||
let escaped = false;
|
||
let unclosedBracketCount = 0;
|
||
let inJSExpr = false;
|
||
let inJSExprString1 = false, inJSExprString2 = false, inJSExprString3 = false;
|
||
let expressionArray = [];
|
||
for(let i = 0; i < text.length; i++) {
|
||
if(i !== 0) {
|
||
if(text[i-1] !== "\\") { escaped = false; }
|
||
}
|
||
if(text[i] === "\\") { escaped = !escaped; }
|
||
|
||
// skip strings in js expressions (square brackets in strings would mess
|
||
// with our unclosedBracketCount):
|
||
if(inJSExpr && !inJSExprString1 && !inJSExprString2 && !inJSExprString3 && !escaped && text[i] === "\"") { inJSExprString1 = true; continue; }
|
||
if(inJSExprString1 && !escaped && text[i] !== "\"") { continue; }
|
||
if(inJSExprString1 && !escaped && text[i] === "\"") { inJSExprString1 = false; continue; }
|
||
|
||
if(inJSExpr && !inJSExprString1 && !inJSExprString2 && !inJSExprString3 && !escaped && text[i] === "'") { inJSExprString2 = true; continue; }
|
||
if(inJSExprString2 && !escaped && text[i] !== "'") { continue; }
|
||
if(inJSExprString2 && !escaped && text[i] === "'") { inJSExprString2 = false; continue; }
|
||
|
||
if(inJSExpr && !inJSExprString1 && !inJSExprString2 && !inJSExprString3 && !escaped && text[i] === "`") { inJSExprString3 = true; continue; }
|
||
if(inJSExprString3 && !escaped && text[i] !== "`") { continue; }
|
||
if(inJSExprString3 && !escaped && text[i] === "`") { inJSExprString3 = false; continue; }
|
||
|
||
// skip escaped brackets within js expressions (i.e. within regex declarations):
|
||
if(inJSExpr && escaped && (text[i] === "[" || text[i] === "]")) { continue; }
|
||
|
||
if(!escaped && text[i] === "[") {
|
||
unclosedBracketCount++;
|
||
// if we weren't already inJSExpr, then this is the start of the a JSExpr:
|
||
if(!inJSExpr && i !== 0) {
|
||
expressionArray.push(text.substr(0, i));
|
||
text = text.substr(i);
|
||
i = 0; // will be incremented to 0 on next loop, as required (we've already processed the first char, "[")
|
||
}
|
||
inJSExpr = true;
|
||
continue;
|
||
}
|
||
|
||
if(!escaped && text[i] === "]") {
|
||
unclosedBracketCount--;
|
||
// we're only out of the js expression when we've closed all brackets
|
||
if(inJSExpr && unclosedBracketCount === 0) {
|
||
inJSExpr = false;
|
||
expressionArray.push(text.substr(0, i+1));
|
||
text = text.substr(i+1);
|
||
i = -1; // will be incremented to 0 on next loop as required (we haven't yet processed the first character of the new string (the character after "]"))
|
||
}
|
||
}
|
||
|
||
// last expression:
|
||
if(i === text.length-1 && text.length !== 0) {
|
||
expressionArray.push(text);
|
||
}
|
||
}
|
||
|
||
if(unclosedBracketCount !== 0) {
|
||
__perchanceError(`It appears that you've got a <b>mismatch in your opening and closing square brackets</b>${ctxInfo.declarationLineNumber ? ` on <b>line number ${ctxInfo.declarationLineNumber}</b>` : ""}. For each opening square bracket, there should be a closing one. If you'd like to use a <i>literal</i> square bracket (i.e. you want to actually display one, rather than using them to output a random list item, then you need to put a "backslash" before it like "\\[ ... \\]". Here's the text that seems to be causing the error: <blockquote>${__escapeHTMLSpecialChars(text)}</blockquote>`, ctxInfo);
|
||
return false;
|
||
}
|
||
|
||
return expressionArray;
|
||
|
||
}
|
||
|
||
|
||
function __getInlineFunctionDetails(lineText) {
|
||
let isAsync = false;
|
||
if(lineText.startsWith("async ")) {
|
||
isAsync = true;
|
||
lineText = lineText.substr(6);
|
||
}
|
||
let escaped = false;
|
||
let openIndex, opened = false;
|
||
let closeIndex, closed = false;
|
||
for(let i = 0; i < lineText.length; i++) {
|
||
if(i !== 0) {
|
||
if(lineText[i-1] !== "\\") { escaped = false; }
|
||
}
|
||
if(lineText[i] === "\\") { escaped = !escaped; }
|
||
if(lineText[i] === "(" && !escaped) { opened = true; openIndex = i; }
|
||
if(lineText[i] === ")" && !escaped && opened) { closed = true; closeIndex = i; }
|
||
if(lineText[i] === "=" && !escaped && opened && closed && lineText[i+1] === ">") {
|
||
let argString = lineText.substr(openIndex+1, closeIndex-openIndex-1);
|
||
let args = argString.split(",").map(a => a.trim());
|
||
let name = lineText.substr(0, openIndex).trim();
|
||
let body = lineText.substr(i+2).trim();
|
||
if(name.trim() === "") { return false; }
|
||
if(body.trim() === "") { return false; }
|
||
if(__areValidFunctionArguments(args) || argString === "") {
|
||
if(!__isValidJavaScriptIdentifier(name)) return false;
|
||
args = args.filter(a => a !== ""); // for zero arg case
|
||
return { args, name, body, isAsync };
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
function __getFunctionHeaderDetails(lineText) {
|
||
let isAsync = false;
|
||
if(lineText.startsWith("async ")) {
|
||
isAsync = true;
|
||
lineText = lineText.substr(6);
|
||
}
|
||
lineText = lineText.trim();
|
||
let l = lineText.length;
|
||
if(lineText[l-2] === "=" && lineText[l-1] === ">") {
|
||
lineText = lineText.substr(0, l-2).trim();
|
||
l = lineText.length;
|
||
} else {
|
||
return false;
|
||
}
|
||
|
||
let escaped = false;
|
||
let opened = false;
|
||
let openIndex;
|
||
for(let i = 0; i < lineText.length; i++) {
|
||
if(i !== 0) {
|
||
if(lineText[i-1] !== "\\") { escaped = false; }
|
||
}
|
||
if(lineText[i] === "\\") { escaped = !escaped; }
|
||
if(lineText[i] === "(" && !escaped) { opened = true; openIndex = i; }
|
||
if(lineText[i] === ")" && !escaped && opened) {
|
||
let argString = lineText.substr(openIndex+1, i-openIndex-1);
|
||
let args = argString.split(",").map(a => a.trim());
|
||
let name = lineText.substr(0, openIndex).trim();
|
||
if(name.trim() === "") { return false; }
|
||
if(__areValidFunctionArguments(args) || argString === "") {
|
||
if(!__isValidJavaScriptIdentifier(name)) return false;
|
||
args = args.filter(a => a !== ""); // for zero arg case
|
||
return { args, name, isAsync };
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function __areValidFunctionArguments(args) {
|
||
for(let a of args) {
|
||
if(!__isValidJavaScriptIdentifier(a.replace("...","").replace("=",""))) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
function __isValidJavaScriptIdentifier(str) {
|
||
return /^(?!(?:do|if|in|for|let|new|try|var|case|else|enum|eval|null|this|true|void|with|await|break|catch|class|const|false|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$)(?:[\$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D])(?:[\$0-9A-Z_a-z\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF])*$/.test(str);
|
||
}
|
||
|
||
function __getPrimitiveNodeDetails(lineText) {
|
||
// NOTE: this function interprets some strings as numbers and casts them using Number()
|
||
// note that this is *just a shorthand*. The reason it's okay to do is because it
|
||
// only interprets strings as numbers if Number(that_number).toString() would return
|
||
// the same string anyway. If the user wants to do something like:
|
||
// prop = [this.age]/[this.height]
|
||
// then they should do this instead:
|
||
// prop = [this.age/this.height]
|
||
// because the prior will return something like "10/140" (i.e. a string, rather than a number)
|
||
|
||
// remember: the lineText could have square blocks which can of course have equals signs in them.
|
||
// But since primitive node keys can't be dynamic we can just return false if we see an unescaped square
|
||
// or curly bracket before we find an unescaped equals sign
|
||
|
||
let escaped = false;
|
||
for(let i = 0; i < lineText.length; i++) {
|
||
if(i !== 0) {
|
||
if(lineText[i-1] !== "\\") { escaped = false; }
|
||
}
|
||
if(lineText[i] === "\\") { escaped = !escaped; }
|
||
|
||
if((lineText[i] === "[" || lineText[i] === "{") && !escaped) {
|
||
// found square or curly block before unescaped equals sign, so it's not a primitive node
|
||
return false;
|
||
}
|
||
|
||
if(lineText[i] === "=" && !escaped) {
|
||
let key = lineText.substr(0, i).trim();
|
||
let valueText = lineText.substr(i+1).trim();
|
||
if(key === "" || valueText === "") {
|
||
return false;
|
||
}
|
||
|
||
let value;
|
||
if(valueText === String(Number(valueText))) {
|
||
value = Number(valueText);
|
||
} else if(valueText === "true") { // TODO: test that this works (with filter/where, etc.)
|
||
value = true;
|
||
} else if(valueText === "false") {
|
||
value = false;
|
||
} else {
|
||
value = valueText;
|
||
}
|
||
|
||
return {key, value};
|
||
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
// function isMostLikelyAnIntentionalNumericString(valueText) {
|
||
// if(isNaN(valueText)) { return false; }
|
||
// if(/[^0-9.\-]+/.test(valueText)) { return false; }
|
||
// if(valueText.split("-").length > 2) { return false; }
|
||
// if(valueText.split(".").length > 2) { return false; }
|
||
//
|
||
// if(valueText.split("-").length === 2) {
|
||
// if(valueText[0] !== "-") { return false; }
|
||
// if(valueText[0] === "-" && valueText[1] === ".") { return false; }
|
||
// }
|
||
//
|
||
// if(valueText.split(".").length === 2) {
|
||
// if(valueText[0] === ".") { return false; }
|
||
// if(valueText[valueText.length-1] === ".") { return false; }
|
||
//
|
||
// let beforeDecimal = valueText.split(".")[0];
|
||
// let afterDecimal = valueText.split(".")[1];
|
||
// if(afterDecimal[afterDecimal.length-1] === "0") { return false; } // e.g. 20.0 shouldn't be treated as a number (they'd have just put in "20")
|
||
// if(beforeDecimal[0] === "0" && beforeDecimal.length > 1) { return false; } // e.g. 020 shouldn't be treated as a number
|
||
// }
|
||
//
|
||
// return true;
|
||
//
|
||
// }
|
||
|
||
|
||
function __splitTextAtCurlyBlocks(text, ctxInfo={}) {
|
||
// remember: we must ignore curly brackets if we're inside a js expression
|
||
|
||
if(!text.includes("{") && !text.includes("}")) return [text];
|
||
|
||
let escaped = false;
|
||
let lastCurlyOpenIndex = null;
|
||
|
||
let inJSExpr = false;
|
||
let unclosedSquareBracketCount = 0;
|
||
let inJSExprString1 = false;
|
||
let inJSExprString2 = false;
|
||
let inJSExprString3 = false;
|
||
|
||
let inCurlyExpr = false;
|
||
let unclosedCurlyBracketCount = 0;
|
||
|
||
let blocks = [];
|
||
|
||
for(let i = 0; i < text.length; i++) {
|
||
if(i !== 0) {
|
||
if(text[i-1] !== "\\") { escaped = false; }
|
||
}
|
||
if(text[i] === "\\") { escaped = !escaped; }
|
||
|
||
////////////////////////////////////
|
||
// skip strings in js expressions //
|
||
////////////////////////////////////
|
||
//(square brackets in strings would mess with our unclosedSquareBracketCount which we use to skip js expressions):
|
||
if(inJSExpr && !inJSExprString1 && !inJSExprString2 && !inJSExprString3 && !escaped && text[i] === "\"") { inJSExprString1 = true; continue; }
|
||
if(inJSExprString1 && !escaped && text[i] !== "\"") { continue; }
|
||
if(inJSExprString1 && !escaped && text[i] === "\"") { inJSExprString1 = false; continue; }
|
||
|
||
if(inJSExpr && !inJSExprString1 && !inJSExprString2 && !inJSExprString3 && !escaped && text[i] === "'") { inJSExprString2 = true; continue; }
|
||
if(inJSExprString2 && !escaped && text[i] !== "'") { continue; }
|
||
if(inJSExprString2 && !escaped && text[i] === "'") { inJSExprString2 = false; continue; }
|
||
|
||
if(inJSExpr && !inJSExprString1 && !inJSExprString2 && !inJSExprString3 && !escaped && text[i] === "`") { inJSExprString3 = true; continue; }
|
||
if(inJSExprString3 && !escaped && text[i] !== "`") { continue; }
|
||
if(inJSExprString3 && !escaped && text[i] === "`") { inJSExprString3 = false; continue; }
|
||
|
||
// skip escaped brackets within js expressions (i.e. escaped brackets within regex declarations):
|
||
if(inJSExpr && /*--->*/escaped/*<---*/ && (text[i] === "[" || text[i] === "]")) { continue; }
|
||
|
||
/////////////////////////////////////
|
||
// skip JS expressions //
|
||
/////////////////////////////////////
|
||
// note that we're guarunteed to NOT be in a string for this block (since the
|
||
// above block skips strings while we're in js expressions)
|
||
if(!inJSExpr && text[i] === "[" && !escaped) {
|
||
inJSExpr = true;
|
||
unclosedSquareBracketCount++;
|
||
continue;
|
||
}
|
||
if(inJSExpr && text[i] === "[") { // `escaped` is irrelevant, we're inJSExpr and not in string
|
||
unclosedSquareBracketCount++;
|
||
continue;
|
||
}
|
||
if(inJSExpr && text[i] === "]") { // `escaped` is irrelevant, we're inJSExpr and not in string
|
||
unclosedSquareBracketCount--;
|
||
if(unclosedSquareBracketCount === 0) { inJSExpr = false; }
|
||
}
|
||
|
||
|
||
//////////////////////////////////////
|
||
// extract curly blocks //
|
||
//////////////////////////////////////
|
||
if(text[i] === "{" && !escaped && !inJSExpr) {
|
||
unclosedCurlyBracketCount++;
|
||
// if we're not yet in a curly expression, then this is the start of one:
|
||
if(!inCurlyExpr && i !== 0) {
|
||
blocks.push(text.substr(0, i));
|
||
text = text.substr(i);
|
||
i = 0;
|
||
}
|
||
inCurlyExpr = true;
|
||
continue;
|
||
}
|
||
if(text[i] === "}" && !escaped && !inJSExpr) {
|
||
unclosedCurlyBracketCount--;
|
||
// we're only out of the curly expression when we've closed all curly brackets that were opened
|
||
if(inCurlyExpr && unclosedCurlyBracketCount === 0) {
|
||
blocks.push(text.substr(0, i+1));
|
||
text = text.substr(i+1);
|
||
i = -1;
|
||
inCurlyExpr = false;
|
||
}
|
||
}
|
||
|
||
// add last expression (if it didn't end in a curly block - in that case text.length === 0)
|
||
if(i === text.length-1 && text.length !== 0) {
|
||
blocks.push(text);
|
||
}
|
||
|
||
}
|
||
|
||
if(unclosedSquareBracketCount !== 0) {
|
||
__perchanceError(`It appears that you've got <b>a mismatch in your opening and closing square brackets</b>${ctxInfo.declarationLineNumber ? ` on <b>line number ${ctxInfo.declarationLineNumber}</b>` : ""}. For each opening square bracket, there should be a closing one. If you'd like to use a <i>literal</i> square bracket (i.e. you want to actually display one, rather than using them to output a random list item, then you need to put a "backslash" before it like "\\[ ... \\]". Here's the text that seems to be causing the error: <blockquote>${__escapeHTMLSpecialChars(text)}</blockquote>`, ctxInfo);
|
||
return ["(syntax error)"];
|
||
}
|
||
|
||
if(unclosedCurlyBracketCount !== 0) {
|
||
__perchanceError(`It appears that you've got <b>a mismatch in your opening and closing curly brackets</b>${ctxInfo.declarationLineNumber ? ` on <b>line number ${ctxInfo.declarationLineNumber}</b>` : ""}. For each opening curly bracket, there should be a closing one. If you'd like to use a <i>literal</i> curly bracket (i.e. you want to actually display one, rather than using them to do {import:noun} and stuff like that, then you need to put a "backslash" before it like "\\{ ... \\}". Here's the text that seems to be causing the error: <blockquote>${__escapeHTMLSpecialChars(text)}</blockquote>`, ctxInfo);
|
||
return ["(syntax error)"];
|
||
}
|
||
|
||
|
||
return blocks;
|
||
|
||
}
|
||
|
||
function __splitTextAtAllBlocks(text, ctxInfo={}) {
|
||
let curlySplitParts = __splitTextAtCurlyBlocks(text, ctxInfo);
|
||
let blocks = []; // this array will contain curly blocks, text blocks, and square blocks
|
||
for(let part of curlySplitParts) {
|
||
if(part[0] !== "{") {
|
||
let squareSplitParts = __splitTextAtSquareBlocks(part, ctxInfo);
|
||
if(squareSplitParts) {
|
||
blocks.push(...squareSplitParts);
|
||
} else {
|
||
console.error("Something is wrong?");
|
||
}
|
||
} else {
|
||
blocks.push(part);
|
||
}
|
||
}
|
||
return blocks;
|
||
}
|
||
|
||
|
||
function __stripCommentFromLine(line) {
|
||
// NOTE: comment must either start at start of line, or have a space before it.
|
||
// e.g. in http://example.com , "//example.com" isn't considered a comment because
|
||
// it doesn't have a preceding space
|
||
let i, escaped = false;
|
||
for(i = 0; i < line.length; i++) {
|
||
if(i !== 0) {
|
||
if(line[i-1] !== "\\") { escaped = false; }
|
||
}
|
||
if(line[i] === "\\") { escaped = !escaped; }
|
||
if(line[i] === "/" && !escaped && line[i+1] === "/") {
|
||
if(i === 0) {
|
||
break;
|
||
} else {
|
||
if(line[i-1] === " " || line[i-1] === "\t") {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return line.substr(0,i);
|
||
}
|
||
|
||
|
||
|
||
function __normaliseLineIndentsToTabs(line) {
|
||
let i, eqSpaceCount = 0; //equivalent spaces (1 tab = 2 spaces)
|
||
for(i = 0; i < line.length; i++) {
|
||
if(line[i] === " ") { eqSpaceCount++; }
|
||
else if(line[i] === "\t") { eqSpaceCount += 2; }
|
||
else { break; }
|
||
}
|
||
if(eqSpaceCount%2 !== 0) {
|
||
return false; //odd number of spaces
|
||
} else {
|
||
return "\t".repeat(parseInt(eqSpaceCount/2)) + line.substr(i);
|
||
}
|
||
}</script> <script>Object.defineProperty(String.prototype, "titleCase", {get:__titleCaseMethod});
|
||
Object.defineProperty(Number.prototype, "titleCase", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "titleCase", {get:function(){return this.valueOf();}});
|
||
|
||
Object.defineProperty(String.prototype, "sentenceCase", {get:__sentenceCaseMethod});
|
||
Object.defineProperty(Number.prototype, "sentenceCase", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "sentenceCase", {get:function(){return this.valueOf();}});
|
||
|
||
Object.defineProperty(String.prototype, "upperCase", {get:__upperCaseMethod});
|
||
Object.defineProperty(Number.prototype, "upperCase", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "upperCase", {get:function(){return this.valueOf();}})
|
||
|
||
Object.defineProperty(String.prototype, "lowerCase", {get:__lowerCaseMethod});
|
||
Object.defineProperty(Number.prototype, "lowerCase", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "lowerCase", {get:function(){return this.valueOf();}});
|
||
|
||
Object.defineProperty(String.prototype, "replaceText", {value:__replaceTextMethod});
|
||
Object.defineProperty(Number.prototype, "replaceText", {value:__replaceTextMethod});
|
||
Object.defineProperty(Boolean.prototype, "replaceText", {value:__replaceTextMethod});
|
||
|
||
Object.defineProperty(String.prototype, "pastTense", {get:__pastTenseMethod});
|
||
Object.defineProperty(Number.prototype, "pastTense", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "pastTense", {get:function(){return this.valueOf();}});
|
||
|
||
Object.defineProperty(String.prototype, "presentTense", {get:__presentTenseMethod});
|
||
Object.defineProperty(Number.prototype, "presentTense", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "presentTense", {get:function(){return this.valueOf();}});
|
||
|
||
Object.defineProperty(String.prototype, "futureTense", {get:__futureTenseMethod});
|
||
Object.defineProperty(Number.prototype, "futureTense", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "futureTense", {get:function(){return this.valueOf();}});
|
||
|
||
Object.defineProperty(String.prototype, "getSelf", {get:function() { return this+""; }});
|
||
Object.defineProperty(Number.prototype, "getSelf", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "getSelf", {get:function(){return this.valueOf();}});
|
||
|
||
Object.defineProperty(String.prototype, "getOdds", {get:function() { return 1; }});
|
||
Object.defineProperty(Number.prototype, "getOdds", {get:function(){ return 1; }});
|
||
Object.defineProperty(Boolean.prototype, "getOdds", {get:function(){ return 1; }});
|
||
|
||
// WHAT IS THIS?
|
||
Object.defineProperty(String.prototype, "getName", {get:function() {
|
||
return this+"";
|
||
}});
|
||
Object.defineProperty(Number.prototype, "getName", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "getName", {get:function(){return this.valueOf();}})
|
||
|
||
|
||
Object.defineProperty(String.prototype, "evaluateItem", {get:function() {
|
||
let r = window.__currentEvaluateSquareBlockRoot ? window.__currentEvaluateSquareBlockRoot : root; // so imported generators use their own root
|
||
let out = __evaluateText(r, r, this.valueOf(), {declarationLineNumber:null});
|
||
if(window.generatorLastEditTime > 1716337636385) { // May 22nd 2024 bugfix, ensures only generators edited after this time get it, to prevent breaking old generators that rely on the bug
|
||
out = __processEscapedCharacters(out);
|
||
}
|
||
if(String(Number(out)) === out) {
|
||
out = Number(out);
|
||
}
|
||
return out;
|
||
}});
|
||
Object.defineProperty(Number.prototype, "evaluateItem", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "evaluateItem", {get:function(){return this.valueOf();}});
|
||
|
||
Object.defineProperty(String.prototype, Symbol.toPrimitive, {value:function(hint) {
|
||
return this.valueOf();
|
||
}});
|
||
// i don't think these two are necessary?
|
||
Object.defineProperty(Number.prototype, Symbol.toPrimitive, {value:function(hint) {
|
||
return this.valueOf();
|
||
}});
|
||
Object.defineProperty(Boolean.prototype, Symbol.toPrimitive, {value:function(hint) {
|
||
return this.valueOf();
|
||
}});
|
||
|
||
|
||
Object.defineProperty(String.prototype, "selectMany", {value:__selectManyMethodStringNum});
|
||
Object.defineProperty(Number.prototype, "selectMany", {value:__selectManyMethodStringNum});
|
||
Object.defineProperty(Boolean.prototype, "selectMany", {value:__selectManyMethodStringNum});
|
||
function __selectManyMethodStringNum(num) {
|
||
let arr = [];
|
||
for(let i = 0; i < num; i++) {
|
||
arr.push(this.selectOne);
|
||
}
|
||
// overwrite default array behaviour (selects a random one)
|
||
// in the case where they don't specify a join() after the repeat:
|
||
arr.toString = function() { return this.join(""); };
|
||
return arr;
|
||
}
|
||
|
||
Object.defineProperty(String.prototype, "selectOne", {get:function() {
|
||
let r = window.__currentEvaluateSquareBlockRoot ? window.__currentEvaluateSquareBlockRoot : root; // so imported generators use their own root
|
||
let out = __evaluateText(r, r, this.valueOf(), {declarationLineNumber:null}); // so you can write e.g. [n = "{1-20}".selectOne]
|
||
if(window.generatorLastEditTime > 1716337636385) { // May 22nd 2024 bugfix, ensures only generators edited after this time get it, to prevent breaking old generators that rely on the bug
|
||
out = __processEscapedCharacters(out);
|
||
}
|
||
if(String(Number(out)) === out) {
|
||
out = Number(out);
|
||
}
|
||
return out;
|
||
}});
|
||
Object.defineProperty(Number.prototype, "selectOne", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "selectOne", {get:function(){return this.valueOf();}});
|
||
|
||
Object.defineProperty(String.prototype, "singularForm", {get:function(n) {
|
||
let input = this;
|
||
let output = __nlpCompromise(input).nouns().toSingular().out("text");
|
||
return output === "" ? input : output;
|
||
}});
|
||
Object.defineProperty(Number.prototype, "singularForm", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "singularForm", {get:function(){return this.valueOf();}});
|
||
|
||
Object.defineProperty(String.prototype, "pluralForm", {get:function(n) {
|
||
let input = this;
|
||
let output = __nlpCompromise(input).nouns().toPlural().out("text");
|
||
return output === "" ? input : output;
|
||
}});
|
||
Object.defineProperty(Number.prototype, "pluralForm", {get:function(){return this.valueOf();}});
|
||
Object.defineProperty(Boolean.prototype, "pluralForm", {get:function(){return this.valueOf();}});
|
||
|
||
// TODO***: add the rest of the node methods here and to Array (e.g. pastTense, etc.)
|
||
|
||
// Object.defineProperty(String.prototype, "shuffleCharacters", {value:function(numShuffles) {
|
||
//
|
||
// if(numShuffles === undefined) {
|
||
//
|
||
// var array = this.split("");
|
||
// var currentIndex = array.length, temporaryValue, randomIndex;
|
||
// // While there remain elements to shuffle...
|
||
// while (0 !== currentIndex) {
|
||
// // Pick a remaining element...
|
||
// randomIndex = Math.floor(Math.random() * currentIndex);
|
||
// currentIndex -= 1;
|
||
// // And swap it with the current element.
|
||
// temporaryValue = array[currentIndex];
|
||
// array[currentIndex] = array[randomIndex];
|
||
// array[randomIndex] = temporaryValue;
|
||
// }
|
||
// return array.join("")
|
||
//
|
||
// } else {
|
||
//
|
||
// let array = this.split("");
|
||
// for(let i = 0; i < numShuffles; i++) {
|
||
// let i1 = Math.floor(array.length*Math.random());
|
||
// let i2 = Math.floor(array.length*Math.random());
|
||
// let c1 = array[i1];
|
||
// let c2 = array[i2];
|
||
// array[i1] = c2;
|
||
// array[i2] = c1;
|
||
// }
|
||
// return array.join("");
|
||
// // TODO: why not join back into a string?
|
||
//
|
||
// }
|
||
//
|
||
// }});</script> <script>Array.prototype.toString = function () {
|
||
// default behaviour of arrays when converting to string is to choose a random element.
|
||
// altering the toString method is how you make it not do this by default (this is how selectMany works)
|
||
// let items = [];
|
||
// for(let item of this) {
|
||
// items.push(item+"");
|
||
// }
|
||
// return chooseRandomTextByOdds(window.root, window.root, items);
|
||
if(this.length === 0) return "";
|
||
|
||
return this.selectOne+""; // should this be `this.selectOne.toString({keepEscapes:true})` ?
|
||
};
|
||
|
||
Object.defineProperty(Array.prototype, "getOdds", {get:function() { return 1; }});
|
||
Object.defineProperty(Array.prototype, "getSelf", {get:function() { return this; }});
|
||
Object.defineProperty(Array.prototype, "getLength", {get:function() { return this.length; }});
|
||
|
||
Object.defineProperty(Array.prototype, "consumableList", {get:function() {
|
||
|
||
let proxy = new Proxy(this, {
|
||
// alreadyConsumedItems: new Set(),
|
||
alreadyConsumedIndices: new Set(), // NOTE: we need this (unlike in the addNodeMethods.js case where we use alreadyConsumedItems) because an array can contain duplicates of the same item: lemmy.world/post/6207000 but we should treat them as separate items.
|
||
get: function(target, property) {
|
||
if(property === "selectOne") {
|
||
let selectedNode = __arraySelectOneMethod.bind(proxy)();
|
||
// if(selectedNode) { // consumption is done in __arraySelectOneMethod now
|
||
// this.alreadyConsumedItems.add(selectedNode);
|
||
// }
|
||
return selectedNode;
|
||
}/* else if(property === "$alreadyConsumedItems") {
|
||
return this.alreadyConsumedItems;
|
||
}*/ else if(property === "$alreadyConsumedIndices") {
|
||
return this.alreadyConsumedIndices;
|
||
} else if(property === "getLength") {
|
||
// return target.length - this.alreadyConsumedItems.size;
|
||
return target.length - this.alreadyConsumedIndices.size;
|
||
} else {
|
||
// TODO: strangely, the return value here seems to be automatically bound to this proxy.
|
||
// so it also handles toString and valueOf methods like we want it to
|
||
return target[property];
|
||
}
|
||
},
|
||
});
|
||
return proxy;
|
||
|
||
}});
|
||
|
||
Object.defineProperty(Array.prototype, "selectAll", {get: function() {
|
||
return this;
|
||
}});
|
||
|
||
Object.defineProperty(Array.prototype, "selectMany", {value:__selectManyMethod});
|
||
|
||
Object.defineProperty(Array.prototype, "selectUnique", {value: function(...args) {
|
||
return this.consumableList.selectMany(...args);
|
||
}});
|
||
|
||
let __arraySelectOneMethod = function() {
|
||
//return this[Math.floor(Math.random()*this.length)];
|
||
let candidates = []; /*{item, odds}*/
|
||
for(let i = 0; i < this.length; i++) {
|
||
if(this.$alreadyConsumedIndices && this.$alreadyConsumedIndices.has(i)) continue;
|
||
let a = this[i];
|
||
if(a.$nodeType) { // if it's a node
|
||
candidates.push({item:a, odds:a.$odds, index:i});
|
||
} else if(typeof a === 'string') {
|
||
let details = __getTextOddsDetails(a);
|
||
if(details && (details.odds.includes("[") || details.odds.includes("{"))) details.odds = details.odds.evaluateItem; // don't need the if statement, but it's better for performance
|
||
let odds = details ? Number(details.odds) : 1; // <-- this doesn't allow dynamic odds notation in arrays. Can always add it later if it turns out that it would be useful.
|
||
|
||
if(odds < 0 || isNaN(odds)) {
|
||
__perchanceError(`The odds of ${a} has evaluated to ${odds < 0 ? "a negative number" : "a non-number"}. It's item number ${i} in the list (the list that starts with ${this[0]}). You may have created this list with selectAll or selectUnique.`);
|
||
}
|
||
|
||
let item = details ? details.textWithoutOdds : a;
|
||
candidates.push({item, odds, index:i});
|
||
} else {
|
||
candidates.push({item:a, odds:1, index:i});
|
||
}
|
||
}
|
||
|
||
// if(this.$alreadyConsumedItems) { // this doesn't make sense because an array can contain duplicates of the same node: lemmy.world/post/6207000
|
||
// candidates = candidates.filter(c => !this.$alreadyConsumedItems.has(c.item));
|
||
// }
|
||
|
||
let oddsTotal = candidates.reduce((a,v) => { return a+v.odds; }, 0);
|
||
let stopOddsSum = oddsTotal*Math.random();
|
||
|
||
let oddsRunningSum = 0;
|
||
for(let c of candidates) {
|
||
oddsRunningSum += c.odds;
|
||
if(oddsRunningSum >= stopOddsSum) {
|
||
if(this.$alreadyConsumedIndices) this.$alreadyConsumedIndices.add(c.index);
|
||
return c.item;
|
||
}
|
||
}
|
||
|
||
if(this.$alreadyConsumedIndices) {
|
||
__perchanceError("It looks like your <code>consumableList</code> ran out of items. This is the list in question: "+this.slice(0, 100).join(", "));
|
||
} else {
|
||
__perchanceError("Something went wrong! <code>Error: selectOne from array returned nothing.</code> Please report this on <a href='https://lemmy.world/c/perchance'>lemmy.world/c/perchance</a> since it's likely a bug with the engine.");
|
||
}
|
||
|
||
};
|
||
Object.defineProperty(Array.prototype, "selectOne", {get:__arraySelectOneMethod});
|
||
|
||
|
||
Object.defineProperty(Array.prototype, Symbol.toPrimitive, {value:function(hint) {
|
||
return this.toString();
|
||
}});
|
||
|
||
// don't need this because we've got joinItems, right?
|
||
// Object.defineProperty(Array.prototype, "evaluateItem", {get:function() {
|
||
// return this.toString();
|
||
// }});
|
||
|
||
Object.defineProperty(Array.prototype, "joinItems", {value:function(str="") {
|
||
return this.join(str);
|
||
}});
|
||
|
||
Object.defineProperty(Array.prototype, "sumItems", {get:function() {
|
||
return this.reduce((a, v) => a+v.evaluateItem, 0);
|
||
}});
|
||
|
||
|
||
// TODO***: make all methods configurable like in nodeMethods?
|
||
|
||
Object.defineProperty(Array.prototype, "pluralForm", {get:function() {
|
||
return this.map(a => a.pluralForm);
|
||
}});
|
||
Object.defineProperty(Array.prototype, "singularForm", {get:function() {
|
||
return this.map(a => a.singularForm);
|
||
}});
|
||
|
||
Object.defineProperty(Array.prototype, "pastTense", {get:function() {
|
||
return this.map(a => a.pastTense);
|
||
}});
|
||
Object.defineProperty(Array.prototype, "presentTense", {get:function() {
|
||
return this.map(a => a.presentTense);
|
||
}});
|
||
Object.defineProperty(Array.prototype, "futureTense", {get:function() {
|
||
return this.map(a => a.futureTense);
|
||
}});
|
||
|
||
Object.defineProperty(Array.prototype, "titleCase", {get:function() {
|
||
return this.map(a => a.titleCase);
|
||
}});
|
||
Object.defineProperty(Array.prototype, "upperCase", {get:function() {
|
||
return this.map(a => a.upperCase);
|
||
}});
|
||
Object.defineProperty(Array.prototype, "lowerCase", {get:function() {
|
||
return this.map(a => a.lowerCase);
|
||
}});
|
||
Object.defineProperty(Array.prototype, "sentenceCase", {get:function() {
|
||
return this.map(a => a.sentenceCase);
|
||
}});
|
||
|
||
Object.defineProperty(Array.prototype, "replaceText", {value:function(p1, p2, p3) {
|
||
return this.map(a => a.replaceText(p1, p2, p3));
|
||
}});</script> <script>let __curlyFunctions = [__curlyFunction_Or, __curlyFunction_Import, __curlyFunction_Range, __curlyFunction_S, __curlyFunction_A];
|
||
|
||
|
||
function __curlyFunction_Import(rootNode, thisRef, text, leftBlocks, rightBlocks, ctxInfo) {
|
||
if(!text.includes(":")) return false;
|
||
let match = /^import:([a-z0-9\-]+)$/.exec(text);
|
||
if(!match) {
|
||
return false;
|
||
} else {
|
||
let moduleName = match[1];
|
||
let moduleRef = rootNode.$moduleSpace[moduleName];
|
||
if( moduleRef ) {
|
||
return moduleRef;
|
||
} else {
|
||
__perchanceError(`You've tried to import a generator that doesn't exist. The generator named '${__escapeHTMLSpecialChars(moduleName)}' was not found. You can see for yourself by visiting that generator: <a href="/${moduleName}">${moduleName}</a>. There's a <a href="/useful-generators">list of useful generators</a> that may help you find what you're looking for.`, ctxInfo);
|
||
return `(cannot find generator '${moduleName}')`;
|
||
}
|
||
}
|
||
}
|
||
|
||
function __curlyFunction_A(rootNode, thisRef, text, leftBlocks, rightBlocks) {
|
||
if(text === "a" || text === "A") {
|
||
let right = __removeHtmlTagsFromBlocksArray(rightBlocks); //rightBlocks.filter(b => b.replace(/<[^>]+?>/g, '').trim() !== "");
|
||
if(right[0] === undefined || (right[0] && (right[0].trim()[0] === "{"|| right[0].trim()[0] === "["))) {
|
||
return text === "a" ? "{a}" : "{A}";
|
||
} else {
|
||
let aOrAn = __AvsAnSimple.query(right[0].trim().replace(/<[^>]+?>/g, '').split(/[\s$%&*@#,!=+\-.?:;'"(){}\[\]\/<>`~_|]/g)[0].trim());
|
||
if(text === "A") {
|
||
if(aOrAn === "a") aOrAn = "A";
|
||
else aOrAn = "An";
|
||
}
|
||
return aOrAn;
|
||
}
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function __curlyFunction_Range(rootNode, thisRef, text, leftBlocks, rightBlocks) {
|
||
if(!text.includes("-")) return false;
|
||
|
||
let match;
|
||
|
||
// TODO: written numbers: {twenty-fifty five} ?
|
||
// TODO: custom increments: {0-100:0.5} ? not sure about notation yet
|
||
|
||
// {1-10}
|
||
match = /^([0-9]+)-([0-9]+)$/.exec(text);
|
||
if(match) {
|
||
let min = Number(match[1]);
|
||
let max = Number(match[2]);
|
||
if(min > max) { [min, max] = [max, min]; }
|
||
return Math.floor(Math.random() * (max - min + 1) + min); // we do not talk about what was here before
|
||
}
|
||
|
||
// {a-z}
|
||
match = /^([a-z])-([a-z])$/.exec(text);
|
||
if(match) {
|
||
let min = Number(match[1].charCodeAt(0));
|
||
let max = Number(match[2].charCodeAt(0));
|
||
if(min > max) { [min, max] = [max, min]; }
|
||
return String.fromCharCode( min+Math.round(Math.random()*(max-min)) );
|
||
}
|
||
|
||
// {A-Z}
|
||
match = /^([A-Z])-([A-Z])$/.exec(text);
|
||
if(match) {
|
||
let min = Number(match[1].charCodeAt(0));
|
||
let max = Number(match[2].charCodeAt(0));
|
||
if(min > max) { [min, max] = [max, min]; }
|
||
return String.fromCharCode( min+Math.round(Math.random()*(max-min)) );
|
||
}
|
||
|
||
return false;
|
||
|
||
}
|
||
|
||
function __curlyFunction_S(rootNode, thisRef, text, leftBlocks, rightBlocks) {
|
||
// there are {1..10} person{s} <-- can't do this, must manually handle the 2 cases
|
||
// I have {1..10} coin{s} <-- can do this :)
|
||
if(text === "s") {
|
||
|
||
// TODO: fix this with some proper NLP to handle written numbers: "twenty five"
|
||
|
||
// search through leftBlocks backwards for the first number.
|
||
// if a non-text block is found before a number is, return "{s}"
|
||
for(let i = leftBlocks.length-1; i >= 0; i--) {
|
||
let block = leftBlocks[i];
|
||
if(block[0] === "{" || block[0] === "[") {
|
||
return "{s}";
|
||
}
|
||
let numbers = block.split(/[\s,!?\-()/.]+/).filter(a => /[0-9]+/.test(a));
|
||
if(numbers.length > 0) {
|
||
let num = Number(numbers[numbers.length-1]);
|
||
return num === 1 ? "" : "s";
|
||
}
|
||
}
|
||
|
||
}
|
||
return false;
|
||
|
||
}
|
||
|
||
function __curlyFunction_Or(rootNode, thisRef, text, leftBlocks, rightBlocks, ctxInfo={}) {
|
||
if(!text.includes("|")) return false;
|
||
|
||
// no need to evaluate the arguments. we can just extract them (with their odds)
|
||
// and select a random one. We could evaluate the args but in that case it would be
|
||
// important that we extract all the *arguments* first (and their odds), then
|
||
// choose a random one (otherwise NEW "|" and "^" characters could end up in the evaluated text)
|
||
// and mess up our interpretation of the arguments.
|
||
|
||
// pulled the bulk of this curlyFunction_Or function out into its own function for use elsewhere:
|
||
let args = __splitUpCurlyOrBlock(text, ctxInfo);
|
||
if(args === false) return false;
|
||
|
||
// now we need to extract odds and choose a random one
|
||
// note that in curly "or" notation, *spaces matter* before and after the text.
|
||
// thus we don't trim the string after extracting the odds.
|
||
|
||
return __chooseRandomTextByOdds(rootNode, thisRef, args);
|
||
|
||
// TODO: sort out Array.toString
|
||
// LOOK AT Array.toString definition - try to extract out a common function
|
||
// (or you could just call) .toString on `parts` lol
|
||
// hmm. Array.toString relies on window.root being available which isn't great.
|
||
// I think first step is to test whether it works, then extract out as much as I
|
||
// can into functions. Array.toString is more of a handy hack - I don't want to rely
|
||
// on it if I can help it.
|
||
|
||
|
||
}
|
||
|
||
function __splitUpCurlyOrBlock(text, ctxInfo={}) {
|
||
// note this returns false if it's not a valid curly OR block.
|
||
// also, it expects that the outer curly brackets have already been removed
|
||
|
||
// the easiest way to be find all the unescaped "|" characters is to split it
|
||
// up and then search through *only text blocks*:
|
||
let blocks = __splitTextAtAllBlocks(text, ctxInfo);
|
||
let args = [];
|
||
let currentArg = "";
|
||
for(let j = 0; j < blocks.length; j++) {
|
||
let block = blocks[j];
|
||
if(block[0] !== "{" && block[0] !== "[") {
|
||
|
||
let escaped = false;
|
||
for(let i = 0; i < block.length; i++) {
|
||
if(i === 0) {
|
||
// if we're at the start of the block, it's not escaped:
|
||
escaped = false;
|
||
} else {
|
||
// if we're not at start, it's not escaped if the last char wasn't a backslash:
|
||
if(block[i-1] !== "\\") { escaped = false; }
|
||
}
|
||
// toggle escapedness at each consecutive backslash:
|
||
if(block[i] === "\\") { escaped = !escaped; }
|
||
|
||
if(block[i] === "|" && !escaped) {
|
||
|
||
currentArg += block.substr(0,i);
|
||
args.push(currentArg);
|
||
currentArg = "";
|
||
block = block.substr(i+1);
|
||
i = -1; // will get incremented to zero on loop
|
||
|
||
} else if(i === block.length-1) {
|
||
|
||
currentArg += block;
|
||
|
||
}
|
||
|
||
}
|
||
if(j === blocks.length-1) {
|
||
args.push(currentArg);
|
||
}
|
||
|
||
} else {
|
||
currentArg += block;
|
||
if(j === blocks.length-1) {
|
||
args.push(currentArg);
|
||
}
|
||
}
|
||
}
|
||
|
||
if(args.length === 0 || args.length === 1) {
|
||
// this is not the correct curly function to interpret this curly block
|
||
return false;
|
||
}
|
||
|
||
return args;
|
||
|
||
}
|
||
|
||
function __chooseRandomTextByOdds(rootNode, thisRef, textArray, ctxInfo={}) {
|
||
|
||
// extract odds
|
||
let items = [];
|
||
for(let text of textArray) {
|
||
text = text+""; // cast to string (needed for Array.toString);
|
||
let odds, textWithoutOdds;
|
||
let details = __getTextOddsDetails(text);
|
||
|
||
// TODO: fix this up to suit the new way of doign things
|
||
|
||
if(!details) {
|
||
textWithoutOdds = text;
|
||
odds = 1;
|
||
items.push({text:textWithoutOdds, odds});
|
||
continue;
|
||
}
|
||
|
||
textWithoutOdds = details.textWithoutOdds;
|
||
odds = details.odds;
|
||
|
||
if(typeof odds === 'string' && (odds[0] === "[" || /[0-9]/.test(odds[0]) )) { // if it's a dynamic odds expression:
|
||
|
||
let evaluatedOdds = __oddsTextToNumber(rootNode, thisRef, odds);
|
||
|
||
if(evaluatedOdds < 0) {
|
||
__perchanceError(`The dynamic odds expression "${__escapeHTMLSpecialChars(odds)}" in ${__escapeHTMLSpecialChars("{"+textArray.join("|")+"}")} resolved to a *negative* number. Odds must be positive numbers, since it doesn't make sense for something to have a negative chance of being selected. Remember that you can try executing this odds expression in the console (bottom-left panel in the editor interface) and see what it yeilds. Also remember that "^" is a special character that is used to declare the probability that the item will be selected, and if you want to use it as a literal character (i.e. not to declare odds), then you need to put a "backslash" before it like so: "\\^"`, ctxInfo);
|
||
return false;
|
||
}
|
||
if(evaluatedOdds === false) {
|
||
__perchanceError(`The dynamic odds expression "${__escapeHTMLSpecialChars(odds)}" in ${__escapeHTMLSpecialChars("{"+textArray.join("|")+"}")} didn't resolve to a number. Remember that you can try executing this odds expression in the console (bottom-left panel in the editor interface) and see what it yeilds. Also remember that "^" is a special character that is used to declare the probability that the item will be selected, and if you want to use it as a literal character (i.e. not to declare odds), then you need to put a "backslash" before it like so: "\\^"`, ctxInfo);
|
||
return false;
|
||
}
|
||
odds = evaluatedOdds;
|
||
|
||
}
|
||
|
||
items.push({text:textWithoutOdds, odds});
|
||
|
||
}
|
||
|
||
|
||
// select one based on odds
|
||
let oddsSum = 0;
|
||
let oddsArray = [];
|
||
for(let item of items) {
|
||
oddsSum += item.odds;
|
||
oddsArray.push(item.odds);
|
||
}
|
||
|
||
if(items.length === 0) {
|
||
console.warn(`Warning: Tried to get random selection from an empty array?`);
|
||
return "";
|
||
}
|
||
|
||
// choose random position in oddsSum range
|
||
let oddsSumStopPoint = oddsSum*Math.random();
|
||
let selectedItem;
|
||
let oddsSumForChoice = 0;
|
||
|
||
for(let i = 0; i < items.length; i++) {
|
||
oddsSumForChoice += oddsArray[i];
|
||
if(oddsSumForChoice >= oddsSumStopPoint) {
|
||
selectedItem = items[i];
|
||
break;
|
||
}
|
||
}
|
||
|
||
return selectedItem.text;
|
||
|
||
}
|
||
|
||
// doesn't need to be perfect! just a rough clean to help the {a/A} blocks
|
||
function __removeHtmlTagsFromBlocksArray(blocks) {
|
||
const joinTag = "sdoxci892387uoooJOINoooTAGooohkdsiyygjd970sjgs";
|
||
let str = blocks.join(joinTag);
|
||
let charArr = str.split("");
|
||
let inTag = false;
|
||
for(let i = 0; i < charArr.length; i++) {
|
||
if(charArr[i] === "<" && !inTag) {
|
||
inTag = true;
|
||
charArr[i] = "";
|
||
} else if(charArr[i] === ">" && inTag) {
|
||
inTag = false;
|
||
charArr[i] = "";
|
||
} else if(inTag) {
|
||
charArr[i] = "";
|
||
}
|
||
}
|
||
return charArr.join("").split(joinTag).filter(c => c.trim() !== "");
|
||
}</script> <script>let ___alreadyAttachedSaveHandler = false;
|
||
let ___postMessagesRecieved = 0;
|
||
let isFirstUpdate = true
|
||
window.moduleSpace = {};
|
||
|
||
async function ___updateOutput(outputTemplate) {
|
||
|
||
document.querySelector("#output-container").innerHTML = outputTemplate;
|
||
|
||
// We need to get the MutationObserver to ignore all of the nodes we just added because
|
||
// the MutationObserver is just for "dynamically added" nodes (i.e. added with custom javascript),
|
||
// and the nodes that we just added will be rendered by the `update()` function, of course.
|
||
// (we wouldn't actually need to do this if this function weren't async)
|
||
let allNewTextNodes = ___getAllTextNodeDescendents(document.querySelector("#output-container")); // this function adds the text nodes to the `allTextNodes` array
|
||
for(let textNode of allNewTextNodes) {
|
||
textNode.___alreadyRenderedPerchanceCode = true; // note that we haven't actually rendered it yet, but we're just about to (need to get in before MutationObserver, since this function is async)
|
||
}
|
||
// Need to do the same for attributes:
|
||
for(let el of Array.from(document.querySelectorAll("#output-container *"))) {
|
||
for(let attr of Array.from(el.attributes)) {
|
||
attr.___alreadyRenderedPerchanceCode = true;
|
||
}
|
||
}
|
||
|
||
___templatedNodes = [];
|
||
___addNodeTemplates(document.querySelector("#output-container"));
|
||
for(let element of Array.from(document.querySelectorAll("#output-container *"))) {
|
||
___reAttachDomElementEventsWithRoot(element);
|
||
}
|
||
await ___executeScriptTags();
|
||
update();
|
||
|
||
}
|
||
|
||
async function ___executeScriptTags(containerSelectorOrEl = "#output-container") {
|
||
let container;
|
||
if(typeof containerSelectorOrEl === 'string') container = document.querySelector(containerSelectorOrEl);
|
||
else container = containerSelectorOrEl;
|
||
|
||
let scriptTags = [];
|
||
if(container.tagName.toLowerCase() === 'script') {
|
||
scriptTags = [container];
|
||
} else {
|
||
scriptTags = container.getElementsByTagName('script');
|
||
}
|
||
|
||
for (var i = 0; i < scriptTags.length ; i++) {
|
||
await ___executeScriptTag(scriptTags[i]);
|
||
}
|
||
}
|
||
|
||
function ___getAllMatches(str, regex) {
|
||
const matches = [];
|
||
let m;
|
||
while(1) {
|
||
m = regex.exec(str);
|
||
if(m) matches.push(m);
|
||
else break;
|
||
}
|
||
return matches;
|
||
}
|
||
|
||
// For all Safari versions before 17.4:
|
||
let ___withFunctionScopeFixRequired = false;
|
||
try {
|
||
let obj = {a7d638p364:0};
|
||
with(obj) {
|
||
function fn() {
|
||
return a7d638p364+1;
|
||
}
|
||
fn();
|
||
}
|
||
} catch(e) {
|
||
___withFunctionScopeFixRequired = true;
|
||
}
|
||
|
||
async function ___executeScriptTag(oldScript) {
|
||
let parent = oldScript.parentElement;
|
||
let newScript = document.createElement('script');
|
||
// had to use hasAttribute instead of simple property access because firefox defaults to script.async=true for dynamically-created script tags
|
||
newScript.async = oldScript.hasAttribute("async"); //oldScript.async;
|
||
newScript.type = oldScript.type;
|
||
let loadPromise;
|
||
if(oldScript.src && !newScript.async && !newScript.defer) {
|
||
loadPromise = new Promise(resolve => {newScript.onload = resolve; newScript.onerror = resolve; });
|
||
}
|
||
if(oldScript.src) {
|
||
newScript.src = oldScript.src;
|
||
} else {
|
||
if(newScript.type === "module") {
|
||
newScript.textContent = oldScript.textContent;
|
||
} else {
|
||
let scriptText = oldScript.textContent;
|
||
|
||
// Apply Safari `with` statement fix if needed:
|
||
if(___withFunctionScopeFixRequired) {
|
||
try {
|
||
let topLevelListNamesRegex = new RegExp(window.root.getSelf.getAllKeys.join("|"));
|
||
if(topLevelListNamesRegex.test(scriptText)) { // only if it contains a list name - to reduce chance of introducing bugs, since regex below is not full-proof.
|
||
scriptText = scriptText.replace(/(\n\s*|^\s*)(async |)function\s+([a-zA-Z0-9_$]+?)(\s*\(.*\)\s*\{)/g, "$1var $3 = $2function$4");
|
||
}
|
||
} catch(e) {
|
||
console.error("Error while applying Safari with statement fix:", r);
|
||
}
|
||
}
|
||
|
||
//newScript.textContent = "with(window.root.___proxyTarget.obj){"+scriptText+"}";
|
||
// The following monstrosity replaces the above commented out line due to the fact that block-scoped declarations (let, const, async function) get trapped by the `with` statement's block. False positives for the regex are fine (e.g. if it grabs non-variables from strings that look like declarations). I'm also grabbing `function` in case I ever allow people to use strict mode (the current `with` precludes it) since in strict mode `function`s are block scoped.
|
||
let potentialNewGlobalVariableNames = ___getAllMatches(scriptText, /[\s;](?:var|let|const)\s+([^\s]+?)\s*=/g).map(r => r[1]);
|
||
potentialNewGlobalVariableNames.push(...___getAllMatches(scriptText, /[\s;](?:function|async function)\*?\s+([^\s]+?)\s*\(/g).map(r => r[1]));
|
||
potentialNewGlobalVariableNames.push(...___getAllMatches(scriptText, /[\s;]class\s+([^\s]+?)\s*\{/g).map(r => r[1]));
|
||
|
||
newScript.textContent = `
|
||
with(window.root.___proxyTarget.obj){
|
||
${scriptText};
|
||
for(let name of ${JSON.stringify(potentialNewGlobalVariableNames)}) {
|
||
try { let val = eval(name); window[name] = val; } catch(e) {}
|
||
}
|
||
}
|
||
`;
|
||
}
|
||
}
|
||
if(!newScript.type) {
|
||
newScript.setAttribute('type','text/javascript');
|
||
}
|
||
parent.insertBefore(newScript, oldScript);
|
||
parent.removeChild(oldScript);
|
||
if(loadPromise) await loadPromise;
|
||
return newScript;
|
||
}
|
||
|
||
let ___templatedNodes; // REMEMBER: order is important for functions like .id()
|
||
function ___addNodeTemplates(domNode) {
|
||
var nodes = domNode.childNodes;
|
||
for (var i = 0, m = nodes.length; i < m; i++) {
|
||
var n = nodes[i];
|
||
if(n.nodeType !== n.TEXT_NODE && n.nodeName !== "#comment") {
|
||
___templatedNodes.push( ...___addAttributeTemplateToEl(n) );
|
||
}
|
||
|
||
if (n.nodeType == n.TEXT_NODE && n.parentNode.tagName !== "SCRIPT" && n.parentNode.nodeName !== "STYLE") {
|
||
|
||
// we found a text node, so lets break it into an expression array
|
||
// and wrap expressions in spans (the "template span")
|
||
|
||
let arr = __splitTextAtAllBlocks(n.textContent);
|
||
if(!arr) {
|
||
__perchanceError(`Some text has caused an error with the compiler. If you can, please post a bug report with a link to your generator on <a href="https://lemmy.world/c/perchance">lemmy.world/c/perchance</a> to help me fix this bug. Thanks! Here's the text that caused this issue: ${__escapeHTMLSpecialChars(n.textContent)}`);
|
||
return;
|
||
}
|
||
|
||
if(arr.length === 0) {
|
||
if(n.textContent.trim() !== "") {
|
||
__perchanceError(`Something's not right. Some text has caused an error with the compiler. If you can, please post a bug report with a link to your generator on <a href="https://lemmy.world/c/perchance">lemmy.world/c/perchance</a> to help me fix this bug. A non-empty text node resulted in an empty block array. This is probably a problem with 'splitTextAtAllBlocks'. Maybe some 'continue' statements skipping over things that they shouldn't?`);
|
||
}
|
||
continue;
|
||
}
|
||
|
||
if(arr.length > 1 || arr[0][0] === "[" || arr[0][0] === "{") {
|
||
//let exprSpan = document.createElement('span');
|
||
// exprSpan.className = "__perchance_textnode_expression";
|
||
// exprSpan.dataset.perchanceExpression = arr.join("");
|
||
//exprSpan.innerText = arr.join("");
|
||
|
||
//n.parentNode.insertBefore(exprSpan, n);
|
||
//n.parentNode.removeChild(n);
|
||
|
||
___templatedNodes.push({oldNodes:[n], parentNode:n.parentNode, previousSibling:n.previousSibling, nextSibling:n.nextSibling, type:"textNode", text:arr.join("")});
|
||
|
||
}
|
||
|
||
// just regular text:
|
||
if(arr.length === 1 && arr[0][0] !== "[" && arr[0][0] !== "{") {
|
||
n.nodeValue = __processEscapedCharacters(n.nodeValue);
|
||
}
|
||
|
||
} else {
|
||
___addNodeTemplates(n);
|
||
}
|
||
}
|
||
}
|
||
|
||
function ___collectTemplatableTextChunks(domNode, foundChunks) {
|
||
if(!foundChunks) foundChunks = [];
|
||
var nodes = domNode.childNodes;
|
||
for (var i = 0, m = nodes.length; i < m; i++) {
|
||
var n = nodes[i];
|
||
|
||
if(n.nodeType !== n.TEXT_NODE && n.nodeName !== "#comment") {
|
||
for(let attribute of Array.from(n.attributes)) {
|
||
if(___isTemplatableAttributeName(attribute.name)) {
|
||
// we found a templatable attribute
|
||
foundChunks.push(attribute.nodeValue);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (n.nodeType == n.TEXT_NODE && n.parentNode.tagName !== "SCRIPT" && n.parentNode.nodeName !== "STYLE") {
|
||
|
||
// we found a templatable text node
|
||
foundChunks.push(n.textContent);
|
||
|
||
} else {
|
||
___collectTemplatableTextChunks(n, foundChunks);
|
||
}
|
||
}
|
||
return foundChunks;
|
||
}
|
||
|
||
let ___domEventAttributeNames = new Set([
|
||
...Object.getOwnPropertyNames(document),
|
||
...Object.getOwnPropertyNames(Object.getPrototypeOf(Object.getPrototypeOf(document))),
|
||
...Object.getOwnPropertyNames(Object.getPrototypeOf(window)),
|
||
].filter(k => k.startsWith("on") && (document[k] == null || typeof document[k] == "function")));
|
||
|
||
function ___isDomEventAttributeName(name) {
|
||
if(___domEventAttributeNames.has(name)) return true;
|
||
else return false;
|
||
}
|
||
|
||
function ___isTemplatableAttributeName(name) {
|
||
|
||
// note that this *doesn't* mean that they're ignored in *generated* html (i.e. generated by perchance code)
|
||
// because all of thosse strings are fully executed before being output.
|
||
if(___isDomEventAttributeName(name)) { return false; }
|
||
|
||
// i was previously ignoring data attributes and stuff, but I see no reason for that.
|
||
// sure, someone may need to use special characters in their web component attirbutes or whatever
|
||
// but they can just escape them.
|
||
|
||
return true;
|
||
|
||
}
|
||
|
||
function ___addAttributeTemplateToEl(el) {
|
||
|
||
let templatableNodes = [];
|
||
for(let attribute of Array.from(el.attributes)) {
|
||
if(!___isTemplatableAttributeName(attribute.name)) { continue; }
|
||
templatableNodes.push({el, attribute, type:"attribute"});
|
||
}
|
||
|
||
let templatedNodes = [];
|
||
for(let item of templatableNodes) {
|
||
let {attribute, el} = item;
|
||
let exprArr = __splitTextAtAllBlocks(attribute.nodeValue);
|
||
if(!exprArr[0]) { continue; }
|
||
if(exprArr && (exprArr.length > 1 || exprArr[0][0] === "[" || exprArr[0][0] === "{")) {
|
||
item.text = attribute.nodeValue;
|
||
templatedNodes.push(item);
|
||
} else {
|
||
// this attribute is just plain text - no template needed. just need to remove any escaping-backslashes
|
||
attribute.nodeValue = __processEscapedCharacters(attribute.nodeValue);
|
||
}
|
||
}
|
||
|
||
return templatedNodes;
|
||
|
||
}
|
||
|
||
function ___reAttachDomElementEventsWithRoot(el) {
|
||
if(el.___alreadyAttatchedEventsWithRoot) return;
|
||
for(let attr of Array.from(el.attributes)) {
|
||
if(___isDomEventAttributeName(attr.name)) {
|
||
let fn = el[attr.name];
|
||
el.removeAttribute(attr.name);
|
||
|
||
// el.addEventListener(attr.name.substr(2), function(event) { // <-- bad because it removes ability to write e.g. el.onchange(), and also prevents *overwriting* of the handler.
|
||
el[attr.name] = function(event) {
|
||
try {
|
||
let fnStr = fn.toString();
|
||
//fnStr = fnStr.replace("{","{ with(window.root.___proxyTarget.obj) {") + "}";
|
||
fnStr = fnStr.replace("{","{ with(window.root) {") + "}";
|
||
eval(`(${fnStr}).bind(this)(event)`);
|
||
} catch(e) {
|
||
__perchanceError(`There was an error in the <b>${attr.name}</b> attribute of this element in your HTML panel: <code>${this.outerHTML.replace(/<(.+?)>/g, "<$1>")}</code>. Here's the error: <span style='color:red'>${e}</span>`);
|
||
}
|
||
};
|
||
|
||
}
|
||
}
|
||
el.___alreadyAttatchedEventsWithRoot = true;
|
||
}
|
||
|
||
|
||
function update(selectorOrEl) {
|
||
// if it has been a few seconds since the error was shown, and error model isn't currently open, we can probably hide the error box so it doesn't clutter the generator UI for end-users. The dev would have clicked the error modal button before randomizing again.
|
||
try {
|
||
if(window.__lastPerchanceErrorTime && Date.now()-window.__lastPerchanceErrorTime > 1000*5 && document.querySelector("#perchance-error-container").offsetHeight === 0) {
|
||
__clearPerchanceErrors();
|
||
}
|
||
} catch(e) { console.error(e); }
|
||
|
||
// _updateOutput essentially reloads the page, whereas `update` just replaces all values of the expressions
|
||
___updateTemplatedNodes(selectorOrEl); // goes through templatedNodes array *in order* (that's important)
|
||
}
|
||
|
||
function ___htmlToElements(html) {
|
||
var template = document.createElement('template');
|
||
template.innerHTML = html;
|
||
return Array.from(template.content.childNodes);
|
||
}
|
||
|
||
let ___trackedNodesCreatedByTemplates = new Set();
|
||
try { // putting this in try/catch because it's new code and I don't want it to break anything
|
||
// if an element that was created by a square/curly block is replaced with another element *specifically using the replaceWith function*
|
||
// then we want our tracking code to treat them as the 'same element' in terms of the ___updateTemplatedNodes process.
|
||
// we don't do that for other ways of replacing elements (e.g. setting innerHTML) because there are valid use cases for that (e.g. comments plugin uses it to avoid update() causing comments iframe to refresh)
|
||
const ___originalReplaceWith = Element.prototype.replaceWith;
|
||
Element.prototype.replaceWith = function(...args) {
|
||
// check if this is a node that was created by a template
|
||
if(___trackedNodesCreatedByTemplates.has(this)) {
|
||
for(let i = 0; i < args.length; i++) { // we convert any strings/numbers/booleans since replaceWith does that automatically, but we need to get a reference to the created nodes, so we do it manually
|
||
if(typeof args[i] === "string" || typeof args[i] === "number" || typeof args[i] === "boolean") {
|
||
args[i] = document.createTextNode(args[i].toString());
|
||
}
|
||
}
|
||
// if so, then we need to swap the new node with the old one in the oldNodes array of each ___templatedNodes item:
|
||
for(let n of ___templatedNodes) {
|
||
if(n.oldNodes.includes(this)) {
|
||
n.oldNodes.splice(n.oldNodes.indexOf(this), 1, ...args);
|
||
}
|
||
}
|
||
}
|
||
___originalReplaceWith.apply(this, args);
|
||
};
|
||
} catch(e) {
|
||
console.error(e);
|
||
}
|
||
|
||
async function ___updateTemplatedNodes(selectorOrEl="") {
|
||
let container;
|
||
if(typeof selectorOrEl === 'string') {
|
||
container = document.querySelector("#output-container "+selectorOrEl);
|
||
} else {
|
||
container = selectorOrEl;
|
||
}
|
||
|
||
if(container instanceof HTMLCollection) { // i.e. they have multiple elements with the same id and they referred to it using named access: https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object
|
||
__perchanceError(`It looks like you've got multiple elements in your HTML with <b>id=${container[0].id}</b>. If you can't find any duplicates, make sure that if you've imported some HTML, the ids used in that HTML aren't the same as the ids that you're using.`);
|
||
return;
|
||
}
|
||
|
||
___trackedNodesCreatedByTemplates.clear();
|
||
|
||
// goes through attributes and text nodes in the order they were declared. (order of execution is important)
|
||
for(let n of ___templatedNodes) {
|
||
// NOTE THAT `n` IS NOT AN ACTUAL `Node` object - it's just an obj we created with similarly names properties which "represents" the original node (which we delete and replace)
|
||
// NOTE: we can't replace spaces with   or new lines with <br/> because they could (for example) have spaces in attributes that are generated, or (for example) in html tags that they generate. we don't want <a href="http://...">...</a>
|
||
if(n.type === "textNode" && (container.contains(n.parentNode) || container === n.parentNode)) {
|
||
// remove old nodes
|
||
for(let node of n.oldNodes) {
|
||
try { n.parentNode.removeChild(node); } catch(e) { console.log(e); } // we try/catch because the node may not be in the parent anymore (e.g. it may have been deleted or moved with some javascript)
|
||
}
|
||
// create new nodes
|
||
let text = __processEscapedCharacters( __evaluateText(window.root, window.root, n.text, {declarationLineNumber:null}) );
|
||
let newNodes = ___htmlToElements(text);
|
||
|
||
// These node additions will trigger our MutationObserver (that we need for monitoring "dynamically added" nodes (i.e. nodes added with "raw" javascript) to the page so we can render them)
|
||
// so we need to mark them all as "already rendered" (because they could have originally-escaped curly/square blocks which would then be seen as unescaped ones if they were "rendered" again)
|
||
let allNewTextNodes = newNodes.filter(n => n.nodeType === Node.TEXT_NODE);
|
||
for(let newNode of newNodes) {
|
||
___getAllTextNodeDescendents(newNode, allNewTextNodes); // this function adds the text nodes to the `allTextNodes` array
|
||
}
|
||
for(let textNode of allNewTextNodes) {
|
||
textNode.___alreadyRenderedPerchanceCode = true;
|
||
}
|
||
|
||
// insert new nodes
|
||
for(let node of newNodes) {
|
||
// add it before the next sibling (if there is no next sibling, then it's the last one, so we just append)
|
||
if(n.nextSibling && n.parentNode.contains(n.nextSibling)) n.parentNode.insertBefore(node, n.nextSibling);
|
||
else n.parentNode.appendChild(node);
|
||
|
||
___trackedNodesCreatedByTemplates.add(node);
|
||
}
|
||
n.oldNodes = newNodes;
|
||
// execute script tags:
|
||
for(let i = 0; i < newNodes.length; i++) {
|
||
if(newNodes[i].tagName && newNodes[i].tagName.toLowerCase() === "script") {
|
||
newNodes[i] = await ___executeScriptTag(newNodes[i]);
|
||
}
|
||
}
|
||
} else if(n.type === "attribute" && (container.contains(n.el) || container === n.el)) {
|
||
let result = __processEscapedCharacters( __evaluateText(window.root, window.root, n.text, {declarationLineNumber:null}) );
|
||
n.attribute.nodeValue = result;
|
||
if(n.attribute.nodeName === "value") n.el.value = result; // <-- because of this: https://stackoverflow.com/a/7986111/11950764 (for input elements, `n.attribute.nodeValue` is the *default* value - so changing it doesn't update the *live* value)
|
||
n.attribute.___alreadyRenderedPerchanceCode = true; // <-- editing attributes triggers our MutationObserver (which watches for and processes "dynamic" JavaScript DOM additions) but we don't want to run rendering twice, so we do this.
|
||
} else {
|
||
// this node isn't within the container/selector that was pased to the `update()` function
|
||
}
|
||
if(n.type !== "attribute" && n.type !== "textNode") __perchanceError(`There was an invalid node type when trying to update the HTML. If you can, please post a bug report with a link to your generator on <a href="https://lemmy.world/c/perchance">lemmy.world/c/perchance</a> to help me fix this bug. Thanks!`);
|
||
}
|
||
}
|
||
|
||
window.addEventListener('message', async function (e) {
|
||
___postMessagesRecieved++;
|
||
let origin = e.origin || e.originalEvent.origin; // For Chrome, the origin property is in the event.originalEvent object.
|
||
//console.log("Change origin when you put it on a domain!");
|
||
//console.log(origin)
|
||
if(/*origin !== "http://app.dev:3001" && */origin !== "https://perchance.org") {
|
||
//console.error("invalid origin");
|
||
return;
|
||
}
|
||
|
||
// if(e.data.command === "updateMetadataIfNeeded") {
|
||
// ___updateGeneratorMetaData();
|
||
// }
|
||
|
||
if(e.data.command === "updateOutput") {
|
||
___updateOutputMessageHandler(e);
|
||
}
|
||
|
||
if(e.data.command === "evaluateText") {
|
||
let text, callerId = e.data.callerId;
|
||
if(window.root === null) {
|
||
text = "There is an error in your generator's script.";
|
||
} else {
|
||
text = __processEscapedCharacters( __evaluateText(window.root, window.root, e.data.text, {declarationLineNumber:null}) );
|
||
}
|
||
e.source.postMessage({type:"evaluateTextResponse", text, callerId}, e.origin);
|
||
}
|
||
|
||
if(!___alreadyAttachedSaveHandler) {
|
||
// manually bubble up save commands out of this iframe and into editor
|
||
document.addEventListener("keydown", (keyEvent) => {
|
||
if (keyEvent.keyCode == 83 && (navigator.platform.match("Mac") ? keyEvent.metaKey : keyEvent.ctrlKey)) {
|
||
keyEvent.preventDefault();
|
||
e.source.postMessage({type:"saveKeyboardShortcut"}, e.origin);
|
||
}
|
||
}, false);
|
||
___alreadyAttachedSaveHandler = true;
|
||
}
|
||
|
||
});
|
||
|
||
|
||
async function ___updateOutputMessageHandler(e) {
|
||
|
||
window.codeWarningsArray = [];
|
||
__clearPerchanceErrors();
|
||
document.querySelector("#perchance-dep-load-indicator").style.display = "none";
|
||
|
||
try {
|
||
|
||
let unfoundDeps = e.data.dependencies.filter(d => d.found === false);
|
||
if(unfoundDeps.length > 0) {
|
||
__perchanceError(`${unfoundDeps.length > 1 ? "Some dependencies" : "A dependency"} (imported generator${unfoundDeps.length > 1 ? "s" : ""}) that you tried to import into your generator could not be found: <b>${unfoundDeps.map(d => d.name).join("</b>, <b>")}</b>. You can check that whether or not they exist by going to: <i>perchance.org/NAME</i> where "NAME" should be replaced with the name of the generator that you're trying to import.`);
|
||
}
|
||
|
||
if(!Array.isArray(e.data.dependencies)) {
|
||
__perchanceError(`Something went wrong with the dependencies (imported modules): ${e.data.dependencies}. This is an unusual bug and may indicate a problem with the Perchance engine. If you could post a bug report on the forum that'd be great: <a href='https://lemmy.world/c/perchance'>lemmy.world/c/perchance<a>`);
|
||
}
|
||
let foundDeps = e.data.dependencies.filter(d => d.found !== false);
|
||
for(let dep of foundDeps) {
|
||
dep.hasImportedPreprocessor = /\n\$preprocess *= *{import:/.test("\n"+dep.modelText);
|
||
}
|
||
foundDeps.sort((a,b) => a.hasImportedPreprocessor ? 1 : -1); // compile generators that rely on preprocessors last so that their preprocessor has already been compiled and is thus available in the moduleSpace when we're compiling that generator
|
||
for(let dep of foundDeps) {
|
||
if(moduleSpace[dep.name]) continue; // Don't want to recompile things that we've already got! (only a problem if there is "recursive" dependency stuff I think)
|
||
moduleSpace[dep.name] = __createPerchanceTree(dep.modelText, dep.name);
|
||
moduleSpace[dep.name].$moduleSpace = moduleSpace;
|
||
}
|
||
|
||
// get all imports in HTML and add them to window.root.$imports
|
||
let htmlTestDiv = document.createElement("div");
|
||
htmlTestDiv.innerHTML = e.data.generator.outputTemplate;
|
||
let templatableTextChunks = ___collectTemplatableTextChunks(htmlTestDiv);
|
||
let htmlImports = [];
|
||
__ignorePerchanceErrors = true;
|
||
for(let chunk of templatableTextChunks) {
|
||
htmlImports.push( ...__collectImportedModuleNamesFromText(chunk) );
|
||
}
|
||
__ignorePerchanceErrors = false;
|
||
|
||
try {
|
||
window.root = __createPerchanceTree(e.data.generator.modelText, e.data.generator.name);
|
||
} catch(e) {
|
||
console.error("Critical error in __createPerchanceTree:", e); // need to catch this else we can't e.g. tell parent that it failed to load (which is relevant for the saving process)
|
||
}
|
||
|
||
if(!window.root) {
|
||
if(e.data.generator.modelText.startsWith("$preprocess") || e.data.generator.modelText.includes("\n$preprocess")) {
|
||
let imports = e.data.generator.modelText.split("\n").map(l => __collectImportedModuleNamesFromText(l)).flat();
|
||
imports.push(...new Set(htmlImports));
|
||
imports = imports.filter(name => name !== e.data.generator.name);
|
||
__parentWindow.postMessage({type:"importsUpdate", imports:[...new Set(imports)]}, "https://perchance.org");
|
||
}
|
||
__perchanceError(`Your generator's script seems to have errors in it. If you haven't recieved any other errors above this one which could indicate what went wrong, then this could be a bug in the Perchance engine. In that case, it would be great if you could post a quick bug report on the forum: <a href="https://lemmy.world/c/perchance">lemmy.world/c/perchance<a>`);
|
||
|
||
__parentWindow.postMessage({type:"failedToLoadDueToGeneratorErrors"}, "https://perchance.org");
|
||
return;
|
||
}
|
||
|
||
window.root.$imports.push(...new Set(htmlImports));
|
||
|
||
// remove import of THIS module (most likely mistake by user)
|
||
window.root.$imports = window.root.$imports.filter(name => name !== e.data.generator.name);
|
||
|
||
moduleSpace[e.data.generator.name] = window.root;
|
||
window.root.$moduleSpace = moduleSpace;
|
||
|
||
// EDIT: This is no longer needed since we do it all in the `key=value` getter - see MARKER:odj29hfi3j0d2kj0hx24f
|
||
// if((document.referrer+"").includes("test-import-linking-removal")) {
|
||
// // do nothing
|
||
// } else {
|
||
// // tie all direct import assignments to the actual module's root node (otherwise we can't access sub-properties):
|
||
// for(let moduleRoot of Object.values(window.root.$moduleSpace)) {
|
||
// for(let node of moduleRoot.$allNodes) {
|
||
// if(node.$nodeType === "value" && typeof node.$value === "string") {
|
||
// let match = /^\{import:([a-z0-9\-]+)\}$/.exec(node.$value);
|
||
// if(match) {
|
||
// let moduleName = match[1];
|
||
// let importedModuleRoot = window.root.$moduleSpace[moduleName];
|
||
// if(importedModuleRoot) {
|
||
// if("$output" in importedModuleRoot.getSelf) {
|
||
// if(importedModuleRoot.getSelf.$valueChildren.includes("$output")) {
|
||
// let outputNode = importedModuleRoot.getSelf.$allNodes.find(n => n.$key === "$output" && n.$parent === importedModuleRoot.getSelf);
|
||
// let value;
|
||
// if(typeof outputNode.$value === "string") value = outputNode;
|
||
// else value = outputNode.$value;
|
||
// Object.defineProperty(node.$parent, node.$key, {value:value, writable:true, configurable:true}); // <-- need outputNode.$value rather than importedModuleRoot.getSelf.$output because $output will be getter if it's a value node that's not a direct link to another list (ctrl+f "tie direct references to" in createPerchanceTree.js), and so if $output=[listOfLists.selectOne], this import statement would get tied to a *specific* list in listOfLists, which is wrong. Bug "report": reddit.com/r/perchance/comments/fft71g/has_anyone_made_an_object_generator/fk0pw5d
|
||
// } else {
|
||
// Object.defineProperty(node.$parent, node.$key, {value:importedModuleRoot.getSelf.$output, writable:true, configurable:true});
|
||
// }
|
||
// } else {
|
||
// //node.$parent[node.$key] = importedModuleRoot;
|
||
// Object.defineProperty(node.$parent, node.$key, {value:importedModuleRoot.getSelf, writable:true, configurable:true});
|
||
// }
|
||
// } else {
|
||
// __perchanceError(`A generator that you imported, '${moduleName}', could not be found. If you're sure that generator exists, try saving your generator and reloading.`);
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
|
||
let currentDepNames = e.data.dependencies.map(d => d.name);
|
||
let newDepNames = window.root.$imports.filter(name => !currentDepNames.includes(name));
|
||
|
||
// // only send import updates if there are new imports
|
||
if(newDepNames.length > 0) {
|
||
|
||
// NOTE: see note below about race condition - we're always sending importsUpdate now
|
||
//e.source.postMessage({type:"importsUpdate", imports:window.root.$imports}, e.origin);
|
||
|
||
document.querySelector("#perchance-dep-load-indicator").style.display = 'block';
|
||
//document.querySelector("#output-container").innerHTML = `Loading newly imported dependenc${newDepNames.length === 1 ? "y" : "ies"}... (${newDepNames.join(", ")})`;
|
||
|
||
} else {
|
||
await ___updateOutput(e.data.generator.outputTemplate);
|
||
}
|
||
|
||
// NOTE: due to issues with race conditions during saving (https://www.reddit.com/r/perchance/comments/cgyhey/when_i_try_to_open_the_generator_it_says_that_the/), I'm just going to *always* send back an importsUpdate (I check in the main thread/frame whether the update is actually needed)
|
||
// // tell main app which imports are being *directly* used by this generator in case we
|
||
// // can clear some no-longer-used dependencies
|
||
// let unusedOrIndirectDeps = currentDepNames.filter(n => !window.root.$imports.includes(n));
|
||
// if(unusedOrIndirectDeps.length > 0) {
|
||
// EDIT: IMPORTANT: this must come before `finishedLoadingIncludingMetaData` postMessage
|
||
__parentWindow.postMessage({type:"importsUpdate", imports:window.root.$imports}, "https://perchance.org");
|
||
// }
|
||
|
||
let metaDataUpdatePromise = ___updateGeneratorMetaData(); // no need to `await` this
|
||
|
||
try { // try/catch since this is new code. can remove later.
|
||
if(e.data.generator.outputTemplate.includes(" id=")) { // <-- just an optimisation
|
||
let topLevelVariableNames = [...window.root.getPropertyNames, ...window.root.getChildNames];
|
||
let htmlElementIds = [...document.querySelectorAll("[id]")].map(el => el.id);
|
||
let intersection = htmlElementIds.filter(value => topLevelVariableNames.includes(value));
|
||
if(intersection.length > 0) {
|
||
window.codeWarningsArray.push({lineNumber:root[intersection[0]].$declarationLineNumber, generatorName:window.generatorName, warningId:"top-level-list-name-same-as-html-element-id"});
|
||
}
|
||
}
|
||
} catch(e) {
|
||
console.error(e);
|
||
}
|
||
|
||
__parentWindow.postMessage({type:"codeWarningsUpdate", warnings:window.codeWarningsArray}, "https://perchance.org");
|
||
|
||
__parentWindow.postMessage({type:"finishedLoading"}, "https://perchance.org");
|
||
|
||
(async function() {
|
||
await metaDataUpdatePromise;
|
||
await new Promise(r => setTimeout(r, 5));
|
||
// this event is used to know when we can save the generator (with correct dependencies + metadata based on current text in editor)
|
||
__parentWindow.postMessage({type:"finishedLoadingIncludingMetaData", imports:window.root.$imports}, "https://perchance.org");
|
||
})();
|
||
|
||
isFirstUpdate = false;
|
||
|
||
} catch(error) {
|
||
//debugger;
|
||
document.querySelector("#output-container").innerHTML = e.data.generator.outputTemplate;
|
||
__perchanceError(`There was an error while trying to compile your generator. Here's the error message: <blockquote>${__escapeHTMLSpecialChars(error.stack)}</blockquote>`);
|
||
__parentWindow.postMessage({type:"finishedLoading"}, "https://perchance.org");
|
||
}
|
||
}
|
||
|
||
|
||
async function ___updateGeneratorMetaData() {
|
||
// get page title from first h1 that contains text:
|
||
let h1 = [...document.querySelectorAll("h1")].filter(el => el.textContent.trim())[0];
|
||
if(!h1) h1 = document.querySelector("h2");
|
||
let generatorTitle = h1 && h1.textContent !== "Your Generator's Title" && h1.textContent !== "Minimal Example" ? h1.textContent : window.location.pathname.slice(1).split("-").filter(function(a){return a;}).map(function(word){return word[0].toUpperCase()+word.slice(1); }).join(" ");
|
||
let generatorHTML = document.querySelector("#output-container").innerHTML;
|
||
let generatorImage = "";
|
||
let generatorDescription = "";
|
||
let generatorDynamicMetaDataFunction = null;
|
||
if(root.$meta) {
|
||
if(root.$meta.title) generatorTitle = root.$meta.title.evaluateItem;
|
||
if(root.$meta.description) generatorDescription = root.$meta.description.evaluateItem;
|
||
if(root.$meta.image) generatorImage = root.$meta.image.evaluateItem;
|
||
if(root.$meta.dynamic) {
|
||
try {
|
||
// grab the lines that are in the 'dynamic' function.
|
||
let lines = window.root.$meta.getRawListText.split("\n");
|
||
let keepLines = [];
|
||
let inFunction = false;
|
||
let functionHeaderIndentSpaces = null;
|
||
for(let line of lines) {
|
||
if(line.trim().startsWith("dynamic(") || line.trim().startsWith("async dynamic(")) {
|
||
inFunction = true;
|
||
functionHeaderIndentSpaces = line.length - line.replace(/^ +/g, "").length;
|
||
keepLines.push(line.trim().replace("dynamic(", "function dynamic(").replace("=>", " {"));
|
||
continue;
|
||
}
|
||
if(inFunction) {
|
||
let indentSpaces = line.length - line.replace(/^ +/g, "").length;
|
||
if(line.trim() && indentSpaces <= functionHeaderIndentSpaces) {
|
||
break;
|
||
}
|
||
keepLines.push(line);
|
||
}
|
||
}
|
||
generatorDynamicMetaDataFunction = keepLines.join("\n") + "\n}";
|
||
if(generatorDynamicMetaDataFunction.length > 20000) {
|
||
generatorDynamicMetaDataFunction = null;
|
||
__perchanceError("Your $meta dynamic function is too long. It must be less than 20,000 characters - you can `fetch` a remote file that you uploaded to perchance.org/upload if needed.");
|
||
}
|
||
} catch(e) {
|
||
console.error(e);
|
||
}
|
||
|
||
if(generatorDynamicMetaDataFunction) {
|
||
try {
|
||
// this would be done server-side anyway, but we do it here so that we can dynamically update the title of the current browser tab
|
||
let urlParams = Object.fromEntries([...new URL(window.location.href).searchParams].filter(e => !e[0].startsWith("utm_")));
|
||
let inputs = {urlParams};
|
||
let cacheKey = generatorDynamicMetaDataFunction + "<<<--->>>" + JSON.stringify(inputs);
|
||
let outputs;
|
||
if(!window.__dynamicMetaDataCache) window.__dynamicMetaDataCache = {}; // simple cache just so while they're editing we're not e.g. spamming a `fetch` that they have in their `dynamic` function
|
||
if(window.__dynamicMetaDataCache[cacheKey]) {
|
||
outputs = window.__dynamicMetaDataCache[cacheKey];
|
||
console.log("Used cached dynamic meta data:", outputs);
|
||
} else {
|
||
outputs = await root.$meta.dynamic(inputs);
|
||
console.log("Computed dynamic meta data:", outputs);
|
||
window.__dynamicMetaDataCache[cacheKey] = outputs;
|
||
}
|
||
if(typeof outputs.title === "string") generatorTitle = outputs.title;
|
||
if(typeof outputs.description === "string") generatorDescription = outputs.description;
|
||
if(typeof outputs.image === "string") generatorImage = outputs.image;
|
||
} catch(e) {
|
||
__perchanceError(`There was an error in your $meta dynamic function. Here's the error message: <blockquote>${__escapeHTMLSpecialChars(e.stack)}</blockquote>`);
|
||
}
|
||
}
|
||
}
|
||
|
||
let metaProps = new Set(root.$meta.$valueChildren);
|
||
metaProps.delete("title");
|
||
metaProps.delete("description");
|
||
metaProps.delete("image");
|
||
if(metaProps.size > 0) __perchanceError("Looks like you've got some invalid properties in your $meta list? The only valid properties are 'title', 'description', and 'image'.");
|
||
}
|
||
if(!navigator.webdriver) { // try to avoid Google crawler title swap bug - no idea if this will fix it.
|
||
__parentWindow.postMessage({type:"metaUpdate", title:generatorTitle, html:generatorHTML, image:generatorImage, description:generatorDescription, dynamic:generatorDynamicMetaDataFunction, _validation:{generatorName:window.generatorName}}, "https://perchance.org"); // had to use "https://perchance.org" as origin so our initial dummy update (using embedded data) works.
|
||
}
|
||
await new Promise(r => setTimeout(r, 5)); // ensure postMessage has actually been sent
|
||
}
|
||
|
||
window.addEventListener("DOMContentLoaded", function() {
|
||
|
||
let dependencies;
|
||
try { // adding try/catch here in case of future instances of this: https://lemmy.world/post/4913660
|
||
dependencies = JSON.parse( decodeURI( document.querySelector("#imported-generators").textContent ) );
|
||
} catch(e) {
|
||
if(!location.href.includes("__generatorDependenciesCacheBust")) { // try a cache bust if we haven't already.
|
||
let url = new URL(window.location.href);
|
||
url.searchParams.set("__generatorDependenciesCacheBust", Math.random());
|
||
window.location.href = url.href;
|
||
return;
|
||
} else { // if we've already tried bust, don't do it again, else it'll be a refresh loop
|
||
dependencies = [];
|
||
let errorCode = 1;
|
||
let importedGeneratorsTextContent = document.querySelector("#imported-generators").textContent;
|
||
if(importedGeneratorsTextContent === "") {
|
||
errorCode = 2;
|
||
} else {
|
||
errorCode = 3;
|
||
try {
|
||
decodeURI(importedGeneratorsTextContent);
|
||
} catch(e) {
|
||
errorCode = 4;
|
||
}
|
||
}
|
||
console.error(e);
|
||
console.error("Error parsing dependencies in embed.", errorCode);
|
||
}
|
||
}
|
||
|
||
if(/__initWithDataFromParentWindow=[1-9]/.test(window.location.href)) {
|
||
// this is so that the 'reload' button in the editor works without saving - i.e. we request the fresh, potentially-not-yet-saved-to-the-server data from the parent window.
|
||
__parentWindow.postMessage({type:"requestOutputUpdate"}, "https://perchance.org");
|
||
} else {
|
||
let fakeMessageEvent = {};
|
||
fakeMessageEvent.source = {};
|
||
fakeMessageEvent.source.postMessage = function() {};
|
||
fakeMessageEvent.data = {
|
||
generator: JSON.parse( decodeURI( document.querySelector("#preloaded-generator-data").textContent ) ),
|
||
dependencies,
|
||
};
|
||
___updateOutputMessageHandler(fakeMessageEvent);
|
||
}
|
||
|
||
});
|
||
|
||
window.addEventListener("DOMContentLoaded", function() {
|
||
var h1 = window.document.querySelector("h1");
|
||
let title;
|
||
if(h1) {
|
||
title = h1.innerText ? h1.innerText : h1.textContent; // fall back to .textContent for e.g. JSDOM which doesn't support .innerText (relevant for using JSDOM to build a hacky API)
|
||
} else {
|
||
title = window.location.pathname.slice(1).split("-").filter(function(a){return a;}).map(function(word){return word[0].toUpperCase()+word.slice(1); }).join(" ");
|
||
}
|
||
document.title = title+" ― Perchance" + (title.toLowerCase().includes("gener") ? "" : " Generator");
|
||
|
||
});</script> <style> .ldspmzjfhueifssge-ring{ display:inline-block;position:relative;width:64px;height:64px;}.ldspmzjfhueifssge-ring div{ box-sizing:border-box;display:block;position:absolute;width:51px;height:51px;margin:6px;border:6px solid #444;border-radius:50%;animation:lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;border-color:#444 transparent transparent transparent;}.ldspmzjfhueifssge-ring div:nth-child(1){ animation-delay:-0.45s;}.ldspmzjfhueifssge-ring div:nth-child(2){ animation-delay:-0.3s;}.ldspmzjfhueifssge-ring div:nth-child(3){ animation-delay:-0.15s;}@keyframes lds-ring{ 0%{ transform:rotate(0deg);}100%{ transform:rotate(360deg);}}</style> <div id="output-container"> </div> <script>// We need to make sure that when a user dynamically adds an element that has an inline event
|
||
// handler (like onclick, for example) then we make sure they can directly reference their
|
||
// top-level lists within those handlers:
|
||
let mutationCallback = function(mutationsList, observer) {
|
||
for(let mutation of mutationsList) {
|
||
|
||
for(let node of (mutation.addedNodes || [])) { // mutation.addedNodes seems to not give all descendents - just the "top-level" nodes of each addition
|
||
if(node.nodeType === 1 && (node.tagName.toLowerCase() === 'script' || node.tagName.toLowerCase() === 'style')) {
|
||
// I'm not currently handling dynamic addition of script tags, so they won't get a `with(root) { ... }` wrapping, but I think that's fine. Might add it later if needed.
|
||
// Oh, and wouldn't they already have executed anyway?
|
||
continue;
|
||
}
|
||
let addedNodesArr = [node, ...___getAllDescendentNodesIncludingTextNodes(node)]; // <-- ignores script and style nodes
|
||
for(let addedNode of addedNodesArr) {
|
||
if(addedNode.nodeType === Node.ELEMENT_NODE) {
|
||
// See below comment where I attach this handler function to learn why I commented this out.
|
||
// for(let attr of [...addedNode.attributes]) {
|
||
// processAttributeMutation(attr, addedNode);
|
||
// }
|
||
___reAttachDomElementEventsWithRoot(addedNode);
|
||
}
|
||
// See below comment where I attach this handler function to learn why I commented this out.
|
||
/*else if(addedNode.nodeType === Node.TEXT_NODE && ___isRenderableDomNode(addedNode)) {
|
||
renderDynamicallyAddedTextNode(addedNode);
|
||
}*/
|
||
}
|
||
}
|
||
|
||
if(mutation.attributeName) {
|
||
// See below comment where I attach this handler function to learn why I commented this out.
|
||
//if(mutation.target.attributes[mutation.attributeName]) processAttributeMutation(mutation.target.attributes[mutation.attributeName], mutation.target);
|
||
}
|
||
|
||
}
|
||
};
|
||
// NOTE: I originally impemented automatic evaluation on DOM mutations, but then there's this problem: https://www.reddit.com/r/perchance/comments/bz9vcu/dev_fixed_a_bug_in_the_engine_today_thanks_to/erbcjr1
|
||
// Basically, the problem is that a mutation will take {<button>button1</button>|<button>button2</button>} and spread it over FIVE DOM nodes, and so we can't render it. I was originally working under that (bad) assumption that
|
||
// each mutation would sort of be "contained" within a single text/attribute node. In retrospect this whole idea is very silly. Instead, the generator maker should render their content with evaluateItem and THEN put that into the innerHTML of some element.
|
||
// EDIT: Actually, we still need to ___reAttachDomElementEventsWithRoot for the new elements! Otherwise if they dynamically add an element (e.g. by having `output.innerHTML = someHTML` within an element's onclick handler) that itself has inline event handlers,
|
||
// then those new element's handlers wouldn't be wrapped in `with(root) { ... }`. So we still need this (but I've commented out the "rendering" stuff). Here's an example that wouldn't work without this mutation stuff: https://perchance.org/t3c1hm87wv
|
||
let ___observer = new MutationObserver(mutationCallback);
|
||
___observer.observe(document.body.querySelector("#output-container"), { childList: true, subtree: true, attributes: true });
|
||
|
||
|
||
// function processAttributeMutation(attr, ownerElement) {
|
||
// if(attr.___alreadyRenderedPerchanceCode) return; // <-- modifying the attribute will trigger the MutationObserver, and so to prevent an infinite loop, we do this.
|
||
//
|
||
// if(___isDomEventAttributeName(attr.name.slice(0, -1))) {
|
||
// if(attr.name.endsWith("\\")) {
|
||
// ownerElement.setAttribute(attr.name.slice(0, -1), processEscapedCharacters(attr.nodeValue) );
|
||
// ownerElement.removeAttribute(attr.name);
|
||
// // note that re-attaching `with(window.root){ ... }` happens after this function in the mutation handler
|
||
// }
|
||
// } else if(___isDomEventAttributeName(attr.name)) {
|
||
// // leave events (that are attached properly) alone
|
||
// } else {
|
||
// let name = attr.name;
|
||
// let value = attr.nodeValue;
|
||
// if(attr.name.endsWith("\\")) {
|
||
// name = attr.name.slice(0, -1);
|
||
// }
|
||
// ownerElement.removeAttribute(attr.name);
|
||
// let newValue = processEscapedCharacters( __evaluateText(window.root, window.root, value, {declarationLineNumber:null}) );
|
||
// ownerElement.setAttribute(name, newValue);
|
||
// ownerElement.attributes[name].___alreadyRenderedPerchanceCode = true;
|
||
// }
|
||
//
|
||
// attr.___alreadyRenderedPerchanceCode = true;
|
||
// }
|
||
|
||
|
||
// // If a user adds some text like "[animal]" to the document with some custom JavaScript, then we should
|
||
// // render that into "mouse" of whatever. If they didn't want that, then they need to escape special characters
|
||
// // with backslashes. Realisation that this is needed: https://www.reddit.com/r/perchance/comments/bpehfa/tip_heres_a_way_to_write_nicely_indented_html/er4ugxz/
|
||
// function renderDynamicallyAddedTextNode(textNode) {
|
||
// if(textNode.___alreadyRenderedPerchanceCode) return; // this prop is set on normal text node creation too (ctrl+f for ref:4378684367397)
|
||
//
|
||
// // create new nodes
|
||
// let text = processEscapedCharacters( __evaluateText(window.root, window.root, textNode.nodeValue, {declarationLineNumber:null}) );
|
||
// let newNodes = ___htmlToElements(text);
|
||
//
|
||
// // This is needed because adding these nodes will actually trigger our MutationObserver and we'd end up
|
||
// // with an infinite loop, re-rendering the text over and over.
|
||
// let allNewTextNodes = newNodes.filter(n => n.nodeType === Node.TEXT_NODE);
|
||
// for(let newNode of newNodes) {
|
||
// ___getAllTextNodeDescendents(newNode, allNewTextNodes); // this function adds the text nodes to the `allTextNodes` array
|
||
// }
|
||
// for(let textNode of allNewTextNodes) {
|
||
// textNode.___alreadyRenderedPerchanceCode = true;
|
||
// }
|
||
//
|
||
// // insert new nodes
|
||
// for(let node of newNodes) {
|
||
// if(node.nodeType === Node.TEXT_NODE) node.___alreadyRenderedPerchanceCode = true;
|
||
// // add it before the next sibling (if there is no next sibling, then it's the last one, so we just append)
|
||
// if(textNode.nextSibling && textNode.parentNode.contains(textNode.nextSibling)) textNode.parentNode.insertBefore(node, textNode.nextSibling);
|
||
// else textNode.parentNode.appendChild(node);
|
||
// }
|
||
// textNode.parentNode.removeChild(textNode);
|
||
// textNode.___alreadyRenderedPerchanceCode = true;
|
||
// }
|
||
|
||
function ___getAllDescendentNodesIncludingTextNodes(element, nodes=[]) { // but not scripts and styles...
|
||
for(let child of element.childNodes) {
|
||
if(child.nodeType === Node.ELEMENT_NODE && child.tagName.toLowerCase() !== 'script' && child.tagName.toLowerCase() !== 'style') {
|
||
nodes.push(child);
|
||
___getAllDescendentNodesIncludingTextNodes(child, nodes);
|
||
} else if(child.nodeType === Node.TEXT_NODE) {
|
||
nodes.push(child);
|
||
}
|
||
}
|
||
return nodes;
|
||
}
|
||
function ___getAllTextNodeDescendents(element, nodes=[]) { // but not scripts and styles...
|
||
for(let child of element.childNodes) {
|
||
if(child.nodeType === Node.ELEMENT_NODE && child.tagName.toLowerCase() !== 'script' && child.tagName.toLowerCase() !== 'style') {
|
||
___getAllDescendentNodesIncludingTextNodes(child, nodes);
|
||
} else if(child.nodeType === Node.TEXT_NODE) {
|
||
nodes.push(child);
|
||
}
|
||
}
|
||
return nodes;
|
||
}
|
||
function ___isRenderableDomNode(node) {
|
||
return node.nodeType === 3 || (node.nodeType === 1 && node.tagName.toLowerCase() !== 'script' && node.tagName.toLowerCase() !== 'style');
|
||
}</script> <div id="perchance-dep-load-indicator" style="display:none;position:fixed;bottom:8px;right:8px;background-color:#34ba22;color:white;cursor:pointer;"> <span style="display:inline-block;padding:0.5em;">🔃︎ Loading imported generators...</span> </div> <div onclick="__showPerchanceErrorBox();" id="perchance-error-indicator" style="display:none;position:fixed;bottom:8px;right:8px;background-color:#fc5b5b;color:white;cursor:pointer;z-index:1000000000;"> <span style="display:inline-block;padding:0.5em;">⚠︎ This generator has errors (click here) ⚠︎</span> </div> <div id="perchance-error-container" style="display:none;color:rgb(25, 25, 25);font-family:monospace;"> <div style class="background" onclick="document.querySelector('#perchance-error-container').style.display = 'none';"></div> <div style="z-index:51;" class="outer-wrapper" onclick="if(!document.querySelector('#perchance-error-container').contains(event.target)) { document.querySelector('#perchance-error-container').style.display = 'none'; }"> <div ref="contentWrapper" class="content-wrapper"> <div class="view"> <div class="modal-body" style="max-height:350px;overflow-y:auto;padding:1em;text-align:left;"> <div id="perchance-error-stream"></div> <p style="background:#b5ffb5;padding:1em;margin-bottom:0;">If you need help with errors, please post a question to the <a href="https://lemmy.world/c/perchance">perchance community</a> along with a link to your generator and someone will take a look at it for you :) </p> </div> <div class="modal-footer"> <button class="main" style="width:100%;color:white;" onclick="document.querySelector('#perchance-error-container').style.display = 'none';">close</button> </div> </div> </div> </div> </div> <style> #perchance-error-container{ display:none;position:fixed;top:0;left:0;right:0;bottom:0;font-family:monospace;z-index:1000000001;}#perchance-error-container blockquote{ background:#eee;padding:1em;}#perchance-error-container .outer-wrapper{ margin:auto;box-sizing:border-box;max-width:90%;}#perchance-error-container .background{ z-index:-1;position:fixed;top:0;left:0;width:100%;height:100%;opacity:0.2;background:#000;transition:opacity .15s linear;}#perchance-error-container .content-wrapper{ overflow:hidden;background:#fff;height:100%;width:100%;border-radius:3px;} #perchance-error-container button, #perchance-error-container input{ height:3em;}#perchance-error-container button{ background:#eee;color:#444;width:50%;border:none;outline:none;font-size:90%;}#perchance-error-container button:hover{ background:#e1e1e1;}#perchance-error-container button.main{ background:#444;color:white;}#perchance-error-container button.main:hover{ background:#333;}#perchance-error-container span.link{ cursor:pointer;text-decoration:underline;color:#1212ff;}#perchance-error-container code{ padding:0.1em 0.3em;background:#eee;}</style> <script>let __perchanceErrorString = "";
|
||
let __maxPerchanceErrorCount = 20;
|
||
let __currentPerchanceErrorCount = 0;
|
||
window.__lastPerchanceErrorTime = null;
|
||
function __perchanceError(message, ctx={}) {
|
||
// __evaluateCurlyBlock, __getTextOddsDetails, __oddsTextToNumber
|
||
window.__lastPerchanceErrorTime = Date.now();
|
||
__currentPerchanceErrorCount++;
|
||
if(__currentPerchanceErrorCount > __maxPerchanceErrorCount) return;
|
||
message = message.replace(/#<Object>/g,"#<Object>");
|
||
if(__ignorePerchanceErrors) { return; } // needed to ignore errors in "secondary parses" (like the one to extract html imports)
|
||
|
||
document.querySelector("#perchance-error-indicator").style.display = "block";
|
||
let errorEl = document.querySelector("#perchance-error-stream");
|
||
let intro;
|
||
if(ctx.declarationLineNumber) {
|
||
intro = `<span style="opacity:0.5;">${ctx.moduleName && ctx.moduleName !== window.generatorName ? `There is a problem with the '<b style="color: red; font-family: inherit;">${ctx.moduleName}</b>' generator. ` : ""}An error has occurred near <b style='color:red;'>line number ${ctx.declarationLineNumber}</b>:</span>`;
|
||
} else {
|
||
intro = `<span style="opacity:0.5;">${ctx.moduleName && ctx.moduleName !== window.generatorName ? `There is a problem with the '<b style="color: red; font-family: inherit;">${ctx.moduleName}</b>' generator. ` : ""}An error has occurred somewhere in your code (in lists or HTML):</span>`;
|
||
}
|
||
__perchanceErrorString += `<div>${intro} ${message}</div><hr style="border: 1px solid #e1e1e1;"/>`;
|
||
|
||
// The following line is a hack to make it so "pause on caught errors" works for perchance errors in devtools.
|
||
// Click the function names in the "call stack" to go "back in time" and find more details about your error (ask for help on the forum if needed)
|
||
try { throw new Error(""); } catch(e) {}
|
||
}
|
||
function __clearPerchanceErrors() {
|
||
document.querySelector("#perchance-error-container").style.display = 'none';
|
||
document.querySelector("#perchance-error-indicator").style.display = "none";
|
||
__perchanceErrorString = "";
|
||
document.querySelector("#perchance-error-stream").innerHTML = "";
|
||
__currentPerchanceErrorCount = 0;
|
||
}
|
||
window.clearPerchanceErrors = __clearPerchanceErrors; // public version
|
||
|
||
window.ignorePerchanceErrors = function(cb) {
|
||
let orig = __ignorePerchanceErrors;
|
||
__ignorePerchanceErrors = true;
|
||
let result = cb();
|
||
__ignorePerchanceErrors = orig;
|
||
return result;
|
||
};
|
||
|
||
function __showPerchanceErrorBox() {
|
||
document.querySelector("#perchance-error-stream").innerHTML = __perchanceErrorString;
|
||
|
||
// to override user styles on the page:
|
||
document.querySelectorAll("#perchance-error-container *").forEach(el => {
|
||
el.style.cssText += ";font-family:inherit;";
|
||
if(!el.style.cssText.includes("color")) el.style.cssText += ";color:inherit;";
|
||
});
|
||
|
||
document.querySelector("#perchance-error-container").style.display = 'flex';
|
||
}</script> <script>(async function() {
|
||
if((window.location.host === "null.perchance.org" || window.location.host === `${window.generatorPublicId}.perchance.org`) && !navigator["\u0077\u0065\u0062\u0064\u0072\u0069\u0076\u0065\u0072"]) {
|
||
while(1) {
|
||
await new Promise(r => { ["mouseenter", "mousemove", "touchstart"].forEach(n => document.addEventListener(n, r, { once: true })); });
|
||
while(document.visibilityState !== "visible" || !document.hasFocus()) await new Promise(r => setTimeout(r, 1000));
|
||
await new Promise(r => setTimeout(r, 1000*90));
|
||
fetch(`https://perchance.org/api/cv?generatorName=${window.location.pathname.slice(1)}&isFromEmbed=1&__cacheBust=${Math.random()}`, {mode:"no-cors"}).catch(e => console.error(e));
|
||
await new Promise(r => setTimeout(r, 1000*60*60*6));
|
||
}
|
||
}
|
||
})();</script> <script>(function() {
|
||
if(window.location.host !== "null.perchance.org" && window.location.host !== `${window.generatorPublicId}.perchance.org`) return;
|
||
|
||
let alreadySentSignal = false; // just to be sure
|
||
let interval;
|
||
|
||
let alreadyInitedFocusBugFix = false;
|
||
function initFocusBugFix() {
|
||
if(alreadyInitedFocusBugFix) return;
|
||
alreadyInitedFocusBugFix = true;
|
||
|
||
// This is to help fix the ad-related focus bug, but it's harmless to add anyway - just makes it so focus is "recovered" to the last active element, rather than the body element.
|
||
let lastActiveElementDuringFocus = null;
|
||
setInterval(() => {
|
||
if(document.hasFocus()) lastActiveElementDuringFocus = document.activeElement;
|
||
}, 1000);
|
||
window.addEventListener("focus", function() {
|
||
if(lastActiveElementDuringFocus) {
|
||
// only if it was a text input element:
|
||
const lastActiveWasTextInput = (lastActiveElementDuringFocus.nodeName === "TEXTAREA" || (lastActiveElementDuringFocus.nodeName === "INPUT" && lastActiveElementDuringFocus.type === "text"));
|
||
if(lastActiveWasTextInput) {
|
||
lastActiveElementDuringFocus.focus();
|
||
lastActiveElementDuringFocus.click();
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
let messageType = "usingAdPoweredPlugin";
|
||
|
||
// for embeds within embeds, we pass the message up the chain:
|
||
window.addEventListener("message", function(e) {
|
||
if(e.data.type === messageType) {
|
||
__parentWindow.postMessage({type:messageType}, "*"); // must use wildcard origin because could be embed within embed
|
||
}
|
||
});
|
||
|
||
function detectAdPoweredPlugin() {
|
||
if(!alreadySentSignal) {
|
||
if(window.root && window.root.$moduleSpace && (window.root.$moduleSpace["text-to-image-plugin"] || window.root.$moduleSpace["ai-text-plugin"])) {
|
||
__parentWindow.postMessage({type:messageType}, "*"); // must use wildcard origin because could be embed within embed
|
||
initFocusBugFix();
|
||
clearInterval(interval);
|
||
alreadySentSignal = true;
|
||
return;
|
||
}
|
||
if([...document.querySelectorAll("iframe")].filter(el => el.src.startsWith("https://image-generation.perchance.org/embed") || el.src.startsWith("https://text-generation.perchance.org/embed")).length > 0) {
|
||
__parentWindow.postMessage({type:messageType}, "*"); // must use wildcard origin because could be embed within embed
|
||
initFocusBugFix();
|
||
clearInterval(interval);
|
||
alreadySentSignal = true;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
interval = setInterval(detectAdPoweredPlugin, 1000);
|
||
setTimeout(() => {
|
||
clearInterval(interval);
|
||
if(!alreadySentSignal) {
|
||
interval = setInterval(detectAdPoweredPlugin, 10000);
|
||
setTimeout(() => clearInterval(interval), 2*60*1000);
|
||
}
|
||
}, 10000);
|
||
})();</script> <script>(async function() {
|
||
// Here we tell the server to update the cache if needed, and if it did, then we temporarily bust the cache using a query string.
|
||
if(window.location.host === "null.perchance.org" || window.location.host === `${window.generatorPublicId}.perchance.org`) { // only if this HTML file is hosted at null.perchance.org / <publidId>.perchance.org
|
||
if(navigator.webdriver) return; // just in case this is what's confusing the Google crawler - RE the title bug
|
||
if(window.location.href.includes("__cacheBust")) return; // no need to run this check if cache is already busted
|
||
if(/__initWithDataFromParentWindow=[1-9]/.test(window.location.href)) return; // data is being loaded from parent
|
||
|
||
let imports = JSON.parse(decodeURI(document.querySelector("#imported-generator-names").textContent));
|
||
let clientHtmlServerRenderTime = Number(document.querySelector("#this-html-server-render-time").textContent);
|
||
|
||
let weHaveAnOldVersionOfThisGen = await fetch(`https://perchance.org/api/clearCacheIfGeneratorOrImportsHaveBeenUpdated?generatorName=${window.location.pathname.slice(1)}&importedGeneratorNames=${imports.join(",")}&clientHtmlServerRenderTime=${clientHtmlServerRenderTime}`).then(r => r.json());
|
||
if(weHaveAnOldVersionOfThisGen) {
|
||
let url = new URL(window.location.href);
|
||
url.searchParams.set("__cacheBust", Math.random());
|
||
window.location.href = url.href;
|
||
}
|
||
}
|
||
})();
|
||
if(location.href.includes("__cacheBust")) {
|
||
let url = new URL(window.location.href);
|
||
url.searchParams.delete("__cacheBust");
|
||
history.replaceState({}, "", url.href);
|
||
}</script> <script>document.addEventListener("DOMContentLoaded", function() {
|
||
if(!window.location.href.startsWith("file:") || window.location.hash !== "#edit") return;
|
||
|
||
let originalHtmlText = document.documentElement.outerHTML; // for editing + saving later
|
||
|
||
let preloadedGeneratorDataEl = document.querySelector("#preloaded-generator-data");
|
||
let preloadedGeneratorData = JSON.parse(decodeURI(preloadedGeneratorDataEl.textContent));
|
||
|
||
let importedGeneratorsEl = document.querySelector("#imported-generators");
|
||
let importedGenerators = JSON.parse(decodeURI(importedGeneratorsEl.textContent));
|
||
|
||
let importedGeneratorNamesEl = document.querySelector("#imported-generator-names");
|
||
let importedGeneratorNames = JSON.parse(decodeURI(importedGeneratorNamesEl.textContent));
|
||
|
||
function saveTextFile(text, name) {
|
||
let el = document.createElement("a");
|
||
let extension = name.split(".").pop();
|
||
let type = extension === "txt" ? "plain" : extension;
|
||
let file = new Blob([text], {type:"text/"+extension});
|
||
let url = URL.createObjectURL(file);
|
||
el.href = url;
|
||
el.download = name;
|
||
el.style.display = 'none';
|
||
document.body.appendChild(el);
|
||
el.click();
|
||
document.body.removeChild(el);
|
||
setTimeout(() => URL.revokeObjectURL(url), 10000);
|
||
}
|
||
|
||
function makeElementDraggable(el) { // This function expects `el` to contain an element with the `drag-handle` class.
|
||
let endX = 0, endY = 0, startX = 0, startY = 0;
|
||
let dragHandleEl = el.querySelector(".drag-handle");
|
||
dragHandleEl.addEventListener("mousedown", dragMouseDown);
|
||
|
||
function dragMouseDown(e) {
|
||
e = e || window.event;
|
||
e.preventDefault();
|
||
// get the mouse cursor position at startup:
|
||
startX = e.clientX;
|
||
startY = e.clientY;
|
||
document.addEventListener("mouseup", closeDragElement);
|
||
document.addEventListener("mousemove", elementDrag);
|
||
}
|
||
|
||
function elementDrag(e) {
|
||
e = e || window.event;
|
||
e.preventDefault();
|
||
// calculate the new cursor position:
|
||
endX = startX - e.clientX;
|
||
endY = startY - e.clientY;
|
||
startX = e.clientX;
|
||
startY = e.clientY;
|
||
// set the element's new position:
|
||
el.style.top = (el.offsetTop - endY) + "px";
|
||
el.style.left = (el.offsetLeft - endX) + "px";
|
||
}
|
||
|
||
function closeDragElement() {
|
||
// stop moving when mouse button is released:
|
||
document.removeEventListener("mouseup", closeDragElement);
|
||
document.removeEventListener("mousemove", elementDrag);
|
||
}
|
||
}
|
||
|
||
|
||
let editorCtn = document.createElement("div");
|
||
editorCtn.style.cssText = "width:700px; height:500px; position:fixed; display: flex; flex-direction: column;";
|
||
editorCtn.innerHTML = `
|
||
<div class="header" style="display:flex; overflow:auto;">
|
||
<!-- <div class="drag-handle" style=" display: flex; background: #e8e8e8; padding: 1rem;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="width: 2rem;"><path d="M278.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8h32v96H128V192c0-12.9-7.8-24.6-19.8-29.6s-25.7-2.2-34.9 6.9l-64 64c-12.5 12.5-12.5 32.8 0 45.3l64 64c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V288h96v96H192c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8H288V288h96v32c0 12.9 7.8 24.6 19.8 29.6s25.7 2.2 34.9-6.9l64-64c12.5-12.5 12.5-32.8 0-45.3l-64-64c-9.2-9.2-22.9-11.9-34.9-6.9s-19.8 16.6-19.8 29.6v32H288V128h32c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-64-64z"></path></svg></div> -->
|
||
<button class="drag-handle">drag</button>
|
||
<button class="save-button">save</button>
|
||
<div style="">
|
||
<div class="tabs" style="display:flex; width:max-content;">
|
||
<!-- tabs get inserted here -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="body" style="flex-grow:1;">
|
||
<!-- text editors get inserted here -->
|
||
</div>
|
||
`;
|
||
|
||
makeElementDraggable(editorCtn);
|
||
|
||
let editors = [];
|
||
editors.push({
|
||
name: preloadedGeneratorData.name,
|
||
content: preloadedGeneratorData.modelText,
|
||
main: true,
|
||
type: "lists",
|
||
visible: true,
|
||
});
|
||
editors.push({
|
||
name: preloadedGeneratorData.name,
|
||
content: preloadedGeneratorData.outputTemplate,
|
||
main: true,
|
||
type: "html",
|
||
visible: false,
|
||
});
|
||
for(let gen of importedGenerators) {
|
||
editors.push({
|
||
name: gen.name,
|
||
content: gen.modelText,
|
||
visible: false,
|
||
});
|
||
}
|
||
|
||
function saveGenerator() {
|
||
let preloadedGeneratorData_new = JSON.parse(JSON.stringify(preloadedGeneratorData));
|
||
preloadedGeneratorData_new.modelText = editors.filter(e => e.main && e.type=="lists")[0].textArea.value;
|
||
preloadedGeneratorData_new.outputTemplate = editors.filter(e => e.main && e.type=="html")[0].textArea.value;
|
||
|
||
let importedGenerators_new = JSON.parse(JSON.stringify(importedGenerators));
|
||
for(let editor of editors) {
|
||
if(editor.main) continue;
|
||
importedGenerators_new.filter(e => e.name===editor.name)[0].modelText = editor.textArea.value;
|
||
}
|
||
let text = originalHtmlText;
|
||
text = text.replace(/(<script id="preloaded-generator-data"[^>]*>)(.+?)(<\/script>)/, `$1${encodeURI(JSON.stringify(preloadedGeneratorData_new))}$3`);
|
||
text = text.replace(/(<script id="imported-generators"[^>]*>)(.+?)(<\/script>)/, `$1${encodeURI(JSON.stringify(importedGenerators_new))}$3`);
|
||
// TODO: Add `imported-generator-names` when you've added the ability to add more generators.
|
||
saveTextFile(text, preloadedGeneratorData_new.name+".html");
|
||
};
|
||
editorCtn.querySelector(".save-button").onclick = saveGenerator;
|
||
document.addEventListener("keydown", function(e) {
|
||
if(e.key === 's' && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
|
||
e.preventDefault();
|
||
saveGenerator();
|
||
}
|
||
}, false);
|
||
|
||
for(let editor of editors) {
|
||
let textArea = document.createElement("textarea");
|
||
textArea.style.cssText = `width:100%; height:100%; display:${editor.visible ? "block" : "none"}; white-space:pre; font-family:monospace; tab-size:2;`;
|
||
textArea.value = editor.content;
|
||
editorCtn.querySelector(".body").appendChild(textArea);
|
||
editor.textArea = textArea;
|
||
|
||
// TODO: Handle resizing of the editor properly:
|
||
// new ResizeObserver(resizeHandler).observe(textArea)
|
||
|
||
let tabButton = document.createElement("button");
|
||
tabButton.innerHTML = `${editor.name}${editor.type=="html" ? " (html)" : ""}`;
|
||
tabButton.style.cssText = `width:max-content; ${editor.main ? "font-weight:bold;" : ""} ${editor.visible ? "color:green;" : ""}`;
|
||
tabButton.onclick = () => {
|
||
editors.forEach(e => e.textArea.style.display="none");
|
||
editors.forEach(e => e.tabButton.style.color="");
|
||
textArea.style.display = "block";
|
||
tabButton.style.color = "green";
|
||
};
|
||
editorCtn.querySelector(".tabs").appendChild(tabButton);
|
||
editor.tabButton = tabButton;
|
||
}
|
||
|
||
document.body.appendChild(editorCtn);
|
||
|
||
});</script> <script>// this is for transferring data across to the new generator-specific subdomains.
|
||
// it's no longer enabled by default - you need to add ?transferDataFromOldSubdomain to the end of the generator's URL.
|
||
// this code can probably be removed - just leaving it here for a few more months in case of forum posts asking about old data .
|
||
(async function() {
|
||
if(localStorage[`___subdomainLocalStorageAlreadyTransferred`] || !(document.referrer+"").includes("transferDataFromOldSubdomain")) {
|
||
return;
|
||
}
|
||
|
||
// this is for the embedded null.perchance.org subdomain that we create
|
||
if(window.location.host === "null.perchance.org") {
|
||
let alreadyResponded = false;
|
||
window.addEventListener('message', async function (e) {
|
||
if(e.origin !== `https://${window.generatorPublicId}.perchance.org`) return;
|
||
if(e.data.generatorName !== window.generatorName) return;
|
||
if(e.data.message !== "pls gib localstorage") return;
|
||
if(alreadyResponded) return;
|
||
alreadyResponded = true;
|
||
console.log("null subdomain received request for localstorage from publicid subdomain");
|
||
|
||
// reply with stringified localStorage data:
|
||
e.source.postMessage({generatorName:window.generatorName, localStorage:JSON.stringify(localStorage)}, e.origin);
|
||
});
|
||
}
|
||
|
||
// transfer across localStorage from null.perchance.org if this is the first time this was loaded
|
||
if(window.location.host.endsWith(".perchance.org") && window.location.host !== "null.perchance.org") {
|
||
// add a null.perchance.org iframe to the page and listen for a message from it
|
||
let iframe = document.createElement("iframe");
|
||
|
||
let alreadyGotData = false;
|
||
window.addEventListener('message', async function (e) {
|
||
if(e.origin !== "https://null.perchance.org" || e.data.generatorName !== window.generatorName || !e.data.localStorage) return;
|
||
if(alreadyGotData) return;
|
||
alreadyGotData = true;
|
||
iframe.remove();
|
||
let data = JSON.parse(e.data.localStorage);
|
||
let thereWasData = false;
|
||
for(let key in data) {
|
||
localStorage.setItem(key, data[key]);
|
||
thereWasData = true;
|
||
}
|
||
localStorage[`___subdomainLocalStorageAlreadyTransferred`] = "1";
|
||
console.log("FINISHED localstorage subdomain transfer");
|
||
if(thereWasData) {
|
||
window.location.reload();
|
||
}
|
||
});
|
||
|
||
iframe.style.cssText = "opacity:0.01; position:fixed; top:-100px; left:-100px; width:5px; height:5px; pointer-events:none;";
|
||
iframe.onload = async function() {
|
||
await new Promise(r => setTimeout(r, 3000)); // just to be sure it's ready
|
||
if(!alreadyGotData) {
|
||
iframe.contentWindow.postMessage({generatorName:window.generatorName, message:"pls gib localstorage"}, "https://null.perchance.org");
|
||
console.log("ONLOAD: publicid subdomain sent request for localstorage to null subdomain");
|
||
}
|
||
};
|
||
iframe.src = `https://null.perchance.org/${window.generatorName}?doNotRedirectToPublicIdSubdomain=1`;
|
||
document.body.appendChild(iframe);
|
||
|
||
// we spam requests until it loads (since onload may fire quite late since it waits for all remote scripts/images/etc. to load)
|
||
// we have alreadyResponded and alreadyGotData so this doesn't cause any problems.
|
||
(async function() {
|
||
let i = 0;
|
||
while(i < 10) {
|
||
await new Promise(r => setTimeout(r, 500));
|
||
if(alreadyGotData) return;
|
||
iframe.contentWindow.postMessage({generatorName:window.generatorName, message:"pls gib localstorage"}, "https://null.perchance.org");
|
||
console.log(`spamin': ${i} publicid subdomain sent request for localstorage to null subdomain`);
|
||
i++;
|
||
}
|
||
})();
|
||
}
|
||
})();</script> <script defer src="https://static.cloudflareinsights.com/beacon.min.js/vef91dfe02fce4ee0ad053f6de4f175db1715022073587" integrity="sha512-sDIX0kl85v1Cl5tu4WGLZCpH/dV9OHbA4YlKCuCiMmOQIk4buzoYDZSFj+TvC71mOBLh8CDC/REgE0GX0xcbjA==" data-cf-beacon='{"rayId":"88f1084fbcd1cb05","r":1,"version":"2024.4.1","token":"fc685cb0ca0145b3acbca350b7d29943"}' crossorigin="anonymous"></script>
|
||
</body> </html> |