App-SocialCalc-Multiplayer

 view release on metacpan or  search on metacpan

socialcalc/SocialCalcServersideUtilities.pm  view on Meta::CPAN

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
sub RenderSheet {
 
   my ($context, $options) = @_;
   my $sheet = $context->{sheet};
 
   CalculateCellSkipData($context, $options);
   PrecomputeSheetFontsAndLayouts($context, $options);
   CalculateColWidthData($context, $options);
 
   # Make a reasonable guess about the size of our rendered sheet, then
   # pre-extend that SV.  This is *critical* for mod_perl performance,
   # as malloc there is much slower there than the command line.
   my $outstr = ("\x00" x ($context->{maxrow} * $context->{maxcol} * 100));
   $outstr = '';
 
   $outstr .= RenderTableTag($context, $options); # start with table tag
 
   $outstr .= RenderColGroup($context, $options); # then colgroup section
 
   $outstr .= RenderSizingRow($context, $options); # add tiny row so all cols have something despite spans

socialcalc/formula1.js  view on Meta::CPAN

4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
   }
 
SocialCalc.Formula.FunctionList["SYD"] = [SocialCalc.Formula.SYDFunction, 4, "cslp", "", "financial"];
 
/*
#
# FV(rate, n, payment, [pv, [paytype]])
# NPER(rate, payment, pv, [fv, [paytype]])
# PMT(rate, n, pv, [fv, [paytype]])
# PV(rate, n, payment, [fv, [paytype]])
# RATE(n, payment, pv, [fv, [paytype, [guess]]])
#
# Following the Open Document Format formula specification:
#
#    PV = - Fv - (Payment * Nper) [if rate equals 0]
#    Pv*(1+Rate)^Nper + Payment * (1 + Rate*PaymentType) * ( (1+Rate)^nper -1)/Rate + Fv = 0
#
# For each function, the formulas are solved for the appropriate value (transformed using
# basic algebra).
#
*/
 
