|
@@ -33,148 +33,319 @@ THREE.MD2Loader.prototype = {
|
|
|
|
|
|
},
|
|
},
|
|
|
|
|
|
- parse: function ( buffer ) {
|
|
|
|
|
|
+ parse: ( function () {
|
|
|
|
+
|
|
|
|
+ var normals = [
|
|
|
|
+ [ -0.525731, 0.000000, 0.850651 ],
|
|
|
|
+ [ -0.442863, 0.238856, 0.864188 ],
|
|
|
|
+ [ -0.295242, 0.000000, 0.955423 ],
|
|
|
|
+ [ -0.309017, 0.500000, 0.809017 ],
|
|
|
|
+ [ -0.162460, 0.262866, 0.951056 ],
|
|
|
|
+ [ 0.000000, 0.000000, 1.000000 ],
|
|
|
|
+ [ 0.000000, 0.850651, 0.525731 ],
|
|
|
|
+ [ -0.147621, 0.716567, 0.681718 ],
|
|
|
|
+ [ 0.147621, 0.716567, 0.681718 ],
|
|
|
|
+ [ 0.000000, 0.525731, 0.850651 ],
|
|
|
|
+ [ 0.309017, 0.500000, 0.809017 ],
|
|
|
|
+ [ 0.525731, 0.000000, 0.850651 ],
|
|
|
|
+ [ 0.295242, 0.000000, 0.955423 ],
|
|
|
|
+ [ 0.442863, 0.238856, 0.864188 ],
|
|
|
|
+ [ 0.162460, 0.262866, 0.951056 ],
|
|
|
|
+ [ -0.681718, 0.147621, 0.716567 ],
|
|
|
|
+ [ -0.809017, 0.309017, 0.500000 ],
|
|
|
|
+ [ -0.587785, 0.425325, 0.688191 ],
|
|
|
|
+ [ -0.850651, 0.525731, 0.000000 ],
|
|
|
|
+ [ -0.864188, 0.442863, 0.238856 ],
|
|
|
|
+ [ -0.716567, 0.681718, 0.147621 ],
|
|
|
|
+ [ -0.688191, 0.587785, 0.425325 ],
|
|
|
|
+ [ -0.500000, 0.809017, 0.309017 ],
|
|
|
|
+ [ -0.238856, 0.864188, 0.442863 ],
|
|
|
|
+ [ -0.425325, 0.688191, 0.587785 ],
|
|
|
|
+ [ -0.716567, 0.681718, -0.147621 ],
|
|
|
|
+ [ -0.500000, 0.809017, -0.309017 ],
|
|
|
|
+ [ -0.525731, 0.850651, 0.000000 ],
|
|
|
|
+ [ 0.000000, 0.850651, -0.525731 ],
|
|
|
|
+ [ -0.238856, 0.864188, -0.442863 ],
|
|
|
|
+ [ 0.000000, 0.955423, -0.295242 ],
|
|
|
|
+ [ -0.262866, 0.951056, -0.162460 ],
|
|
|
|
+ [ 0.000000, 1.000000, 0.000000 ],
|
|
|
|
+ [ 0.000000, 0.955423, 0.295242 ],
|
|
|
|
+ [ -0.262866, 0.951056, 0.162460 ],
|
|
|
|
+ [ 0.238856, 0.864188, 0.442863 ],
|
|
|
|
+ [ 0.262866, 0.951056, 0.162460 ],
|
|
|
|
+ [ 0.500000, 0.809017, 0.309017 ],
|
|
|
|
+ [ 0.238856, 0.864188, -0.442863 ],
|
|
|
|
+ [ 0.262866, 0.951056, -0.162460 ],
|
|
|
|
+ [ 0.500000, 0.809017, -0.309017 ],
|
|
|
|
+ [ 0.850651, 0.525731, 0.000000 ],
|
|
|
|
+ [ 0.716567, 0.681718, 0.147621 ],
|
|
|
|
+ [ 0.716567, 0.681718, -0.147621 ],
|
|
|
|
+ [ 0.525731, 0.850651, 0.000000 ],
|
|
|
|
+ [ 0.425325, 0.688191, 0.587785 ],
|
|
|
|
+ [ 0.864188, 0.442863, 0.238856 ],
|
|
|
|
+ [ 0.688191, 0.587785, 0.425325 ],
|
|
|
|
+ [ 0.809017, 0.309017, 0.500000 ],
|
|
|
|
+ [ 0.681718, 0.147621, 0.716567 ],
|
|
|
|
+ [ 0.587785, 0.425325, 0.688191 ],
|
|
|
|
+ [ 0.955423, 0.295242, 0.000000 ],
|
|
|
|
+ [ 1.000000, 0.000000, 0.000000 ],
|
|
|
|
+ [ 0.951056, 0.162460, 0.262866 ],
|
|
|
|
+ [ 0.850651, -0.525731, 0.000000 ],
|
|
|
|
+ [ 0.955423, -0.295242, 0.000000 ],
|
|
|
|
+ [ 0.864188, -0.442863, 0.238856 ],
|
|
|
|
+ [ 0.951056, -0.162460, 0.262866 ],
|
|
|
|
+ [ 0.809017, -0.309017, 0.500000 ],
|
|
|
|
+ [ 0.681718, -0.147621, 0.716567 ],
|
|
|
|
+ [ 0.850651, 0.000000, 0.525731 ],
|
|
|
|
+ [ 0.864188, 0.442863, -0.238856 ],
|
|
|
|
+ [ 0.809017, 0.309017, -0.500000 ],
|
|
|
|
+ [ 0.951056, 0.162460, -0.262866 ],
|
|
|
|
+ [ 0.525731, 0.000000, -0.850651 ],
|
|
|
|
+ [ 0.681718, 0.147621, -0.716567 ],
|
|
|
|
+ [ 0.681718, -0.147621, -0.716567 ],
|
|
|
|
+ [ 0.850651, 0.000000, -0.525731 ],
|
|
|
|
+ [ 0.809017, -0.309017, -0.500000 ],
|
|
|
|
+ [ 0.864188, -0.442863, -0.238856 ],
|
|
|
|
+ [ 0.951056, -0.162460, -0.262866 ],
|
|
|
|
+ [ 0.147621, 0.716567, -0.681718 ],
|
|
|
|
+ [ 0.309017, 0.500000, -0.809017 ],
|
|
|
|
+ [ 0.425325, 0.688191, -0.587785 ],
|
|
|
|
+ [ 0.442863, 0.238856, -0.864188 ],
|
|
|
|
+ [ 0.587785, 0.425325, -0.688191 ],
|
|
|
|
+ [ 0.688191, 0.587785, -0.425325 ],
|
|
|
|
+ [ -0.147621, 0.716567, -0.681718 ],
|
|
|
|
+ [ -0.309017, 0.500000, -0.809017 ],
|
|
|
|
+ [ 0.000000, 0.525731, -0.850651 ],
|
|
|
|
+ [ -0.525731, 0.000000, -0.850651 ],
|
|
|
|
+ [ -0.442863, 0.238856, -0.864188 ],
|
|
|
|
+ [ -0.295242, 0.000000, -0.955423 ],
|
|
|
|
+ [ -0.162460, 0.262866, -0.951056 ],
|
|
|
|
+ [ 0.000000, 0.000000, -1.000000 ],
|
|
|
|
+ [ 0.295242, 0.000000, -0.955423 ],
|
|
|
|
+ [ 0.162460, 0.262866, -0.951056 ],
|
|
|
|
+ [ -0.442863, -0.238856, -0.864188 ],
|
|
|
|
+ [ -0.309017, -0.500000, -0.809017 ],
|
|
|
|
+ [ -0.162460, -0.262866, -0.951056 ],
|
|
|
|
+ [ 0.000000, -0.850651, -0.525731 ],
|
|
|
|
+ [ -0.147621, -0.716567, -0.681718 ],
|
|
|
|
+ [ 0.147621, -0.716567, -0.681718 ],
|
|
|
|
+ [ 0.000000, -0.525731, -0.850651 ],
|
|
|
|
+ [ 0.309017, -0.500000, -0.809017 ],
|
|
|
|
+ [ 0.442863, -0.238856, -0.864188 ],
|
|
|
|
+ [ 0.162460, -0.262866, -0.951056 ],
|
|
|
|
+ [ 0.238856, -0.864188, -0.442863 ],
|
|
|
|
+ [ 0.500000, -0.809017, -0.309017 ],
|
|
|
|
+ [ 0.425325, -0.688191, -0.587785 ],
|
|
|
|
+ [ 0.716567, -0.681718, -0.147621 ],
|
|
|
|
+ [ 0.688191, -0.587785, -0.425325 ],
|
|
|
|
+ [ 0.587785, -0.425325, -0.688191 ],
|
|
|
|
+ [ 0.000000, -0.955423, -0.295242 ],
|
|
|
|
+ [ 0.000000, -1.000000, 0.000000 ],
|
|
|
|
+ [ 0.262866, -0.951056, -0.162460 ],
|
|
|
|
+ [ 0.000000, -0.850651, 0.525731 ],
|
|
|
|
+ [ 0.000000, -0.955423, 0.295242 ],
|
|
|
|
+ [ 0.238856, -0.864188, 0.442863 ],
|
|
|
|
+ [ 0.262866, -0.951056, 0.162460 ],
|
|
|
|
+ [ 0.500000, -0.809017, 0.309017 ],
|
|
|
|
+ [ 0.716567, -0.681718, 0.147621 ],
|
|
|
|
+ [ 0.525731, -0.850651, 0.000000 ],
|
|
|
|
+ [ -0.238856, -0.864188, -0.442863 ],
|
|
|
|
+ [ -0.500000, -0.809017, -0.309017 ],
|
|
|
|
+ [ -0.262866, -0.951056, -0.162460 ],
|
|
|
|
+ [ -0.850651, -0.525731, 0.000000 ],
|
|
|
|
+ [ -0.716567, -0.681718, -0.147621 ],
|
|
|
|
+ [ -0.716567, -0.681718, 0.147621 ],
|
|
|
|
+ [ -0.525731, -0.850651, 0.000000 ],
|
|
|
|
+ [ -0.500000, -0.809017, 0.309017 ],
|
|
|
|
+ [ -0.238856, -0.864188, 0.442863 ],
|
|
|
|
+ [ -0.262866, -0.951056, 0.162460 ],
|
|
|
|
+ [ -0.864188, -0.442863, 0.238856 ],
|
|
|
|
+ [ -0.809017, -0.309017, 0.500000 ],
|
|
|
|
+ [ -0.688191, -0.587785, 0.425325 ],
|
|
|
|
+ [ -0.681718, -0.147621, 0.716567 ],
|
|
|
|
+ [ -0.442863, -0.238856, 0.864188 ],
|
|
|
|
+ [ -0.587785, -0.425325, 0.688191 ],
|
|
|
|
+ [ -0.309017, -0.500000, 0.809017 ],
|
|
|
|
+ [ -0.147621, -0.716567, 0.681718 ],
|
|
|
|
+ [ -0.425325, -0.688191, 0.587785 ],
|
|
|
|
+ [ -0.162460, -0.262866, 0.951056 ],
|
|
|
|
+ [ 0.442863, -0.238856, 0.864188 ],
|
|
|
|
+ [ 0.162460, -0.262866, 0.951056 ],
|
|
|
|
+ [ 0.309017, -0.500000, 0.809017 ],
|
|
|
|
+ [ 0.147621, -0.716567, 0.681718 ],
|
|
|
|
+ [ 0.000000, -0.525731, 0.850651 ],
|
|
|
|
+ [ 0.425325, -0.688191, 0.587785 ],
|
|
|
|
+ [ 0.587785, -0.425325, 0.688191 ],
|
|
|
|
+ [ 0.688191, -0.587785, 0.425325 ],
|
|
|
|
+ [ -0.955423, 0.295242, 0.000000 ],
|
|
|
|
+ [ -0.951056, 0.162460, 0.262866 ],
|
|
|
|
+ [ -1.000000, 0.000000, 0.000000 ],
|
|
|
|
+ [ -0.850651, 0.000000, 0.525731 ],
|
|
|
|
+ [ -0.955423, -0.295242, 0.000000 ],
|
|
|
|
+ [ -0.951056, -0.162460, 0.262866 ],
|
|
|
|
+ [ -0.864188, 0.442863, -0.238856 ],
|
|
|
|
+ [ -0.951056, 0.162460, -0.262866 ],
|
|
|
|
+ [ -0.809017, 0.309017, -0.500000 ],
|
|
|
|
+ [ -0.864188, -0.442863, -0.238856 ],
|
|
|
|
+ [ -0.951056, -0.162460, -0.262866 ],
|
|
|
|
+ [ -0.809017, -0.309017, -0.500000 ],
|
|
|
|
+ [ -0.681718, 0.147621, -0.716567 ],
|
|
|
|
+ [ -0.681718, -0.147621, -0.716567 ],
|
|
|
|
+ [ -0.850651, 0.000000, -0.525731 ],
|
|
|
|
+ [ -0.688191, 0.587785, -0.425325 ],
|
|
|
|
+ [ -0.587785, 0.425325, -0.688191 ],
|
|
|
|
+ [ -0.425325, 0.688191, -0.587785 ],
|
|
|
|
+ [ -0.425325, -0.688191, -0.587785 ],
|
|
|
|
+ [ -0.587785, -0.425325, -0.688191 ],
|
|
|
|
+ [ -0.688191, -0.587785, -0.425325 ]
|
|
|
|
+ ];
|
|
|
|
|
|
- var data = new DataView( buffer );
|
|
|
|
|
|
+ return function ( buffer ) {
|
|
|
|
|
|
- // http://tfc.duke.free.fr/coding/md2-specs-en.html
|
|
|
|
|
|
+ var data = new DataView( buffer );
|
|
|
|
|
|
- var header = {};
|
|
|
|
- var headerNames = [
|
|
|
|
- 'ident', 'version',
|
|
|
|
- 'skinwidth', 'skinheight',
|
|
|
|
- 'framesize',
|
|
|
|
- 'num_skins', 'num_vertices', 'num_st', 'num_tris', 'num_glcmds', 'num_frames',
|
|
|
|
- 'offset_skins', 'offset_st', 'offset_tris', 'offset_frames', 'offset_glcmds', 'offset_end'
|
|
|
|
- ];
|
|
|
|
|
|
+ // http://tfc.duke.free.fr/coding/md2-specs-en.html
|
|
|
|
|
|
- for ( var i = 0; i < headerNames.length; i ++ ) {
|
|
|
|
|
|
+ var header = {};
|
|
|
|
+ var headerNames = [
|
|
|
|
+ 'ident', 'version',
|
|
|
|
+ 'skinwidth', 'skinheight',
|
|
|
|
+ 'framesize',
|
|
|
|
+ 'num_skins', 'num_vertices', 'num_st', 'num_tris', 'num_glcmds', 'num_frames',
|
|
|
|
+ 'offset_skins', 'offset_st', 'offset_tris', 'offset_frames', 'offset_glcmds', 'offset_end'
|
|
|
|
+ ];
|
|
|
|
|
|
- header[ headerNames[ i ] ] = data.getInt32( i * 4, true );
|
|
|
|
|
|
+ for ( var i = 0; i < headerNames.length; i ++ ) {
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ header[ headerNames[ i ] ] = data.getInt32( i * 4, true );
|
|
|
|
|
|
- if ( header.ident !== 844121161 || header.version !== 8 ) {
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- console.error( 'Not a valid MD2 file' );
|
|
|
|
- return;
|
|
|
|
|
|
+ if ( header.ident !== 844121161 || header.version !== 8 ) {
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ console.error( 'Not a valid MD2 file' );
|
|
|
|
+ return;
|
|
|
|
|
|
- if ( header.offset_end !== data.byteLength ) {
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- console.error( 'Corrupted MD2 file' );
|
|
|
|
- return;
|
|
|
|
|
|
+ if ( header.offset_end !== data.byteLength ) {
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ console.error( 'Corrupted MD2 file' );
|
|
|
|
+ return;
|
|
|
|
|
|
- //
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- var geometry = new THREE.Geometry();
|
|
|
|
|
|
+ //
|
|
|
|
|
|
- // uvs
|
|
|
|
|
|
+ var geometry = new THREE.Geometry();
|
|
|
|
|
|
- var uvs = [];
|
|
|
|
- var offset = header.offset_st;
|
|
|
|
|
|
+ // uvs
|
|
|
|
|
|
- for ( var i = 0; i < header.num_st; i ++, offset += 4 ) {
|
|
|
|
|
|
+ var uvs = [];
|
|
|
|
+ var offset = header.offset_st;
|
|
|
|
|
|
- var u = data.getInt16( offset + 0, true );
|
|
|
|
- var v = data.getInt16( offset + 2, true );
|
|
|
|
|
|
+ for ( var i = 0; i < header.num_st; i ++, offset += 4 ) {
|
|
|
|
|
|
- var uv = new THREE.Vector2( u / header.skinwidth, 1 - ( v / header.skinheight ) );
|
|
|
|
|
|
+ var u = data.getInt16( offset + 0, true );
|
|
|
|
+ var v = data.getInt16( offset + 2, true );
|
|
|
|
|
|
- uvs.push( uv );
|
|
|
|
|
|
+ var uv = new THREE.Vector2( u / header.skinwidth, 1 - ( v / header.skinheight ) );
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ uvs.push( uv );
|
|
|
|
|
|
- // triangles
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- var offset = header.offset_tris;
|
|
|
|
|
|
+ // triangles
|
|
|
|
|
|
- for ( var i = 0; i < header.num_tris; i ++ ) {
|
|
|
|
|
|
+ var offset = header.offset_tris;
|
|
|
|
|
|
- var a = data.getUint16( offset + 0, true );
|
|
|
|
- var b = data.getUint16( offset + 2, true );
|
|
|
|
- var c = data.getUint16( offset + 4, true );
|
|
|
|
|
|
+ for ( var i = 0; i < header.num_tris; i ++ ) {
|
|
|
|
|
|
- var face = new THREE.Face3( a, b, c );
|
|
|
|
|
|
+ var a = data.getUint16( offset + 0, true );
|
|
|
|
+ var b = data.getUint16( offset + 2, true );
|
|
|
|
+ var c = data.getUint16( offset + 4, true );
|
|
|
|
|
|
- geometry.faces.push( face );
|
|
|
|
|
|
+ var face = new THREE.Face3( a, b, c );
|
|
|
|
|
|
- geometry.faceVertexUvs[ 0 ].push( [
|
|
|
|
- uvs[ data.getUint16( offset + 6, true ) ],
|
|
|
|
- uvs[ data.getUint16( offset + 8, true ) ],
|
|
|
|
- uvs[ data.getUint16( offset + 10, true ) ]
|
|
|
|
- ] );
|
|
|
|
|
|
+ geometry.faces.push( face );
|
|
|
|
|
|
- offset += 12;
|
|
|
|
|
|
+ geometry.faceVertexUvs[ 0 ].push( [
|
|
|
|
+ uvs[ data.getUint16( offset + 6, true ) ],
|
|
|
|
+ uvs[ data.getUint16( offset + 8, true ) ],
|
|
|
|
+ uvs[ data.getUint16( offset + 10, true ) ]
|
|
|
|
+ ] );
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ offset += 12;
|
|
|
|
|
|
- // frames
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- var translation = new THREE.Vector3();
|
|
|
|
- var scale = new THREE.Vector3();
|
|
|
|
|
|
+ // frames
|
|
|
|
|
|
- var offset = header.offset_frames;
|
|
|
|
|
|
+ var translation = new THREE.Vector3();
|
|
|
|
+ var scale = new THREE.Vector3();
|
|
|
|
|
|
- for ( var i = 0; i < header.num_frames; i ++ ) {
|
|
|
|
|
|
+ var offset = header.offset_frames;
|
|
|
|
|
|
- scale.set(
|
|
|
|
- data.getFloat32( offset + 0, true ),
|
|
|
|
- data.getFloat32( offset + 4, true ),
|
|
|
|
- data.getFloat32( offset + 8, true )
|
|
|
|
- );
|
|
|
|
|
|
+ for ( var i = 0; i < header.num_frames; i ++ ) {
|
|
|
|
|
|
- translation.set(
|
|
|
|
- data.getFloat32( offset + 12, true ),
|
|
|
|
- data.getFloat32( offset + 16, true ),
|
|
|
|
- data.getFloat32( offset + 20, true )
|
|
|
|
- );
|
|
|
|
|
|
+ scale.set(
|
|
|
|
+ data.getFloat32( offset + 0, true ),
|
|
|
|
+ data.getFloat32( offset + 4, true ),
|
|
|
|
+ data.getFloat32( offset + 8, true )
|
|
|
|
+ );
|
|
|
|
|
|
- offset += 24;
|
|
|
|
|
|
+ translation.set(
|
|
|
|
+ data.getFloat32( offset + 12, true ),
|
|
|
|
+ data.getFloat32( offset + 16, true ),
|
|
|
|
+ data.getFloat32( offset + 20, true )
|
|
|
|
+ );
|
|
|
|
|
|
- var string = [];
|
|
|
|
|
|
+ offset += 24;
|
|
|
|
|
|
- for ( var j = 0; j < 16; j ++ ) {
|
|
|
|
|
|
+ var string = [];
|
|
|
|
|
|
- string[ j ] = data.getUint8( offset + j, true );
|
|
|
|
|
|
+ for ( var j = 0; j < 16; j ++ ) {
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ string[ j ] = data.getUint8( offset + j, true );
|
|
|
|
|
|
- var frame = {
|
|
|
|
- name: String.fromCharCode.apply( null, string ),
|
|
|
|
- vertices: []
|
|
|
|
- };
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- offset += 16;
|
|
|
|
|
|
+ var frame = {
|
|
|
|
+ name: String.fromCharCode.apply( null, string ),
|
|
|
|
+ vertices: [],
|
|
|
|
+ normals: []
|
|
|
|
+ };
|
|
|
|
|
|
- for ( var j = 0; j < header.num_vertices; j ++ ) {
|
|
|
|
|
|
+ offset += 16;
|
|
|
|
|
|
- var x = data.getUint8( offset ++, true );
|
|
|
|
- var y = data.getUint8( offset ++, true );
|
|
|
|
- var z = data.getUint8( offset ++, true );
|
|
|
|
- var n = data.getUint8( offset ++, true );
|
|
|
|
|
|
+ for ( var j = 0; j < header.num_vertices; j ++ ) {
|
|
|
|
|
|
- var vertex = new THREE.Vector3(
|
|
|
|
- x * scale.x + translation.x,
|
|
|
|
- z * scale.z + translation.z,
|
|
|
|
- y * scale.y + translation.y
|
|
|
|
- );
|
|
|
|
|
|
+ var x = data.getUint8( offset ++, true );
|
|
|
|
+ var y = data.getUint8( offset ++, true );
|
|
|
|
+ var z = data.getUint8( offset ++, true );
|
|
|
|
+ var n = data.getUint8( offset ++, true );
|
|
|
|
|
|
- frame.vertices.push( vertex );
|
|
|
|
|
|
+ var vertex = new THREE.Vector3(
|
|
|
|
+ x * scale.x + translation.x,
|
|
|
|
+ z * scale.z + translation.z,
|
|
|
|
+ y * scale.y + translation.y
|
|
|
|
+ );
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ frame.vertices.push( vertex );
|
|
|
|
+ frame.normals.push( new THREE.Vector3().fromArray( normals[ n ] ) )
|
|
|
|
|
|
- geometry.morphTargets.push( frame );
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ geometry.morphTargets.push( frame );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
- geometry.vertices = geometry.morphTargets[ 0 ].vertices;
|
|
|
|
|
|
+ geometry.vertices = geometry.morphTargets[ 0 ].vertices;
|
|
|
|
|
|
- return geometry;
|
|
|
|
|
|
+ return geometry;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ })()
|
|
|
|
|
|
}
|
|
}
|