1 /****************************************************************************
  2  Copyright (c) 2008-2010 Ricardo Quesada
  3  Copyright (c) 2011-2012 cocos2d-x.org
  4  Copyright (c) 2013-2014 Chukong Technologies Inc.
  5 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 
 27 /**
 28  * @constant
 29  * @type Number
 30  */
 31 cc.INVALID_INDEX = -1;
 32 
 33 /**
 34  * PI is the ratio of a circle's circumference to its diameter.
 35  * @constant
 36  * @type Number
 37  */
 38 cc.PI = Math.PI;
 39 
 40 /**
 41  * @constant
 42  * @type Number
 43  */
 44 cc.FLT_MAX = parseFloat('3.402823466e+38F');
 45 
 46 /**
 47  * @constant
 48  * @type Number
 49  */
 50 cc.FLT_MIN = parseFloat("1.175494351e-38F");
 51 
 52 /**
 53  * @constant
 54  * @type Number
 55  */
 56 cc.RAD = cc.PI / 180;
 57 
 58 /**
 59  * @constant
 60  * @type Number
 61  */
 62 cc.DEG = 180 / cc.PI;
 63 
 64 /**
 65  * maximum unsigned int value
 66  * @constant
 67  * @type Number
 68  */
 69 cc.UINT_MAX = 0xffffffff;
 70 
 71 /**
 72  * <p>
 73  * simple macro that swaps 2 variables<br/>
 74  *  modified from c++ macro, you need to pass in the x and y variables names in string, <br/>
 75  *  and then a reference to the whole object as third variable
 76  * </p>
 77  * @param {String} x
 78  * @param {String} y
 79  * @param {Object} ref
 80  * @function
 81  * @deprecated since v3.0
 82  */
 83 cc.swap = function (x, y, ref) {
 84     if (cc.isObject(ref) && !cc.isUndefined(ref.x) && !cc.isUndefined(ref.y)) {
 85         var tmp = ref[x];
 86         ref[x] = ref[y];
 87         ref[y] = tmp;
 88     } else
 89         cc.log(cc._LogInfos.swap);
 90 };
 91 
 92 /**
 93  * <p>
 94  *     Linear interpolation between 2 numbers, the ratio sets how much it is biased to each end
 95  * </p>
 96  * @param {Number} a number A
 97  * @param {Number} b number B
 98  * @param {Number} r ratio between 0 and 1
 99  * @function
100  * @example
101  * cc.lerp(2,10,0.5)//returns 6<br/>
102  * cc.lerp(2,10,0.2)//returns 3.6
103  */
104 cc.lerp = function (a, b, r) {
105     return a + (b - a) * r;
106 };
107 
108 /**
109  * get a random number from 0 to 0xffffff
110  * @function
111  * @returns {number}
112  */
113 cc.rand = function () {
114 	return Math.random() * 0xffffff;
115 };
116 
117 /**
118  * returns a random float between -1 and 1
119  * @return {Number}
120  * @function
121  */
122 cc.randomMinus1To1 = function () {
123     return (Math.random() - 0.5) * 2;
124 };
125 
126 /**
127  * returns a random float between 0 and 1
128  * @return {Number}
129  * @function
130  */
131 cc.random0To1 = Math.random;
132 
133 /**
134  * converts degrees to radians
135  * @param {Number} angle
136  * @return {Number}
137  * @function
138  */
139 cc.degreesToRadians = function (angle) {
140     return angle * cc.RAD;
141 };
142 
143 /**
144  * converts radians to degrees
145  * @param {Number} angle
146  * @return {Number}
147  * @function
148  */
149 cc.radiansToDegrees = function (angle) {
150     return angle * cc.DEG;
151 };
152 /**
153  * converts radians to degrees
154  * @param {Number} angle
155  * @return {Number}
156  * @function
157  */
158 cc.radiansToDegress = function (angle) {
159     cc.log(cc._LogInfos.radiansToDegress);
160     return angle * cc.DEG;
161 };
162 
163 /**
164  * @constant
165  * @type Number
166  */
167 cc.REPEAT_FOREVER = Number.MAX_VALUE - 1;
168 
169 /**
170  * Helpful macro that setups the GL server state, the correct GL program and sets the Model View Projection matrix
171  * @param {cc.Node} node setup node
172  * @function
173  */
174 cc.nodeDrawSetup = function (node) {
175     //cc.glEnable(node._glServerState);
176     if (node._shaderProgram) {
177         //cc._renderContext.useProgram(node._shaderProgram._programObj);
178         node._shaderProgram.use();
179         node._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4();
180     }
181 };
182 
183 /**
184  * <p>
185  *     GL states that are enabled:<br/>
186  *       - GL_TEXTURE_2D<br/>
187  *       - GL_VERTEX_ARRAY<br/>
188  *       - GL_TEXTURE_COORD_ARRAY<br/>
189  *       - GL_COLOR_ARRAY<br/>
190  * </p>
191  * @function
192  */
193 cc.enableDefaultGLStates = function () {
194     //TODO OPENGL STUFF
195     /*
196      glEnableClientState(GL_VERTEX_ARRAY);
197      glEnableClientState(GL_COLOR_ARRAY);
198      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
199      glEnable(GL_TEXTURE_2D);*/
200 };
201 
202 /**
203  * <p>
204  *   Disable default GL states:<br/>
205  *     - GL_TEXTURE_2D<br/>
206  *     - GL_TEXTURE_COORD_ARRAY<br/>
207  *     - GL_COLOR_ARRAY<br/>
208  * </p>
209  * @function
210  */
211 cc.disableDefaultGLStates = function () {
212     //TODO OPENGL
213     /*
214      glDisable(GL_TEXTURE_2D);
215      glDisableClientState(GL_COLOR_ARRAY);
216      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
217      glDisableClientState(GL_VERTEX_ARRAY);
218      */
219 };
220 
221 /**
222  * <p>
223  *  Increments the GL Draws counts by one.<br/>
224  *  The number of calls per frame are displayed on the screen when the CCDirector's stats are enabled.<br/>
225  * </p>
226  * @param {Number} addNumber
227  * @function
228  */
229 cc.incrementGLDraws = function (addNumber) {
230     cc.g_NumberOfDraws += addNumber;
231 };
232 
233 /**
234  * @constant
235  * @type Number
236  */
237 cc.FLT_EPSILON = 0.0000001192092896;
238 
239 /**
240  * <p>
241  *     On Mac it returns 1;<br/>
242  *     On iPhone it returns 2 if RetinaDisplay is On. Otherwise it returns 1
243  * </p>
244  * @return {Number}
245  * @function
246  */
247 cc.contentScaleFactor = cc.IS_RETINA_DISPLAY_SUPPORTED ? function () {
248     return cc.director.getContentScaleFactor();
249 } : function () {
250     return 1;
251 };
252 
253 /**
254  * Converts a Point in points to pixels
255  * @param {cc.Point} points
256  * @return {cc.Point}
257  * @function
258  */
259 cc.pointPointsToPixels = function (points) {
260     var scale = cc.contentScaleFactor();
261     return cc.p(points.x * scale, points.y * scale);
262 };
263 
264 /**
265  * Converts a Point in pixels to points
266  * @param {cc.Rect} pixels
267  * @return {cc.Point}
268  * @function
269  */
270 cc.pointPixelsToPoints = function (pixels) {
271 	var scale = cc.contentScaleFactor();
272 	return cc.p(pixels.x / scale, pixels.y / scale);
273 };
274 
275 cc._pointPixelsToPointsOut = function(pixels, outPoint){
276 	var scale = cc.contentScaleFactor();
277 	outPoint.x = pixels.x / scale;
278 	outPoint.y = pixels.y / scale;
279 };
280 
281 /**
282  * Converts a Size in points to pixels
283  * @param {cc.Size} sizeInPoints
284  * @return {cc.Size}
285  * @function
286  */
287 cc.sizePointsToPixels = function (sizeInPoints) {
288     var scale = cc.contentScaleFactor();
289     return cc.size(sizeInPoints.width * scale, sizeInPoints.height * scale);
290 };
291 
292 /**
293  * Converts a size in pixels to points
294  * @param {cc.Size} sizeInPixels
295  * @return {cc.Size}
296  * @function
297  */
298 cc.sizePixelsToPoints = function (sizeInPixels) {
299     var scale = cc.contentScaleFactor();
300     return cc.size(sizeInPixels.width / scale, sizeInPixels.height / scale);
301 };
302 
303 cc._sizePixelsToPointsOut = function (sizeInPixels, outSize) {
304     var scale = cc.contentScaleFactor();
305     outSize.width = sizeInPixels.width / scale;
306     outSize.height = sizeInPixels.height / scale;
307 };
308 
309 /**
310  * Converts a rect in pixels to points
311  * @param {cc.Rect} pixel
312  * @return {cc.Rect}
313  * @function
314  */
315 cc.rectPixelsToPoints = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (pixel) {
316     var scale = cc.contentScaleFactor();
317     return cc.rect(pixel.x / scale, pixel.y / scale,
318         pixel.width / scale, pixel.height / scale);
319 } : function (p) {
320     return p;
321 };
322 
323 /**
324  * Converts a rect in points to pixels
325  * @param {cc.Rect} point
326  * @return {cc.Rect}
327  * @function
328  */
329 cc.rectPointsToPixels = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (point) {
330    var scale = cc.contentScaleFactor();
331     return cc.rect(point.x * scale, point.y * scale,
332         point.width * scale, point.height * scale);
333 } : function (p) {
334     return p;
335 };
336 
337 //some gl constant variable
338 /**
339  * @constant
340  * @type Number
341  */
342 cc.ONE = 1;
343 
344 /**
345  * @constant
346  * @type Number
347  */
348 cc.ZERO = 0;
349 
350 /**
351  * @constant
352  * @type Number
353  */
354 cc.SRC_ALPHA = 0x0302;
355 
356 /**
357  * @constant
358  * @type Number
359  */
360 cc.SRC_ALPHA_SATURATE = 0x308;
361 
362 /**
363  * @constant
364  * @type Number
365  */
366 cc.SRC_COLOR = 0x300;
367 
368 /**
369  * @constant
370  * @type Number
371  */
372 cc.DST_ALPHA = 0x304;
373 
374 /**
375  * @constant
376  * @type Number
377  */
378 cc.DST_COLOR = 0x306;
379 
380 /**
381  * @constant
382  * @type Number
383  */
384 cc.ONE_MINUS_SRC_ALPHA = 0x0303;
385 
386 /**
387  * @constant
388  * @type Number
389  */
390 cc.ONE_MINUS_SRC_COLOR = 0x301;
391 
392 /**
393  * @constant
394  * @type Number
395  */
396 cc.ONE_MINUS_DST_ALPHA = 0x305;
397 
398 /**
399  * @constant
400  * @type Number
401  */
402 cc.ONE_MINUS_DST_COLOR = 0x0307;
403 
404 /**
405  * @constant
406  * @type Number
407  */
408 cc.ONE_MINUS_CONSTANT_ALPHA	= 0x8004;
409 
410 /**
411  * @constant
412  * @type Number
413  */
414 cc.ONE_MINUS_CONSTANT_COLOR	= 0x8002;
415 
416 /**
417  * the constant variable equals gl.LINEAR for texture
418  * @constant
419  * @type Number
420  */
421 cc.LINEAR	= 0x2601;
422 
423 /**
424  * the constant variable equals gl.REPEAT for texture
425  * @constant
426  * @type Number
427  */
428 cc.REPEAT	= 0x2901;
429 
430 /**
431  * the constant variable equals gl.CLAMP_TO_EDGE for texture
432  * @constant
433  * @type Number
434  */
435 cc.CLAMP_TO_EDGE	= 0x812f;
436 
437 /**
438  * the constant variable equals gl.MIRRORED_REPEAT for texture
439  * @constant
440  * @type Number
441  */
442 cc.MIRRORED_REPEAT   = 0x8370;
443 
444 /**
445  * default gl blend src function. Compatible with premultiplied alpha images.
446  * @constant
447  * @name cc.BLEND_SRC
448  * @type Number
449  */
450 cc.BLEND_SRC = cc.SRC_ALPHA;
451 cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
452     if (cc._renderType === cc.game.RENDER_TYPE_WEBGL
453          && cc.OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA) {
454         cc.BLEND_SRC = cc.ONE;
455     }
456 });
457 
458 /**
459  * default gl blend dst function. Compatible with premultiplied alpha images.
460  * @constant
461  * @type Number
462  */
463 cc.BLEND_DST = cc.ONE_MINUS_SRC_ALPHA;
464 
465 /**
466  * Check webgl error.Error will be shown in console if exists.
467  * @function
468  */
469 cc.checkGLErrorDebug = function () {
470     if (cc.renderMode === cc.game.RENDER_TYPE_WEBGL) {
471         var _error = cc._renderContext.getError();
472         if (_error) {
473             cc.log(cc._LogInfos.checkGLErrorDebug, _error);
474         }
475     }
476 };
477 
478 //Possible device orientations
479 /**
480  * Device oriented vertically, home button on the bottom (UIDeviceOrientationPortrait)
481  * @constant
482  * @type Number
483  */
484 cc.ORIENTATION_PORTRAIT = 1;
485 
486 /**
487  * Device oriented horizontally, home button on the right (UIDeviceOrientationLandscapeLeft)
488  * @constant
489  * @type Number
490  */
491 cc.ORIENTATION_LANDSCAPE = 2;
492 
493 /**
494  * Device oriented vertically, home button on the top (UIDeviceOrientationPortraitUpsideDown)
495  * @constant
496  * @type Number
497  */
498 cc.ORIENTATION_AUTO = 3;
499 
500 
501 // ------------------- vertex attrib flags -----------------------------
502 /**
503  * @constant
504  * @type {Number}
505  */
506 cc.VERTEX_ATTRIB_FLAG_NONE = 0;
507 /**
508  * @constant
509  * @type {Number}
510  */
511 cc.VERTEX_ATTRIB_FLAG_POSITION = 1 << 0;
512 /**
513  * @constant
514  * @type {Number}
515  */
516 cc.VERTEX_ATTRIB_FLAG_COLOR = 1 << 1;
517 /**
518  * @constant
519  * @type {Number}
520  */
521 cc.VERTEX_ATTRIB_FLAG_TEX_COORDS = 1 << 2;
522 /**
523  * @constant
524  * @type {Number}
525  */
526 cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX = ( cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS );
527 
528 /**
529  * GL server side states
530  * @constant
531  * @type {Number}
532  */
533 cc.GL_ALL = 0;
534 
535 //-------------Vertex Attributes-----------
536 /**
537  * @constant
538  * @type {Number}
539  */
540 cc.VERTEX_ATTRIB_POSITION = 0;
541 /**
542  * @constant
543  * @type {Number}
544  */
545 cc.VERTEX_ATTRIB_COLOR = 1;
546 /**
547  * @constant
548  * @type {Number}
549  */
550 cc.VERTEX_ATTRIB_TEX_COORDS = 2;
551 /**
552  * @constant
553  * @type {Number}
554  */
555 cc.VERTEX_ATTRIB_MAX = 7;
556 
557 //------------Uniforms------------------
558 /**
559  * @constant
560  * @type {Number}
561  */
562 cc.UNIFORM_PMATRIX = 0;
563 /**
564  * @constant
565  * @type {Number}
566  */
567 cc.UNIFORM_MVMATRIX = 1;
568 /**
569  * @constant
570  * @type {Number}
571  */
572 cc.UNIFORM_MVPMATRIX = 2;
573 /**
574  * @constant
575  * @type {Number}
576  */
577 cc.UNIFORM_TIME = 3;
578 /**
579  * @constant
580  * @type {Number}
581  */
582 cc.UNIFORM_SINTIME = 4;
583 /**
584  * @constant
585  * @type {Number}
586  */
587 cc.UNIFORM_COSTIME = 5;
588 /**
589  * @constant
590  * @type {Number}
591  */
592 cc.UNIFORM_RANDOM01 = 6;
593 /**
594  * @constant
595  * @type {Number}
596  */
597 cc.UNIFORM_SAMPLER = 7;
598 /**
599  * @constant
600  * @type {Number}
601  */
602 cc.UNIFORM_MAX = 8;
603 
604 //------------Shader Name---------------
605 /**
606  * @constant
607  * @type {String}
608  */
609 cc.SHADER_POSITION_TEXTURECOLOR = "ShaderPositionTextureColor";
610 /**
611  * @constant
612  * @type {String}
613  */
614 cc.SHADER_SPRITE_POSITION_TEXTURECOLOR = "ShaderSpritePositionTextureColor";
615 /**
616  * @constant
617  * @type {String}
618  */
619 cc.SHADER_POSITION_TEXTURECOLORALPHATEST = "ShaderPositionTextureColorAlphaTest";
620 /**
621  * @constant
622  * @type {String}
623  */
624 cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST = "ShaderSpritePositionTextureColorAlphaTest";
625 /**
626  * @constant
627  * @type {String}
628  */
629 cc.SHADER_POSITION_COLOR = "ShaderPositionColor";
630 /**
631  * @constant
632  * @type {String}
633  */
634 cc.SHADER_SPRITE_POSITION_COLOR = "ShaderSpritePositionColor";
635 /**
636  * @constant
637  * @type {String}
638  */
639 cc.SHADER_POSITION_TEXTURE = "ShaderPositionTexture";
640 /**
641  * @constant
642  * @type {String}
643  */
644 cc.SHADER_POSITION_TEXTURE_UCOLOR = "ShaderPositionTexture_uColor";
645 /**
646  * @constant
647  * @type {String}
648  */
649 cc.SHADER_POSITION_TEXTUREA8COLOR = "ShaderPositionTextureA8Color";
650 /**
651  * @constant
652  * @type {String}
653  */
654 cc.SHADER_POSITION_UCOLOR = "ShaderPosition_uColor";
655 /**
656  * @constant
657  * @type {String}
658  */
659 cc.SHADER_POSITION_LENGTHTEXTURECOLOR = "ShaderPositionLengthTextureColor";
660 
661 //------------uniform names----------------
662 /**
663  * @constant
664  * @type {String}
665  */
666 cc.UNIFORM_PMATRIX_S = "CC_PMatrix";
667 /**
668  * @constant
669  * @type {String}
670  */
671 cc.UNIFORM_MVMATRIX_S = "CC_MVMatrix";
672 /**
673  * @constant
674  * @type {String}
675  */
676 cc.UNIFORM_MVPMATRIX_S = "CC_MVPMatrix";
677 /**
678  * @constant
679  * @type {String}
680  */
681 cc.UNIFORM_TIME_S = "CC_Time";
682 /**
683  * @constant
684  * @type {String}
685  */
686 cc.UNIFORM_SINTIME_S = "CC_SinTime";
687 /**
688  * @constant
689  * @type {String}
690  */
691 cc.UNIFORM_COSTIME_S = "CC_CosTime";
692 /**
693  * @constant
694  * @type {String}
695  */
696 cc.UNIFORM_RANDOM01_S = "CC_Random01";
697 /**
698  * @constant
699  * @type {String}
700  */
701 cc.UNIFORM_SAMPLER_S = "CC_Texture0";
702 /**
703  * @constant
704  * @type {String}
705  */
706 cc.UNIFORM_ALPHA_TEST_VALUE_S = "CC_alpha_value";
707 
708 //------------Attribute names--------------
709 /**
710  * @constant
711  * @type {String}
712  */
713 cc.ATTRIBUTE_NAME_COLOR = "a_color";
714 /**
715  * @constant
716  * @type {String}
717  */
718 cc.ATTRIBUTE_NAME_POSITION = "a_position";
719 /**
720  * @constant
721  * @type {String}
722  */
723 cc.ATTRIBUTE_NAME_TEX_COORD = "a_texCoord";
724 /**
725  * @constant
726  * @type {String}
727  */
728 cc.ATTRIBUTE_NAME_MVMAT = "a_mvMatrix";
729 
730 
731 /**
732  * default size for font size
733  * @constant
734  * @type Number
735  */
736 cc.ITEM_SIZE = 32;
737 
738 /**
739  * default tag for current item
740  * @constant
741  * @type Number
742  */
743 cc.CURRENT_ITEM = 0xc0c05001;
744 /**
745  * default tag for zoom action tag
746  * @constant
747  * @type Number
748  */
749 cc.ZOOM_ACTION_TAG = 0xc0c05002;
750 /**
751  * default tag for normal
752  * @constant
753  * @type Number
754  */
755 cc.NORMAL_TAG = 8801;
756 
757 /**
758  * default selected tag
759  * @constant
760  * @type Number
761  */
762 cc.SELECTED_TAG = 8802;
763 
764 /**
765  * default disabled tag
766  * @constant
767  * @type Number
768  */
769 cc.DISABLE_TAG = 8803;
770 
771 
772 // Array utils
773 
774 /**
775  * Verify Array's Type
776  * @param {Array} arr
777  * @param {function} type
778  * @return {Boolean}
779  * @function
780  */
781 cc.arrayVerifyType = function (arr, type) {
782     if (arr && arr.length > 0) {
783         for (var i = 0; i < arr.length; i++) {
784             if (!(arr[i] instanceof  type)) {
785                 cc.log("element type is wrong!");
786                 return false;
787             }
788         }
789     }
790     return true;
791 };
792 
793 /**
794  * Searches for the first occurrence of object and removes it. If object is not found the function has no effect.
795  * @function
796  * @param {Array} arr Source Array
797  * @param {*} delObj  remove object
798  */
799 cc.arrayRemoveObject = function (arr, delObj) {
800     for (var i = 0, l = arr.length; i < l; i++) {
801         if (arr[i] === delObj) {
802             arr.splice(i, 1);
803             break;
804         }
805     }
806 };
807 
808 /**
809  * Removes from arr all values in minusArr. For each Value in minusArr, the first matching instance in arr will be removed.
810  * @function
811  * @param {Array} arr Source Array
812  * @param {Array} minusArr minus Array
813  */
814 cc.arrayRemoveArray = function (arr, minusArr) {
815     for (var i = 0, l = minusArr.length; i < l; i++) {
816         cc.arrayRemoveObject(arr, minusArr[i]);
817     }
818 };
819 
820 /**
821  * Inserts some objects at index
822  * @function
823  * @param {Array} arr
824  * @param {Array} addObjs
825  * @param {Number} index
826  * @return {Array}
827  */
828 cc.arrayAppendObjectsToIndex = function(arr, addObjs,index){
829     arr.splice.apply(arr, [index, 0].concat(addObjs));
830     return arr;
831 };
832 
833 /**
834  * Copy an array's item to a new array (its performance is better than Array.slice)
835  * @param {Array} arr
836  * @return {Array}
837  */
838 cc.copyArray = function(arr){
839     var i, len = arr.length, arr_clone = new Array(len);
840     for (i = 0; i < len; i += 1)
841         arr_clone[i] = arr[i];
842     return arr_clone;
843 };
844