// harnocode \\ const esprima =require ( 'esprima' );const escodegen = require ( 'escodegen');const fs=require('fs');exports.harnocode=function(code,mask,options){options= options||{ } ; const format = { safeConcatenation : true , escapeless : true,semicolons :true ,renumber: true, quotes:'single' };code =escodegen . generate(esprima .parse( code), { format:format} ); const tokens = tokenize ( code ) ; const lines = splitMaskToGroups ( mask);let tokenIndex =0;let groupIndex=0;let result=[]; let splitStrings= options. splitStrings === undefined ? false:options. splitStrings;let safe= options . safe === undefined ? true : options . safe ; function processMask ( ){ return lines.map(groups=> {let lineResult=[ ];let offset=0;if( tokenIndex >= tokens.length)return;groups.forEach((group,i ) => { let groupWidth = group [ 0 ]. length;let isBeforeNewline =i==groups .length-1; if(group . index < offset){groupWidth-=offset -group.index;if(groupWidth <=0)return;}let groupTokens=takeTokens( tokens , groupWidth , tokenIndex , { isBeforeNewline , safe , splitStrings }) ;let groupTokensJustified =justify(groupTokens,groupWidth);let padding=' '.repeat(Math.max(0,group.index-offset));offset +=padding. length + groupTokensJustified . length ; tokenIndex+= groupTokens. length ; lineResult . push(padding) ;lineResult.push(groupTokensJustified );});return lineResult. join('');});}do{ result = result. concat ( processMask()) ;} while(tokenIndex < tokens . length && options.repeat);let remainder = tokens . slice(tokenIndex) .join(''); result. push ( remainder ) ; let resultStr=result.join('\n' ) . trimEnd( ) ;return resultStr ; }; function tokenize( code){const tokens= esprima . tokenize( code);let result=[] ;const isPunct= token => token . type=='Punctuator' ;const isString=token=> token.type=='String';for(var i=0;i0 ) result. push( tokens. at (- 1) .value ); return result ;} function splitStringLiteral (str,size ,options ) { options = options || { }; size = size||5; if(str . length < size + 3 ) return[str] ;while(str.slice(size+1-5,size+1).includes('\\')&&size'];const isStringLiteral =s => s. startsWith ( '\'' ) && s . endsWith ( '\'' ) ; const isLongStringLiteral= s=>isStringLiteral(s )&&s .length >=10 ; while ( tokenIndex< tokens.length ){ let token=tokens [tokenIndex];let canTake = toTakeLength+token.length<= groupLength;if(toTakeLength==0)canTake= true;if( toTakeLength ==1&&toTake[0 ] == ' ' ) canTake=true ; let toTakeNext= canTake?1: 0 ; if ( options.isBeforeNewline&&!canTake){ if(specialTokens.includes(toTake.at(-1)) )toTakeNext=1;if( toTake.at (-1)==' ' && specialTokens . includes (toTake .at(-2) ) ) toTakeNext =1 ;if ( cantStartWith .includes ( tokens.at ( tokenIndex+0)))toTakeNext=1;if(cantStartWith.includes(tokens.at(tokenIndex+1)))toTakeNext= 2 ; if ( cantStartWith . includes ( tokens . at( tokenIndex+2)) )toTakeNext=3 ;}if (!toTakeNext &&options. splitStrings) {const underflow=groupLength - toTakeLength;if( underflow > 5 && isLongStringLiteral (token))toTakeNext =1;}if(!toTakeNext) break ; while ( toTakeNext){ toTake. push ( tokens [ tokenIndex]);toTakeLength+=tokens[ tokenIndex ] . length ; tokenIndex+=1;toTakeNext-=1; }}const lastToken=toTake.at(-1);const overflow = toTakeLength - groupLength ; if ( options . splitStrings && overflow > 5 && isStringLiteral ( lastToken ) && lastToken . length>5 ){let splitSize=lastToken. length- overflow - 1- 2; splitSize = Math.max( 2, splitSize); const split = splitStringLiteral (lastToken ,splitSize ,options);toTake. splice(-1,1,...split. slice(0,2));tokens .splice(tokenIndex-1,1,... split);} return toTake;} function justify (tokens ,width) { if ( tokens . length==0 )return' ' .repeat(width); let tokensWidth=tokens.reduce( (a,b)=>a+b .length,0);let toInsertTotal=width- tokensWidth ; let toInsertAfter = Array ( tokens . length- 1) . fill(0) ;let insertedActual =0;for(let i=0;itoken+' '. repeat(Math .max(0 , toInsertAfter[i]))) ;return result.join ('') ;}exports . formatFile = function ( path , mask,options){var program =fs.readFileSync(path). toString();var rest='';if(options .bryntum){options[ 'skip-validation' ]=true ;let index = program . indexOf(';' ) ; rest = program . slice ( index);program=program.slice(0,index);}let result=exports.harnocode(program,mask,options);if(! options [ ('skip-v' +'alidation' )])if (! validate ( program ,result ) ) process. exit(1); if ( options . bryntum ) { result=result+'\n'+rest;}process.stdout.write('// harnocode \\\\\n');process.stdout.write( result);};