@@ -26,24 +26,24 @@ export function jsonToCsv(jsonString: string): string {
2626 if ( ! Array . isArray ( data ) ) {
2727 throw new Error ( 'JSON must be an array of objects' ) ;
2828 }
29-
29+
3030 if ( data . length === 0 ) {
3131 return '' ;
3232 }
33-
33+
3434 const headers = Object . keys ( data [ 0 ] ) ;
3535 const csvRows = [ headers . join ( ',' ) ] ;
36-
36+
3737 for ( const row of data ) {
3838 const values = headers . map ( header => {
3939 const value = row [ header ] ;
40- return typeof value === 'string' && ( value . includes ( ',' ) || value . includes ( '"' ) )
41- ? `"${ value . replace ( / " / g, '""' ) } "`
40+ return typeof value === 'string' && ( value . includes ( ',' ) || value . includes ( '"' ) )
41+ ? `"${ value . replace ( / " / g, '""' ) } "`
4242 : value ;
4343 } ) ;
4444 csvRows . push ( values . join ( ',' ) ) ;
4545 }
46-
46+
4747 return csvRows . join ( '\n' ) ;
4848 } catch ( error ) {
4949 throw new Error ( `JSON to CSV conversion error: ${ error instanceof Error ? error . message : 'Unknown error' } ` ) ;
@@ -56,21 +56,21 @@ export function csvToJson(csvString: string): string {
5656 if ( lines . length < 2 ) {
5757 throw new Error ( 'CSV must have at least a header row and one data row' ) ;
5858 }
59-
59+
6060 const headers = lines [ 0 ] . split ( ',' ) . map ( h => h . trim ( ) ) ;
6161 const result = [ ] ;
62-
62+
6363 for ( let i = 1 ; i < lines . length ; i ++ ) {
6464 const values = lines [ i ] . split ( ',' ) . map ( v => v . trim ( ) ) ;
6565 const obj : any = { } ;
66-
66+
6767 headers . forEach ( ( header , index ) => {
6868 obj [ header ] = values [ index ] || '' ;
6969 } ) ;
70-
70+
7171 result . push ( obj ) ;
7272 }
73-
73+
7474 return JSON . stringify ( result , null , 2 ) ;
7575 } catch ( error ) {
7676 throw new Error ( `CSV to JSON conversion error: ${ error instanceof Error ? error . message : 'Unknown error' } ` ) ;
@@ -98,25 +98,25 @@ export function rgbToHsl(r: number, g: number, b: number): { h: number; s: numbe
9898 r /= 255 ;
9999 g /= 255 ;
100100 b /= 255 ;
101-
101+
102102 const max = Math . max ( r , g , b ) ;
103103 const min = Math . min ( r , g , b ) ;
104104 let h = 0 ;
105105 let s = 0 ;
106106 const l = ( max + min ) / 2 ;
107-
107+
108108 if ( max !== min ) {
109109 const d = max - min ;
110110 s = l > 0.5 ? d / ( 2 - max - min ) : d / ( max + min ) ;
111-
111+
112112 switch ( max ) {
113113 case r : h = ( g - b ) / d + ( g < b ? 6 : 0 ) ; break ;
114114 case g : h = ( b - r ) / d + 2 ; break ;
115115 case b : h = ( r - g ) / d + 4 ; break ;
116116 }
117117 h /= 6 ;
118118 }
119-
119+
120120 return {
121121 h : Math . round ( h * 360 ) ,
122122 s : Math . round ( s * 100 ) ,
@@ -128,7 +128,7 @@ export function hslToRgb(h: number, s: number, l: number): { r: number; g: numbe
128128 h /= 360 ;
129129 s /= 100 ;
130130 l /= 100 ;
131-
131+
132132 const hue2rgb = ( p : number , q : number , t : number ) => {
133133 if ( t < 0 ) t += 1 ;
134134 if ( t > 1 ) t -= 1 ;
@@ -137,9 +137,9 @@ export function hslToRgb(h: number, s: number, l: number): { r: number; g: numbe
137137 if ( t < 2 / 3 ) return p + ( q - p ) * ( 2 / 3 - t ) * 6 ;
138138 return p ;
139139 } ;
140-
140+
141141 let r , g , b ;
142-
142+
143143 if ( s === 0 ) {
144144 r = g = b = l ;
145145 } else {
@@ -149,7 +149,7 @@ export function hslToRgb(h: number, s: number, l: number): { r: number; g: numbe
149149 g = hue2rgb ( p , q , h ) ;
150150 b = hue2rgb ( p , q , h - 1 / 3 ) ;
151151 }
152-
152+
153153 return {
154154 r : Math . round ( r * 255 ) ,
155155 g : Math . round ( g * 255 ) ,
@@ -169,9 +169,9 @@ export function generateLoremIpsum(paragraphs: number, wordsPerParagraph: number
169169 'occaecat' , 'cupidatat' , 'non' , 'proident' , 'sunt' , 'culpa' , 'qui' , 'officia' ,
170170 'deserunt' , 'mollit' , 'anim' , 'id' , 'est' , 'laborum'
171171 ] ;
172-
172+
173173 const result = [ ] ;
174-
174+
175175 for ( let p = 0 ; p < paragraphs ; p ++ ) {
176176 const paragraph = [ ] ;
177177 for ( let w = 0 ; w < wordsPerParagraph ; w ++ ) {
@@ -180,7 +180,7 @@ export function generateLoremIpsum(paragraphs: number, wordsPerParagraph: number
180180 }
181181 result . push ( paragraph . join ( ' ' ) + '.' ) ;
182182 }
183-
183+
184184 return result . join ( '\n\n' ) ;
185185}
186186
@@ -190,24 +190,26 @@ export function analyzeString(text: string) {
190190 const words = text . trim ( ) . split ( / \s + / ) . filter ( w => w . length > 0 ) ;
191191 const characters = text . length ;
192192 const charactersNoSpaces = text . replace ( / \s / g, '' ) . length ;
193- const paragraphs = text . split ( / \n \s * \n / ) . filter ( p => p . trim ( ) . length > 0 ) . length ;
194-
193+
194+ // Calculate byte size (UTF-8 encoding)
195+ const byteSize = new TextEncoder ( ) . encode ( text ) . length ;
196+
195197 // Character frequency
196198 const charFreq : { [ key : string ] : number } = { } ;
197199 for ( const char of text ) {
198200 charFreq [ char ] = ( charFreq [ char ] || 0 ) + 1 ;
199201 }
200-
202+
201203 return {
202204 characters,
203205 charactersNoSpaces,
204206 words : words . length ,
205207 lines : lines . length ,
206- paragraphs,
207208 sentences : text . split ( / [ . ! ? ] + / ) . filter ( s => s . trim ( ) . length > 0 ) . length ,
208209 averageWordsPerSentence : words . length / text . split ( / [ . ! ? ] + / ) . filter ( s => s . trim ( ) . length > 0 ) . length || 0 ,
209210 mostFrequentChar : Object . entries ( charFreq ) . sort ( ( [ , a ] , [ , b ] ) => b - a ) [ 0 ] ?. [ 0 ] || '' ,
210- charFrequency : charFreq
211+ charFrequency : charFreq ,
212+ byteSize
211213 } ;
212214}
213215
@@ -252,13 +254,13 @@ export function htmlToJsx(html: string): string {
252254// Cron expression parser
253255export function parseCronExpression ( expression : string ) : string {
254256 const parts = expression . trim ( ) . split ( / \s + / ) ;
255-
257+
256258 if ( parts . length !== 5 && parts . length !== 6 ) {
257259 throw new Error ( 'Invalid cron expression. Expected 5 or 6 parts.' ) ;
258260 }
259-
261+
260262 const [ minute , hour , dayOfMonth , month , dayOfWeek , year ] = parts ;
261-
263+
262264 const parseField = ( value : string , fieldName : string , min : number , max : number ) : string => {
263265 if ( value === '*' ) return `any ${ fieldName } ` ;
264266 if ( value . includes ( '/' ) ) {
@@ -274,19 +276,19 @@ export function parseCronExpression(expression: string): string {
274276 }
275277 return `${ fieldName } ${ value } ` ;
276278 } ;
277-
279+
278280 const minuteDesc = parseField ( minute , 'minute' , 0 , 59 ) ;
279281 const hourDesc = parseField ( hour , 'hour' , 0 , 23 ) ;
280282 const dayOfMonthDesc = parseField ( dayOfMonth , 'day of month' , 1 , 31 ) ;
281283 const monthDesc = parseField ( month , 'month' , 1 , 12 ) ;
282284 const dayOfWeekDesc = parseField ( dayOfWeek , 'day of week' , 0 , 6 ) ;
283-
285+
284286 let description = `At ${ minuteDesc } of ${ hourDesc } , on ${ dayOfMonthDesc } of ${ monthDesc } , and on ${ dayOfWeekDesc } ` ;
285-
287+
286288 if ( year ) {
287289 const yearDesc = parseField ( year , 'year' , 1970 , 3000 ) ;
288290 description += `, in ${ yearDesc } ` ;
289291 }
290-
292+
291293 return description ;
292294}
0 commit comments