SocialCalc.Formula.InterestFunctions = function(fname, operand, foperand, sheet) {
 
   var resulttype, result, dval, eval, fval;
   var pv, fv, rate, n, payment, paytype, guess, part1, part2, part3, part4, part5;
   var olddelta, maxloop, tries, deltaepsilon, rate, oldrate, m;
 
   var scf = SocialCalc.Formula;
 
   var aval = scf.OperandAsNumber(sheet, foperand);
   var bval = scf.OperandAsNumber(sheet, foperand);
   var cval = scf.OperandAsNumber(sheet, foperand);
 
   resulttype = scf.LookupResultType(aval.type, bval.type, scf.TypeLookupTable.twoargnumeric);
   resulttype = scf.LookupResultType(resulttype, cval.type, scf.TypeLookupTable.twoargnumeric);

socialcalc/formula1.js  view on Meta::CPAN

4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
else if (rate == 0) { // simple calculation if no interest
   pv = -fv - (payment * n);
   }
else {
   pv = (-fv - payment * (1 + rate*paytype) * ( Math.pow(1+rate,n) -1)/rate)/(Math.pow(1+rate,n));
   }
result = pv;
resulttype = 'n$';
break;
 
case "RATE": // RATE(n, payment, pv, [fv, [paytype, [guess]]])
   n = aval.value;
   payment = bval.value;
   pv = cval.value;
   fv = dval!=null ? dval.value : 0;
   paytype = eval!=null ? (eval.value ? 1 : 0) : 0;
   guess = fval!=null ? fval.value : 0.1;
 
   // rate is calculated by repeated approximations
   // The deltas are used to calculate new guesses
 
   maxloop = 100;
   tries = 0;
   delta = 1;
   epsilon = 0.0000001; // this is close enough
   rate = guess || 0.00000001; // zero is not allowed
   while ((delta >= 0 ? delta : -delta) > epsilon && (rate != oldrate)) {
      delta = fv + pv*Math.pow(1+rate,n) + payment * (1 + rate*paytype) * ( Math.pow(1+rate,n) -1)/rate;
      if (olddelta!=null) {
         m = (delta - olddelta)/(rate - oldrate) || .001; // get slope (not zero)
         oldrate = rate;
         rate = rate - delta / m; // look for zero crossing
         olddelta = delta;
         }
      else { // first time - no old values
         oldrate = rate;

socialcalc/formula1.js  view on Meta::CPAN

4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
   scf.PushOperand(operand, resulttypenpv, sum);
 
   return;
 
   }
 
SocialCalc.Formula.FunctionList["NPV"] = [SocialCalc.Formula.NPVFunction, -2, "npv", "", "financial"];
 
/*
#
# IRR(c1:c2,[guess])
#
*/
 
SocialCalc.Formula.IRRFunction = function(fname, operand, foperand, sheet) {
 
   var value1, guess, oldsum, maxloop, tries, epsilon, rate, oldrate, m, sum, factor, i;
   var rangeoperand = [];
   var cashflows = [];
 
   var scf = SocialCalc.Formula;
 
   rangeoperand.push(foperand.pop()); // first operand is a range
 
   while (rangeoperand.length) { // get values from range so we can do iterative approximations
      value1 = scf.OperandValueAndType(sheet, rangeoperand);
      if (value1.type.charAt(0) == "n") {

socialcalc/formula1.js  view on Meta::CPAN

4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
      scf.PushOperand(operand, "e#VALUE!", 0);
      return;
      }
   }
 
if (!cashflows.length) {
   scf.PushOperand(operand, "e#NUM!", 0);
   return;
   }
 
guess = {value: 0};
 
if (foperand.length) { // guess is provided
   guess = scf.OperandAsNumber(sheet, foperand);
   if (guess.type.charAt(0) != "n" && guess.type.charAt(0) != "b") {
      scf.PushOperand(operand, "e#VALUE!", 0);
      return;
      }
   if (foperand.length) { // should be no more args
      scf.FunctionArgsError(fname, operand);
      return;
      }
   }
 
guess.value = guess.value || 0.1;
 
// rate is calculated by repeated approximations
// The deltas are used to calculate new guesses
 
maxloop = 20;
tries = 0;
epsilon = 0.0000001; // this is close enough
rate = guess.value;
sum = 1;
 
while ((sum >= 0 ? sum : -sum) > epsilon && (rate != oldrate)) {
   sum = 0;
   factor = 1;
   for (i=0; i<cashflows.length; i++) {
      factor *= (1 + rate);
      if (factor == 0) {
         scf.PushOperand(operand, "e#DIV/0!", 0);
         return;

socialcalc/socialcalc2demo-0-8-1.html  view on Meta::CPAN

631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
'range and return the corresponding value in the cell specified by the row offset. '+
'If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match&lt;=value) instead of exact match. '+
'<dt>HOUR(value)<dd>Returns the hour portion of a time or date/time value. '+
'<dt>IF(logical-expression, true-value, false-value)<dd>Results in true-value if logical-expression is TRUE or non-zero, '+
'otherwise results in false-value. '+
'<dt>INDEX(range, rownum, colnum)<dd>Returns a cell or range reference for the specified row and column in the range. '+
'If range is 1-dimensional, then only one of rownum or colnum are needed. '+
'If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. '+
'You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). '+
'<dt>INT(value)<dd>Returns the value rounded down to the nearest integer (towards -infinity). '+
'<dt>IRR(range, [guess])<dd>Returns the interest rate at which the cash flows in the range '+
'have a net present value of zero. Uses an iterative process that will return '+
'#NUM! error if it does not converge. '+
'There may be more than one possible solution. '+
'Providing the optional guess value may help in certain situations '+
'where it does not converge or finds an inappropriate solution (the default guess is 10%). '+
'<dt>ISBLANK(value)<dd>Returns "true" if the value is a reference to a blank cell. '+
'<dt>ISERR(value)<dd>Returns "true" if the value is of type "Error" but not "NA". '+
'<dt>ISERROR(value)<dd>Returns "true" if the value is of type "Error". '+
'<dt>ISLOGICAL(value)<dd>Returns "true" if the value is of type "Logical" (true/false). '+
'<dt>ISNA(value)<dd>Returns "true" if the value is the error type "NA". '+
'<dt>ISNONTEXT(value)<dd>Returns "true" if the value is not of type "Text". '+
'<dt>ISNUMBER(value)<dd>Returns "true" if the value is of type "Number" (including logical values). '+
'<dt>ISTEXT(value)<dd>Returns "true" if the value is of type "Text". '+
'<dt>LEFT(text, count)<dd>Returns the specified number of characters from the text value. '+
'If count is omitted, 1 is assumed. '+

socialcalc/socialcalc2demo-0-8-1.html  view on Meta::CPAN

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
'and payment type (default 0 = at end of period, 1 = beginning of period). '+
'<dt>POWER(value1, value2)<dd>Returns the first value raised to the second value power. '+
'<dt>PRODUCT(value1, value2, ...)<dd>Returns the result of multiplying the numeric values. '+
'<dt>PROPER(value)<dd>Returns the text value with the first letter of each word '+
'converted to uppercase and the others to lowercase. '+
'<dt>PV(rate, n, payment, [fv, [paytype]])<dd>Returns the present value of '+
'the given number of payments each invested at the given rate, '+
'with optional future value (default 0) '+
'and payment type (default 0 = at end of period, 1 = beginning of period). '+
'<dt>RADIANS(value)<dd>Converts value in degrees into radians. '+
'<dt>RATE(n, payment, pv, [fv, [paytype, [guess]]])<dd>Returns the rate at which '+
'the given number of payments each invested at the given rate has the '+
'specified present value, with optional future value (default 0) '+
'and payment type (default 0 = at end of period, 1 = beginning of period). '+
'Uses an iterative process that will return #NUM! error if it does not converge. '+
'There may be more than one possible solution. '+
'Providing the optional guess value may help in certain situations '+
'where it does not converge or finds an inappropriate solution (the default guess is 10%). '+
'<dt>REPLACE(text1, start, length, text2)<dd>Returns text1 with the specified number of characters '+
'starting from the specified position replaced by text2. '+
'<dt>REPT(text, count)<dd>Returns the text repeated the specified number of times. '+
'<dt>RIGHT(text, count)<dd>Returns the specified number of characters from the text value '+
'starting from the end. '+
'If count is omitted, 1 is assumed. '+
'<dt>ROUND(value, [precision])<dd>Rounds the value to the specified number of decimal places. '+
'If precision is negative, then round to powers of 10. '+
'The default precision is 0 (round to integer). '+
'<dt>ROWS(range)<dd>Returns the number of rows in the range. '+

socialcalc/socialcalc2demo10.html  view on Meta::CPAN

604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
'range and return the corresponding value in the cell specified by the row offset. '+
'If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match&lt;=value) instead of exact match. '+
'<dt>HOUR(value)<dd>Returns the hour portion of a time or date/time value. '+
'<dt>IF(logical-expression, true-value, false-value)<dd>Results in true-value if logical-expression is TRUE or non-zero, '+
'otherwise results in false-value. '+
'<dt>INDEX(range, rownum, colnum)<dd>Returns a cell or range reference for the specified row and column in the range. '+
'If range is 1-dimensional, then only one of rownum or colnum are needed. '+
'If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. '+
'You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). '+
'<dt>INT(value)<dd>Returns the value rounded down to the nearest integer (towards -infinity). '+
'<dt>IRR(range, [guess])<dd>Returns the interest rate at which the cash flows in the range '+
'have a net present value of zero. Uses an iterative process that will return '+
'#NUM! error if it does not converge. '+
'There may be more than one possible solution. '+
'Providing the optional guess value may help in certain situations '+
'where it does not converge or finds an inappropriate solution (the default guess is 10%). '+
'<dt>ISBLANK(value)<dd>Returns "true" if the value is a reference to a blank cell. '+
'<dt>ISERR(value)<dd>Returns "true" if the value is of type "Error" but not "NA". '+
'<dt>ISERROR(value)<dd>Returns "true" if the value is of type "Error". '+
'<dt>ISLOGICAL(value)<dd>Returns "true" if the value is of type "Logical" (true/false). '+
'<dt>ISNA(value)<dd>Returns "true" if the value is the error type "NA". '+
'<dt>ISNONTEXT(value)<dd>Returns "true" if the value is not of type "Text". '+
'<dt>ISNUMBER(value)<dd>Returns "true" if the value is of type "Number" (including logical values). '+
'<dt>ISTEXT(value)<dd>Returns "true" if the value is of type "Text". '+
'<dt>LEFT(text, count)<dd>Returns the specified number of characters from the text value. '+
'If count is omitted, 1 is assumed. '+

socialcalc/socialcalc2demo10.html  view on Meta::CPAN

664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
'and payment type (default 0 = at end of period, 1 = beginning of period). '+
'<dt>POWER(value1, value2)<dd>Returns the first value raised to the second value power. '+
'<dt>PRODUCT(value1, value2, ...)<dd>Returns the result of multiplying the numeric values. '+
'<dt>PROPER(value)<dd>Returns the text value with the first letter of each word '+
'converted to uppercase and the others to lowercase. '+
'<dt>PV(rate, n, payment, [fv, [paytype]])<dd>Returns the present value of '+
'the given number of payments each invested at the given rate, '+
'with optional future value (default 0) '+
'and payment type (default 0 = at end of period, 1 = beginning of period). '+
'<dt>RADIANS(value)<dd>Converts value in degrees into radians. '+
'<dt>RATE(n, payment, pv, [fv, [paytype, [guess]]])<dd>Returns the rate at which '+
'the given number of payments each invested at the given rate has the '+
'specified present value, with optional future value (default 0) '+
'and payment type (default 0 = at end of period, 1 = beginning of period). '+
'Uses an iterative process that will return #NUM! error if it does not converge. '+
'There may be more than one possible solution. '+
'Providing the optional guess value may help in certain situations '+
'where it does not converge or finds an inappropriate solution (the default guess is 10%). '+
'<dt>REPLACE(text1, start, length, text2)<dd>Returns text1 with the specified number of characters '+
'starting from the specified position replaced by text2. '+
'<dt>REPT(text, count)<dd>Returns the text repeated the specified number of times. '+
'<dt>RIGHT(text, count)<dd>Returns the specified number of characters from the text value '+
'starting from the end. '+
'If count is omitted, 1 is assumed. '+
'<dt>ROUND(value, [precision])<dd>Rounds the value to the specified number of decimal places. '+
'If precision is negative, then round to powers of 10. '+
'The default precision is 0 (round to integer). '+
'<dt>ROWS(range)<dd>Returns the number of rows in the range. '+

socialcalc/socialcalcconstants.js  view on Meta::CPAN

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
s_escUnknownSetCoordCmd: "Unknown set coord command: ",
s_escUnknownCmd: "Unknown command: ",
 
//*** SocialCalc.CheckAndCalcCell
 
s_caccCircRef: "Circular reference to ", // circular reference found during recalc
 
//*** SocialCalc.RenderContext
 
defaultRowNameWidth: "30", // used to set minimum width of the row header column - a string in pixels
defaultAssumedRowHeight: 15, // used when guessing row heights - number
defaultCellIDPrefix: "cell_", // if non-null, each cell will render with an ID starting with this
 
// Default sheet display values
 
defaultCellLayout: "padding:2px 2px 1px 2px;vertical-align:top;",
defaultCellFontStyle: "normal normal",
defaultCellFontSize: "small",
defaultCellFontFamily: "Verdana,Arial,Helvetica,sans-serif",
 
defaultPaneDividerWidth: "2", // a string

socialcalc/socialcalcconstants.js  view on Meta::CPAN

626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
s_fdef_EXP: 'Returns e raised to the value power. ',
s_fdef_FACT: 'Returns factorial of the value. ',
s_fdef_FALSE: 'Returns the logical value "false". ',
s_fdef_FIND: 'Returns the starting position within string2 of the first occurrence of string1 at or after "start". If start is omitted, 1 is assumed. ',
s_fdef_FV: 'Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). ',
s_fdef_HLOOKUP: 'Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) ...
s_fdef_HOUR: 'Returns the hour portion of a time or date/time value. ',
s_fdef_IF: 'Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. ',
s_fdef_INDEX: 'Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the ra...
s_fdef_INT: 'Returns the value rounded down to the nearest integer (towards -infinity). ',
s_fdef_IRR: 'Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing t...
s_fdef_ISBLANK: 'Returns "true" if the value is a reference to a blank cell. ',
s_fdef_ISERR: 'Returns "true" if the value is of type "Error" but not "NA". ',
s_fdef_ISERROR: 'Returns "true" if the value is of type "Error". ',
s_fdef_ISLOGICAL: 'Returns "true" if the value is of type "Logical" (true/false). ',
s_fdef_ISNA: 'Returns "true" if the value is the error type "NA". ',
s_fdef_ISNONTEXT: 'Returns "true" if the value is not of type "Text". ',
s_fdef_ISNUMBER: 'Returns "true" if the value is of type "Number" (including logical values). ',
s_fdef_ISTEXT: 'Returns "true" if the value is of type "Text". ',
s_fdef_LEFT: 'Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. ',
s_fdef_LEN: 'Returns the number of characters in the text value. ',

socialcalc/socialcalcconstants.js  view on Meta::CPAN

663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
s_fdef_NPV: 'Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. ',
s_fdef_ODD: 'Rounds the value up in magnitude to the nearest odd integer. ',
s_fdef_OR: 'True if any argument is true ',
s_fdef_PI: 'The value 3.1415926... ',
s_fdef_PMT: 'Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period,...
s_fdef_POWER: 'Returns the first value raised to the second value power. ',
s_fdef_PRODUCT: 'Returns the result of multiplying the numeric values. ',
s_fdef_PROPER: 'Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. ',
s_fdef_PV: 'Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). ',
s_fdef_RADIANS: 'Converts value in degrees into radians. ',
s_fdef_RATE: 'Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). ...
s_fdef_REPLACE: 'Returns text1 with the specified number of characters starting from the specified position replaced by text2. ',
s_fdef_REPT: 'Returns the text repeated the specified number of times. ',
s_fdef_RIGHT: 'Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. ',
s_fdef_ROUND: 'Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). ',
s_fdef_ROWS: 'Returns the number of rows in the range. ',
s_fdef_SECOND: 'Returns the second portion of a time or date/time value (truncated to an integer). ',
s_fdef_SIN: 'Trigonometric sine function (value is in radians) ',
s_fdef_SLN: 'Returns the amount of depreciation at each period of time using the straight-line method. ',
s_fdef_SQRT: 'Square root of the value ',
s_fdef_STDEV: 'Returns the sample standard deviation of the numeric values. ',

socialcalc/socialcalcconstants.js  view on Meta::CPAN

708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
s_farg_range: "range",
s_farg_rangec: "range, criteria",
s_farg_date: "year, month, day",
s_farg_dfunc: "databaserange, fieldname, criteriarange",
s_farg_ddb: "cost, salvage, lifetime, period [, factor]",
s_farg_find: "string1, string2 [, start]",
s_farg_fv: "rate, n, payment, [pv, [paytype]]",
s_farg_hlookup: "value, range, row, [rangelookup]",
s_farg_iffunc: "logical-expression, true-value, false-value",
s_farg_index: "range, rownum, colnum",
s_farg_irr: "range, [guess]",
s_farg_tc: "text, count",
s_farg_log: "value, base",
s_farg_match: "value, range, [rangelookup]",
s_farg_mid: "text, start, length",
s_farg_nper: "rate, payment, pv, [fv, [paytype]]",
s_farg_npv: "rate, value1, value2, ...",
s_farg_pmt: "rate, n, pv, [fv, [paytype]]",
s_farg_pv: "rate, n, payment, [fv, [paytype]]",
s_farg_rate: "n, payment, pv, [fv, [paytype, [guess]]]",
s_farg_replace: "text1, start, length, text2",
s_farg_vp: "value, [precision]",
s_farg_valpre: "value, precision",
s_farg_csl: "cost, salvage, lifetime",
s_farg_cslp: "cost, salvage, lifetime, period",
s_farg_subs: "text1, oldtext, newtext [, occurrence]",
s_farg_sumif: "range1, criteria [, range2]",
s_farg_hms: "hour, minute, second",
s_farg_txt: "text",
s_farg_vlookup: "value, range, col, [rangelookup]",

socialcalc/third-party/hippie/Stream.js  view on Meta::CPAN

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
        } else {
        //No
            //Grab from the start of the start flag to the end of the chunk
            this.currentStream += packet.substr(startFlag);
             
            //Leave this.currentStream set and wait for another packet
        }
    } else {
        //WTF? No open stream and no start flag means someone fucked up the output
        //...OR maybe they're sending garbage in front of their first payload. Weird.
        //I guess just ignore it for now?
    }
//Else we have an open stream
} else {
    //Is there an end flag?
    if(endFlag > -1) {
    //Yes
        //Use the end flag to grab the rest of the payload
        var chunk = packet.substring(0, endFlag);
        this.currentStream += chunk;
        



( run in 0.299 second using v1.01-cache-2.11-cpan-26ccb49234f )