Brunobkr/llama.cpp_AlgMor24_github
ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.
03k
1(function (global, factory) {2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :3 typeof define === 'function' && define.amd ? define(factory) :4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.MagicString = factory());5})(this, (function () { 'use strict';6 7 class BitSet {8 constructor(arg) {9 this.bits = arg instanceof BitSet ? arg.bits.slice() : [];10 }11 12 add(n) {13 this.bits[n >> 5] |= 1 << (n & 31);14 }15 16 has(n) {17 return !!(this.bits[n >> 5] & (1 << (n & 31)));18 }19 }20 21 class Chunk {22 constructor(start, end, content) {23 this.start = start;24 this.end = end;25 this.original = content;26 27 this.intro = '';28 this.outro = '';29 30 this.content = content;31 this.storeName = false;32 this.edited = false;33 34 {35 this.previous = null;36 this.next = null;37 }38 }39 40 appendLeft(content) {41 this.outro += content;42 }43 44 appendRight(content) {45 this.intro = this.intro + content;46 }47 48 clone() {49 const chunk = new Chunk(this.start, this.end, this.original);50 51 chunk.intro = this.intro;52 chunk.outro = this.outro;53 chunk.content = this.content;54 chunk.storeName = this.storeName;55 chunk.edited = this.edited;56 57 return chunk;58 }59 60 contains(index) {61 return this.start < index && index < this.end;62 }63 64 eachNext(fn) {65 let chunk = this;66 while (chunk) {67 fn(chunk);68 chunk = chunk.next;69 }70 }71 72 eachPrevious(fn) {73 let chunk = this;74 while (chunk) {75 fn(chunk);76 chunk = chunk.previous;77 }78 }79 80 edit(content, storeName, contentOnly) {81 this.content = content;82 if (!contentOnly) {83 this.intro = '';84 this.outro = '';85 }86 this.storeName = storeName;87 88 this.edited = true;89 90 return this;91 }92 93 prependLeft(content) {94 this.outro = content + this.outro;95 }96 97 prependRight(content) {98 this.intro = content + this.intro;99 }100 101 reset() {102 this.intro = '';103 this.outro = '';104 if (this.edited) {105 this.content = this.original;106 this.storeName = false;107 this.edited = false;108 }109 }110 111 split(index) {112 const sliceIndex = index - this.start;113 114 const originalBefore = this.original.slice(0, sliceIndex);115 const originalAfter = this.original.slice(sliceIndex);116 117 this.original = originalBefore;118 119 const newChunk = new Chunk(index, this.end, originalAfter);120 newChunk.outro = this.outro;121 this.outro = '';122 123 this.end = index;124 125 if (this.edited) {126 // after split we should save the edit content record into the correct chunk127 // to make sure sourcemap correct128 // For example:129 // ' test'.trim()130 // split -> ' ' + 'test'131 // ✔️ edit -> '' + 'test'132 // ✖️ edit -> 'test' + ''133 // TODO is this block necessary?...134 newChunk.edit('', false);135 this.content = '';136 } else {137 this.content = originalBefore;138 }139 140 newChunk.next = this.next;141 if (newChunk.next) newChunk.next.previous = newChunk;142 newChunk.previous = this;143 this.next = newChunk;144 145 return newChunk;146 }147 148 toString() {149 return this.intro + this.content + this.outro;150 }151 152 trimEnd(rx) {153 this.outro = this.outro.replace(rx, '');154 if (this.outro.length) return true;155 156 const trimmed = this.content.replace(rx, '');157 158 if (trimmed.length) {159 if (trimmed !== this.content) {160 this.split(this.start + trimmed.length).edit('', undefined, true);161 if (this.edited) {162 // save the change, if it has been edited163 this.edit(trimmed, this.storeName, true);164 }165 }166 return true;167 } else {168 this.edit('', undefined, true);169 170 this.intro = this.intro.replace(rx, '');171 if (this.intro.length) return true;172 }173 }174 175 trimStart(rx) {176 this.intro = this.intro.replace(rx, '');177 if (this.intro.length) return true;178 179 const trimmed = this.content.replace(rx, '');180 181 if (trimmed.length) {182 if (trimmed !== this.content) {183 const newChunk = this.split(this.end - trimmed.length);184 if (this.edited) {185 // save the change, if it has been edited186 newChunk.edit(trimmed, this.storeName, true);187 }188 this.edit('', undefined, true);189 }190 return true;191 } else {192 this.edit('', undefined, true);193 194 this.outro = this.outro.replace(rx, '');195 if (this.outro.length) return true;196 }197 }198 }199 200 // src/vlq.ts201 var comma = ",".charCodeAt(0);202 var semicolon = ";".charCodeAt(0);203 var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";204 var intToChar = new Uint8Array(64);205 var charToInt = new Uint8Array(128);206 for (let i = 0; i < chars.length; i++) {207 const c = chars.charCodeAt(i);208 intToChar[i] = c;209 charToInt[c] = i;210 }211 function encodeInteger(builder, num, relative) {212 let delta = num - relative;213 delta = delta < 0 ? -delta << 1 | 1 : delta << 1;214 do {215 let clamped = delta & 31;216 delta >>>= 5;217 if (delta > 0) clamped |= 32;218 builder.write(intToChar[clamped]);219 } while (delta > 0);220 return num;221 }222 223 // src/strings.ts224 var bufLength = 1024 * 16;225 var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? {226 decode(buf) {227 const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);228 return out.toString();229 }230 } : {231 decode(buf) {232 let out = "";233 for (let i = 0; i < buf.length; i++) {234 out += String.fromCharCode(buf[i]);235 }236 return out;237 }238 };239 var StringWriter = class {240 constructor() {241 this.pos = 0;242 this.out = "";243 this.buffer = new Uint8Array(bufLength);244 }245 write(v) {246 const { buffer } = this;247 buffer[this.pos++] = v;248 if (this.pos === bufLength) {249 this.out += td.decode(buffer);250 this.pos = 0;251 }252 }253 flush() {254 const { buffer, out, pos } = this;255 return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;256 }257 };258 function encode(decoded) {259 const writer = new StringWriter();260 let sourcesIndex = 0;261 let sourceLine = 0;262 let sourceColumn = 0;263 let namesIndex = 0;264 for (let i = 0; i < decoded.length; i++) {265 const line = decoded[i];266 if (i > 0) writer.write(semicolon);267 if (line.length === 0) continue;268 let genColumn = 0;269 for (let j = 0; j < line.length; j++) {270 const segment = line[j];271 if (j > 0) writer.write(comma);272 genColumn = encodeInteger(writer, segment[0], genColumn);273 if (segment.length === 1) continue;274 sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);275 sourceLine = encodeInteger(writer, segment[2], sourceLine);276 sourceColumn = encodeInteger(writer, segment[3], sourceColumn);277 if (segment.length === 4) continue;278 namesIndex = encodeInteger(writer, segment[4], namesIndex);279 }280 }281 return writer.flush();282 }283 284 function getBtoa() {285 if (typeof globalThis !== 'undefined' && typeof globalThis.btoa === 'function') {286 return (str) => globalThis.btoa(unescape(encodeURIComponent(str)));287 } else if (typeof Buffer === 'function') {288 return (str) => Buffer.from(str, 'utf-8').toString('base64');289 } else {290 return () => {291 throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');292 };293 }294 }295 296 const btoa = /*#__PURE__*/ getBtoa();297 298 class SourceMap {299 constructor(properties) {300 this.version = 3;301 this.file = properties.file;302 this.sources = properties.sources;303 this.sourcesContent = properties.sourcesContent;304 this.names = properties.names;305 this.mappings = encode(properties.mappings);306 if (typeof properties.x_google_ignoreList !== 'undefined') {307 this.x_google_ignoreList = properties.x_google_ignoreList;308 }309 if (typeof properties.debugId !== 'undefined') {310 this.debugId = properties.debugId;311 }312 }313 314 toString() {315 return JSON.stringify(this);316 }317 318 toUrl() {319 return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());320 }321 }322 323 function guessIndent(code) {324 const lines = code.split('\n');325 326 const tabbed = lines.filter((line) => /^\t+/.test(line));327 const spaced = lines.filter((line) => /^ {2,}/.test(line));328 329 if (tabbed.length === 0 && spaced.length === 0) {330 return null;331 }332 333 // More lines tabbed than spaced? Assume tabs, and334 // default to tabs in the case of a tie (or nothing335 // to go on)336 if (tabbed.length >= spaced.length) {337 return '\t';338 }339 340 // Otherwise, we need to guess the multiple341 const min = spaced.reduce((previous, current) => {342 const numSpaces = /^ +/.exec(current)[0].length;343 return Math.min(numSpaces, previous);344 }, Infinity);345 346 return new Array(min + 1).join(' ');347 }348 349 function getRelativePath(from, to) {350 const fromParts = from.split(/[/\\]/);351 const toParts = to.split(/[/\\]/);352 353 fromParts.pop(); // get dirname354 355 while (fromParts[0] === toParts[0]) {356 fromParts.shift();357 toParts.shift();358 }359 360 if (fromParts.length) {361 let i = fromParts.length;362 while (i--) fromParts[i] = '..';363 }364 365 return fromParts.concat(toParts).join('/');366 }367 368 const toString = Object.prototype.toString;369 370 function isObject(thing) {371 return toString.call(thing) === '[object Object]';372 }373 374 function getLocator(source) {375 const originalLines = source.split('\n');376 const lineOffsets = [];377 378 for (let i = 0, pos = 0; i < originalLines.length; i++) {379 lineOffsets.push(pos);380 pos += originalLines[i].length + 1;381 }382 383 return function locate(index) {384 let i = 0;385 let j = lineOffsets.length;386 while (i < j) {387 const m = (i + j) >> 1;388 if (index < lineOffsets[m]) {389 j = m;390 } else {391 i = m + 1;392 }393 }394 const line = i - 1;395 const column = index - lineOffsets[line];396 return { line, column };397 };398 }399 400 const wordRegex = /\w/;401 402 class Mappings {403 constructor(hires) {404 this.hires = hires;405 this.generatedCodeLine = 0;406 this.generatedCodeColumn = 0;407 this.raw = [];408 this.rawSegments = this.raw[this.generatedCodeLine] = [];409 this.pending = null;410 }411 412 addEdit(sourceIndex, content, loc, nameIndex) {413 if (content.length) {414 const contentLengthMinusOne = content.length - 1;415 let contentLineEnd = content.indexOf('\n', 0);416 let previousContentLineEnd = -1;417 // Loop through each line in the content and add a segment, but stop if the last line is empty,418 // else code afterwards would fill one line too many419 while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {420 const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];421 if (nameIndex >= 0) {422 segment.push(nameIndex);423 }424 this.rawSegments.push(segment);425 426 this.generatedCodeLine += 1;427 this.raw[this.generatedCodeLine] = this.rawSegments = [];428 this.generatedCodeColumn = 0;429 430 previousContentLineEnd = contentLineEnd;431 contentLineEnd = content.indexOf('\n', contentLineEnd + 1);432 }433 434 const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];435 if (nameIndex >= 0) {436 segment.push(nameIndex);437 }438 this.rawSegments.push(segment);439 440 this.advance(content.slice(previousContentLineEnd + 1));441 } else if (this.pending) {442 this.rawSegments.push(this.pending);443 this.advance(content);444 }445 446 this.pending = null;447 }448 449 addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {450 let originalCharIndex = chunk.start;451 let first = true;452 // when iterating each char, check if it's in a word boundary453 let charInHiresBoundary = false;454 455 while (originalCharIndex < chunk.end) {456 if (original[originalCharIndex] === '\n') {457 loc.line += 1;458 loc.column = 0;459 this.generatedCodeLine += 1;460 this.raw[this.generatedCodeLine] = this.rawSegments = [];461 this.generatedCodeColumn = 0;462 first = true;463 charInHiresBoundary = false;464 } else {465 if (this.hires || first || sourcemapLocations.has(originalCharIndex)) {466 const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];467 468 if (this.hires === 'boundary') {469 // in hires "boundary", group segments per word boundary than per char470 if (wordRegex.test(original[originalCharIndex])) {471 // for first char in the boundary found, start the boundary by pushing a segment472 if (!charInHiresBoundary) {473 this.rawSegments.push(segment);474 charInHiresBoundary = true;475 }476 } else {477 // for non-word char, end the boundary by pushing a segment478 this.rawSegments.push(segment);479 charInHiresBoundary = false;480 }481 } else {482 this.rawSegments.push(segment);483 }484 }485 486 loc.column += 1;487 this.generatedCodeColumn += 1;488 first = false;489 }490 491 originalCharIndex += 1;492 }493 494 this.pending = null;495 }496 497 advance(str) {498 if (!str) return;499 500 const lines = str.split('\n');501 502 if (lines.length > 1) {503 for (let i = 0; i < lines.length - 1; i++) {504 this.generatedCodeLine++;505 this.raw[this.generatedCodeLine] = this.rawSegments = [];506 }507 this.generatedCodeColumn = 0;508 }509 510 this.generatedCodeColumn += lines[lines.length - 1].length;511 }512 }513 514 const n = '\n';515 516 const warned = {517 insertLeft: false,518 insertRight: false,519 storeName: false,520 };521 522 class MagicString {523 constructor(string, options = {}) {524 const chunk = new Chunk(0, string.length, string);525 526 Object.defineProperties(this, {527 original: { writable: true, value: string },528 outro: { writable: true, value: '' },529 intro: { writable: true, value: '' },530 firstChunk: { writable: true, value: chunk },531 lastChunk: { writable: true, value: chunk },532 lastSearchedChunk: { writable: true, value: chunk },533 byStart: { writable: true, value: {} },534 byEnd: { writable: true, value: {} },535 filename: { writable: true, value: options.filename },536 indentExclusionRanges: { writable: true, value: options.indentExclusionRanges },537 sourcemapLocations: { writable: true, value: new BitSet() },538 storedNames: { writable: true, value: {} },539 indentStr: { writable: true, value: undefined },540 ignoreList: { writable: true, value: options.ignoreList },541 offset: { writable: true, value: options.offset || 0 },542 });543 544 this.byStart[0] = chunk;545 this.byEnd[string.length] = chunk;546 }547 548 addSourcemapLocation(char) {549 this.sourcemapLocations.add(char);550 }551 552 append(content) {553 if (typeof content !== 'string') throw new TypeError('outro content must be a string');554 555 this.outro += content;556 return this;557 }558 559 appendLeft(index, content) {560 index = index + this.offset;561 562 if (typeof content !== 'string') throw new TypeError('inserted content must be a string');563 564 this._split(index);565 566 const chunk = this.byEnd[index];567 568 if (chunk) {569 chunk.appendLeft(content);570 } else {571 this.intro += content;572 }573 return this;574 }575 576 appendRight(index, content) {577 index = index + this.offset;578 579 if (typeof content !== 'string') throw new TypeError('inserted content must be a string');580 581 this._split(index);582 583 const chunk = this.byStart[index];584 585 if (chunk) {586 chunk.appendRight(content);587 } else {588 this.outro += content;589 }590 return this;591 }592 593 clone() {594 const cloned = new MagicString(this.original, { filename: this.filename, offset: this.offset });595 596 let originalChunk = this.firstChunk;597 let clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());598 599 while (originalChunk) {600 cloned.byStart[clonedChunk.start] = clonedChunk;601 cloned.byEnd[clonedChunk.end] = clonedChunk;602 603 const nextOriginalChunk = originalChunk.next;604 const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();605 606 if (nextClonedChunk) {607 clonedChunk.next = nextClonedChunk;608 nextClonedChunk.previous = clonedChunk;609 610 clonedChunk = nextClonedChunk;611 }612 613 originalChunk = nextOriginalChunk;614 }615 616 cloned.lastChunk = clonedChunk;617 618 if (this.indentExclusionRanges) {619 cloned.indentExclusionRanges = this.indentExclusionRanges.slice();620 }621 622 cloned.sourcemapLocations = new BitSet(this.sourcemapLocations);623 624 cloned.intro = this.intro;625 cloned.outro = this.outro;626 627 return cloned;628 }629 630 generateDecodedMap(options) {631 options = options || {};632 633 const sourceIndex = 0;634 const names = Object.keys(this.storedNames);635 const mappings = new Mappings(options.hires);636 637 const locate = getLocator(this.original);638 639 if (this.intro) {640 mappings.advance(this.intro);641 }642 643 this.firstChunk.eachNext((chunk) => {644 const loc = locate(chunk.start);645 646 if (chunk.intro.length) mappings.advance(chunk.intro);647 648 if (chunk.edited) {649 mappings.addEdit(650 sourceIndex,651 chunk.content,652 loc,653 chunk.storeName ? names.indexOf(chunk.original) : -1,654 );655 } else {656 mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);657 }658 659 if (chunk.outro.length) mappings.advance(chunk.outro);660 });661 662 if (this.outro) {663 mappings.advance(this.outro);664 }665 666 return {667 file: options.file ? options.file.split(/[/\\]/).pop() : undefined,668 sources: [669 options.source ? getRelativePath(options.file || '', options.source) : options.file || '',670 ],671 sourcesContent: options.includeContent ? [this.original] : undefined,672 names,673 mappings: mappings.raw,674 x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined,675 };676 }677 678 generateMap(options) {679 return new SourceMap(this.generateDecodedMap(options));680 }681 682 _ensureindentStr() {683 if (this.indentStr === undefined) {684 this.indentStr = guessIndent(this.original);685 }686 }687 688 _getRawIndentString() {689 this._ensureindentStr();690 return this.indentStr;691 }692 693 getIndentString() {694 this._ensureindentStr();695 return this.indentStr === null ? '\t' : this.indentStr;696 }697 698 indent(indentStr, options) {699 const pattern = /^[^\r\n]/gm;700 701 if (isObject(indentStr)) {702 options = indentStr;703 indentStr = undefined;704 }705 706 if (indentStr === undefined) {707 this._ensureindentStr();708 indentStr = this.indentStr || '\t';709 }710 711 if (indentStr === '') return this; // noop712 713 options = options || {};714 715 // Process exclusion ranges716 const isExcluded = {};717 718 if (options.exclude) {719 const exclusions =720 typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;721 exclusions.forEach((exclusion) => {722 for (let i = exclusion[0]; i < exclusion[1]; i += 1) {723 isExcluded[i] = true;724 }725 });726 }727 728 let shouldIndentNextCharacter = options.indentStart !== false;729 const replacer = (match) => {730 if (shouldIndentNextCharacter) return `${indentStr}${match}`;731 shouldIndentNextCharacter = true;732 return match;733 };734 735 this.intro = this.intro.replace(pattern, replacer);736 737 let charIndex = 0;738 let chunk = this.firstChunk;739 740 while (chunk) {741 const end = chunk.end;742 743 if (chunk.edited) {744 if (!isExcluded[charIndex]) {745 chunk.content = chunk.content.replace(pattern, replacer);746 747 if (chunk.content.length) {748 shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n';749 }750 }751 } else {752 charIndex = chunk.start;753 754 while (charIndex < end) {755 if (!isExcluded[charIndex]) {756 const char = this.original[charIndex];757 758 if (char === '\n') {759 shouldIndentNextCharacter = true;760 } else if (char !== '\r' && shouldIndentNextCharacter) {761 shouldIndentNextCharacter = false;762 763 if (charIndex === chunk.start) {764 chunk.prependRight(indentStr);765 } else {766 this._splitChunk(chunk, charIndex);767 chunk = chunk.next;768 chunk.prependRight(indentStr);769 }770 }771 }772 773 charIndex += 1;774 }775 }776 777 charIndex = chunk.end;778 chunk = chunk.next;779 }780 781 this.outro = this.outro.replace(pattern, replacer);782 783 return this;784 }785 786 insert() {787 throw new Error(788 'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)',789 );790 }791 792 insertLeft(index, content) {793 if (!warned.insertLeft) {794 console.warn(795 'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead',796 );797 warned.insertLeft = true;798 }799 800 return this.appendLeft(index, content);801 }802 803 insertRight(index, content) {804 if (!warned.insertRight) {805 console.warn(806 'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead',807 );808 warned.insertRight = true;809 }810 811 return this.prependRight(index, content);812 }813 814 move(start, end, index) {815 start = start + this.offset;816 end = end + this.offset;817 index = index + this.offset;818 819 if (index >= start && index <= end) throw new Error('Cannot move a selection inside itself');820 821 this._split(start);822 this._split(end);823 this._split(index);824 825 const first = this.byStart[start];826 const last = this.byEnd[end];827 828 const oldLeft = first.previous;829 const oldRight = last.next;830 831 const newRight = this.byStart[index];832 if (!newRight && last === this.lastChunk) return this;833 const newLeft = newRight ? newRight.previous : this.lastChunk;834 835 if (oldLeft) oldLeft.next = oldRight;836 if (oldRight) oldRight.previous = oldLeft;837 838 if (newLeft) newLeft.next = first;839 if (newRight) newRight.previous = last;840 841 if (!first.previous) this.firstChunk = last.next;842 if (!last.next) {843 this.lastChunk = first.previous;844 this.lastChunk.next = null;845 }846 847 first.previous = newLeft;848 last.next = newRight || null;849 850 if (!newLeft) this.firstChunk = first;851 if (!newRight) this.lastChunk = last;852 return this;853 }854 855 overwrite(start, end, content, options) {856 options = options || {};857 return this.update(start, end, content, { ...options, overwrite: !options.contentOnly });858 }859 860 update(start, end, content, options) {861 start = start + this.offset;862 end = end + this.offset;863 864 if (typeof content !== 'string') throw new TypeError('replacement content must be a string');865 866 if (this.original.length !== 0) {867 while (start < 0) start += this.original.length;868 while (end < 0) end += this.original.length;869 }870 871 if (end > this.original.length) throw new Error('end is out of bounds');872 if (start === end)873 throw new Error(874 'Cannot overwrite a zero-length range – use appendLeft or prependRight instead',875 );876 877 this._split(start);878 this._split(end);879 880 if (options === true) {881 if (!warned.storeName) {882 console.warn(883 'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string',884 );885 warned.storeName = true;886 }887 888 options = { storeName: true };889 }890 const storeName = options !== undefined ? options.storeName : false;891 const overwrite = options !== undefined ? options.overwrite : false;892 893 if (storeName) {894 const original = this.original.slice(start, end);895 Object.defineProperty(this.storedNames, original, {896 writable: true,897 value: true,898 enumerable: true,899 });900 }901 902 const first = this.byStart[start];903 const last = this.byEnd[end];904 905 if (first) {906 let chunk = first;907 while (chunk !== last) {908 if (chunk.next !== this.byStart[chunk.end]) {909 throw new Error('Cannot overwrite across a split point');910 }911 chunk = chunk.next;912 chunk.edit('', false);913 }914 915 first.edit(content, storeName, !overwrite);916 } else {917 // must be inserting at the end918 const newChunk = new Chunk(start, end, '').edit(content, storeName);919 920 // TODO last chunk in the array may not be the last chunk, if it's moved...921 last.next = newChunk;922 newChunk.previous = last;923 }924 return this;925 }926 927 prepend(content) {928 if (typeof content !== 'string') throw new TypeError('outro content must be a string');929 930 this.intro = content + this.intro;931 return this;932 }933 934 prependLeft(index, content) {935 index = index + this.offset;936 937 if (typeof content !== 'string') throw new TypeError('inserted content must be a string');938 939 this._split(index);940 941 const chunk = this.byEnd[index];942 943 if (chunk) {944 chunk.prependLeft(content);945 } else {946 this.intro = content + this.intro;947 }948 return this;949 }950 951 prependRight(index, content) {952 index = index + this.offset;953 954 if (typeof content !== 'string') throw new TypeError('inserted content must be a string');955 956 this._split(index);957 958 const chunk = this.byStart[index];959 960 if (chunk) {961 chunk.prependRight(content);962 } else {963 this.outro = content + this.outro;964 }965 return this;966 }967 968 remove(start, end) {969 start = start + this.offset;970 end = end + this.offset;971 972 if (this.original.length !== 0) {973 while (start < 0) start += this.original.length;974 while (end < 0) end += this.original.length;975 }976 977 if (start === end) return this;978 979 if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');980 if (start > end) throw new Error('end must be greater than start');981 982 this._split(start);983 this._split(end);984 985 let chunk = this.byStart[start];986 987 while (chunk) {988 chunk.intro = '';989 chunk.outro = '';990 chunk.edit('');991 992 chunk = end > chunk.end ? this.byStart[chunk.end] : null;993 }994 return this;995 }996 997 reset(start, end) {998 start = start + this.offset;999 end = end + this.offset;1000 1001 if (this.original.length !== 0) {1002 while (start < 0) start += this.original.length;1003 while (end < 0) end += this.original.length;1004 }1005 1006 if (start === end) return this;1007 1008 if (start < 0 || end > this.original.length) throw new Error('Character is out of bounds');1009 if (start > end) throw new Error('end must be greater than start');1010 1011 this._split(start);1012 this._split(end);1013 1014 let chunk = this.byStart[start];1015 1016 while (chunk) {1017 chunk.reset();1018 1019 chunk = end > chunk.end ? this.byStart[chunk.end] : null;1020 }1021 return this;1022 }1023 1024 lastChar() {1025 if (this.outro.length) return this.outro[this.outro.length - 1];1026 let chunk = this.lastChunk;1027 do {1028 if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];1029 if (chunk.content.length) return chunk.content[chunk.content.length - 1];1030 if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];1031 } while ((chunk = chunk.previous));1032 if (this.intro.length) return this.intro[this.intro.length - 1];1033 return '';1034 }1035 1036 lastLine() {1037 let lineIndex = this.outro.lastIndexOf(n);1038 if (lineIndex !== -1) return this.outro.substr(lineIndex + 1);1039 let lineStr = this.outro;1040 let chunk = this.lastChunk;1041 do {1042 if (chunk.outro.length > 0) {1043 lineIndex = chunk.outro.lastIndexOf(n);1044 if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;1045 lineStr = chunk.outro + lineStr;1046 }1047 1048 if (chunk.content.length > 0) {1049 lineIndex = chunk.content.lastIndexOf(n);1050 if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr;1051 lineStr = chunk.content + lineStr;1052 }1053 1054 if (chunk.intro.length > 0) {1055 lineIndex = chunk.intro.lastIndexOf(n);1056 if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;1057 lineStr = chunk.intro + lineStr;1058 }1059 } while ((chunk = chunk.previous));1060 lineIndex = this.intro.lastIndexOf(n);1061 if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;1062 return this.intro + lineStr;1063 }1064 1065 slice(start = 0, end = this.original.length - this.offset) {1066 start = start + this.offset;1067 end = end + this.offset;1068 1069 if (this.original.length !== 0) {1070 while (start < 0) start += this.original.length;1071 while (end < 0) end += this.original.length;1072 }1073 1074 let result = '';1075 1076 // find start chunk1077 let chunk = this.firstChunk;1078 while (chunk && (chunk.start > start || chunk.end <= start)) {1079 // found end chunk before start1080 if (chunk.start < end && chunk.end >= end) {1081 return result;1082 }1083 1084 chunk = chunk.next;1085 }1086 1087 if (chunk && chunk.edited && chunk.start !== start)1088 throw new Error(`Cannot use replaced character ${start} as slice start anchor.`);1089 1090 const startChunk = chunk;1091 while (chunk) {1092 if (chunk.intro && (startChunk !== chunk || chunk.start === start)) {1093 result += chunk.intro;1094 }1095 1096 const containsEnd = chunk.start < end && chunk.end >= end;1097 if (containsEnd && chunk.edited && chunk.end !== end)1098 throw new Error(`Cannot use replaced character ${end} as slice end anchor.`);1099 1100 const sliceStart = startChunk === chunk ? start - chunk.start : 0;1101 const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;1102 1103 result += chunk.content.slice(sliceStart, sliceEnd);1104 1105 if (chunk.outro && (!containsEnd || chunk.end === end)) {1106 result += chunk.outro;1107 }1108 1109 if (containsEnd) {1110 break;1111 }1112 1113 chunk = chunk.next;1114 }1115 1116 return result;1117 }1118 1119 // TODO deprecate this? not really very useful1120 snip(start, end) {1121 const clone = this.clone();1122 clone.remove(0, start);1123 clone.remove(end, clone.original.length);1124 1125 return clone;1126 }1127 1128 _split(index) {1129 if (this.byStart[index] || this.byEnd[index]) return;1130 1131 let chunk = this.lastSearchedChunk;1132 let previousChunk = chunk;1133 const searchForward = index > chunk.end;1134 1135 while (chunk) {1136 if (chunk.contains(index)) return this._splitChunk(chunk, index);1137 1138 chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];1139 1140 // Prevent infinite loop (e.g. via empty chunks, where start === end)1141 if (chunk === previousChunk) return;1142 1143 previousChunk = chunk;1144 }1145 }1146 1147 _splitChunk(chunk, index) {1148 if (chunk.edited && chunk.content.length) {1149 // zero-length edited chunks are a special case (overlapping replacements)1150 const loc = getLocator(this.original)(index);1151 throw new Error(1152 `Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`,1153 );1154 }1155 1156 const newChunk = chunk.split(index);1157 1158 this.byEnd[index] = chunk;1159 this.byStart[index] = newChunk;1160 this.byEnd[newChunk.end] = newChunk;1161 1162 if (chunk === this.lastChunk) this.lastChunk = newChunk;1163 1164 this.lastSearchedChunk = chunk;1165 return true;1166 }1167 1168 toString() {1169 let str = this.intro;1170 1171 let chunk = this.firstChunk;1172 while (chunk) {1173 str += chunk.toString();1174 chunk = chunk.next;1175 }1176 1177 return str + this.outro;1178 }1179 1180 isEmpty() {1181 let chunk = this.firstChunk;1182 do {1183 if (1184 (chunk.intro.length && chunk.intro.trim()) ||1185 (chunk.content.length && chunk.content.trim()) ||1186 (chunk.outro.length && chunk.outro.trim())1187 )1188 return false;1189 } while ((chunk = chunk.next));1190 return true;1191 }1192 1193 length() {1194 let chunk = this.firstChunk;1195 let length = 0;1196 do {1197 length += chunk.intro.length + chunk.content.length + chunk.outro.length;1198 } while ((chunk = chunk.next));1199 return length;1200 }