/************************************************************\ * * id3lib v1b Copyright 2005 Howard Yeend * www.puremango.co.uk * * This file is part of id3lib v1b. * * id3lib is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * id3lib is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with freeCap; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * \************************************************************/ // !!!!!!!!!!!!!!!!! this is BETA code !!!!!!!!!!!!!!!!!!!! // standard genres $genres = Array(); $genres[0] = "Blues"; $genres[1] = "Classic Rock"; $genres[2] = "Country"; $genres[3] = "Dance"; $genres[4] = "Disco"; $genres[5] = "Funk"; $genres[6] = "Grunge"; $genres[7] = "Hip-Hop"; $genres[8] = "Jazz"; $genres[9] = "Metal"; $genres[10] = "New Age"; $genres[11] = "Oldies"; $genres[12] = "Other"; $genres[13] = "Pop"; $genres[14] = "R&B"; $genres[15] = "Rap"; $genres[16] = "Reggae"; $genres[17] = "Rock"; $genres[18] = "Techno"; $genres[19] = "Industrial"; $genres[20] = "Alternative"; $genres[21] = "Ska"; $genres[22] = "Death Metal"; $genres[23] = "Pranks"; $genres[24] = "Soundtrack"; $genres[25] = "Euro-Techno"; $genres[26] = "Ambient"; $genres[27] = "Trip-Hop"; $genres[28] = "Vocal"; $genres[29] = "Jazz+Funk"; $genres[30] = "Fusion"; $genres[31] = "Trance"; $genres[32] = "Classical"; $genres[33] = "Instrumental"; $genres[34] = "Acid"; $genres[35] = "House"; $genres[36] = "Game"; $genres[37] = "Sound Clip"; $genres[38] = "Gospel"; $genres[39] = "Noise"; $genres[40] = "AlternRock"; $genres[41] = "Bass"; $genres[42] = "Soul"; $genres[43] = "Punk"; $genres[44] = "Space"; $genres[45] = "Meditative"; $genres[46] = "Instrumental Pop"; $genres[47] = "Instrumental Rock"; $genres[48] = "Ethnic"; $genres[49] = "Gothic"; $genres[50] = "Darkwave"; $genres[51] = "Techno-Industrial"; $genres[52] = "Electronic"; $genres[53] = "Pop-Folk"; $genres[54] = "Eurodance"; $genres[55] = "Dream"; $genres[56] = "Southern Rock"; $genres[57] = "Comedy"; $genres[58] = "Cult"; $genres[59] = "Gangsta"; $genres[60] = "Top 40"; $genres[61] = "Christian Rap"; $genres[62] = "Pop/Funk"; $genres[63] = "Jungle"; $genres[64] = "Native American"; $genres[65] = "Cabaret"; $genres[66] = "New Wave"; $genres[67] = "Psychadelic"; $genres[68] = "Rave"; $genres[69] = "Showtunes"; $genres[70] = "Trailer"; $genres[71] = "Lo-Fi"; $genres[72] = "Tribal"; $genres[73] = "Acid Punk"; $genres[74] = "Acid Jazz"; $genres[75] = "Polka"; $genres[76] = "Retro"; $genres[77] = "Musical"; $genres[78] = "Rock & Roll"; $genres[79] = "Hard Rock"; // nullsoft-added genres $genres[80] = "Folk"; $genres[81] = "Folk-Rock"; $genres[82] = "National Folk"; $genres[83] = "Swing"; $genres[84] = "Fast Fusion"; $genres[85] = "Bebob"; $genres[86] = "Latin"; $genres[87] = "Revival"; $genres[88] = "Celtic"; $genres[89] = "Bluegrass"; $genres[90] = "Avantgarde"; $genres[91] = "Gothic Rock"; $genres[92] = "Progressive Rock"; $genres[93] = "Psychedelic Rock"; $genres[94] = "Symphonic Rock"; $genres[95] = "Slow Rock"; $genres[96] = "Big Band"; $genres[97] = "Chorus"; $genres[98] = "Easy Listening"; $genres[99] = "Acoustic"; $genres[100] = "Humour"; $genres[101] = "Speech"; $genres[102] = "Chanson"; $genres[103] = "Opera"; $genres[104] = "Chamber Music"; $genres[105] = "Sonata"; $genres[106] = "Symphony"; $genres[107] = "Booty Bass"; $genres[108] = "Primus"; $genres[109] = "Porn Groove"; $genres[110] = "Satire"; $genres[111] = "Slow Jam"; $genres[112] = "Club"; $genres[113] = "Tango"; $genres[114] = "Samba"; $genres[115] = "Folklore"; $genres[116] = "Ballad"; $genres[117] = "Power Ballad"; $genres[118] = "Rhythmic Soul"; $genres[119] = "Freestyle"; $genres[120] = "Duet"; $genres[121] = "Punk Rock"; $genres[122] = "Drum Solo"; $genres[123] = "A capella"; $genres[124] = "Euro-House"; $genres[125] = "Dance"; // any others? // embedded picture types $pictypes = Array(); $pictypes[0] = "Other"; $pictypes[1] = "32x32 pixels 'file icon' (PNG only)"; $pictypes[2] = "Other file icon"; $pictypes[3] = "Cover (front)"; $pictypes[4] = "Cover (back)"; $pictypes[5] = "Leaflet page"; $pictypes[6] = "Media (e.g. lable side of CD)"; $pictypes[7] = "Lead artist/lead performer/soloist"; $pictypes[8] = "Artist/performer"; $pictypes[9] = "Conductor"; $pictypes[10] = "Band/Orchestra"; $pictypes[11] = "Composer"; $pictypes[12] = "Lyricist/text writer"; $pictypes[13] = "Recording Location"; $pictypes[14] = "During recording"; $pictypes[15] = "During performance"; $pictypes[16] = "Movie/video screen capture"; $pictypes[17] = "A bright coloured fish"; //?!?! $pictypes[18] = "Illustration"; $pictypes[19] = "Band/artist logotype"; $pictypes[20] = "Publisher/Studio logotype"; // what the frame names mean $frame_definitions = Array(); $frame_definitions["AENC"] = "Audio encryption"; $frame_definitions["APIC"] = "Attached picture"; $frame_definitions["COMM"] = "Comments"; $frame_definitions["COMR"] = "Commercial frame"; $frame_definitions["ENCR"] = "Encryption method registration"; $frame_definitions["EQUA"] = "Equalization"; $frame_definitions["ETCO"] = "Event timing codes"; $frame_definitions["GEOB"] = "General encapsulated object"; $frame_definitions["GRID"] = "Group identification registration"; $frame_definitions["IPLS"] = "Involved people list"; $frame_definitions["LINK"] = "Linked information"; $frame_definitions["MCDI"] = "Music CD identifier"; $frame_definitions["MLLT"] = "MPEG location lookup table"; $frame_definitions["OWNE"] = "Ownership frame"; $frame_definitions["PRIV"] = "Private frame"; $frame_definitions["PCNT"] = "Play counter"; $frame_definitions["POPM"] = "Popularimeter"; $frame_definitions["POSS"] = "Position synchronisation frame"; $frame_definitions["RBUF"] = "Recommended buffer size"; $frame_definitions["RVAD"] = "Relative volume adjustment"; $frame_definitions["RVRB"] = "Reverb"; $frame_definitions["SYLT"] = "Synchronized lyric/text"; $frame_definitions["SYTC"] = "Synchronized tempo codes"; $frame_definitions["TALB"] = "Album/Movie/Show title"; $frame_definitions["TBPM"] = "BPM (beats per minute)"; $frame_definitions["TCOM"] = "Composer"; $frame_definitions["TCON"] = "Content type"; $frame_definitions["TCOP"] = "Copyright message"; $frame_definitions["TDAT"] = "Date"; $frame_definitions["TDLY"] = "Playlist delay"; $frame_definitions["TENC"] = "Encoded by"; $frame_definitions["TEXT"] = "Lyricist/Text writer"; $frame_definitions["TFLT"] = "File type"; $frame_definitions["TIME"] = "Time"; $frame_definitions["TIT1"] = "Content group description"; $frame_definitions["TIT2"] = "Title/songname/content description"; $frame_definitions["TIT3"] = "Subtitle/Description refinement"; $frame_definitions["TKEY"] = "Initial key"; $frame_definitions["TLAN"] = "Language(s)"; $frame_definitions["TLEN"] = "Length"; $frame_definitions["TMED"] = "Media type"; $frame_definitions["TOAL"] = "Original album/movie/show title"; $frame_definitions["TOFN"] = "Original filename"; $frame_definitions["TOLY"] = "Original lyricist(s)/text writer(s)"; $frame_definitions["TOPE"] = "Original artist(s)/performer(s)"; $frame_definitions["TORY"] = "Original release year"; $frame_definitions["TOWN"] = "File owner/licensee"; $frame_definitions["TPE1"] = "Lead performer(s)/Soloist(s)"; $frame_definitions["TPE2"] = "Band/orchestra/accompaniment"; $frame_definitions["TPE3"] = "Conductor/performer refinement"; $frame_definitions["TPE4"] = "Interpreted, remixed, or otherwise modified by"; $frame_definitions["TPOS"] = "Part of a set"; $frame_definitions["TPUB"] = "Publisher"; $frame_definitions["TRCK"] = "Track number/Position in set"; $frame_definitions["TRDA"] = "Recording dates"; $frame_definitions["TRSN"] = "Internet radio station name"; $frame_definitions["TRSO"] = "Internet radio station owner"; $frame_definitions["TSIZ"] = "Size"; $frame_definitions["TSRC"] = "ISRC (international standard recording code)"; $frame_definitions["TSSE"] = "Software/Hardware and settings used for encoding"; $frame_definitions["TYER"] = "Year"; $frame_definitions["TXXX"] = "User defined text information frame"; $frame_definitions["UFID"] = "Unique file identifier"; $frame_definitions["USER"] = "Terms of use"; $frame_definitions["USLT"] = "Unsychronized lyric/text transcription"; $frame_definitions["WCOM"] = "Commercial information"; $frame_definitions["WCOP"] = "Copyright/Legal information"; $frame_definitions["WOAF"] = "Official audio file webpage"; $frame_definitions["WOAR"] = "Official artist/performer webpage"; $frame_definitions["WOAS"] = "Official audio source webpage"; $frame_definitions["WORS"] = "Official internet radio station homepage"; $frame_definitions["WPAY"] = "Payment"; $frame_definitions["WPUB"] = "Publishers official webpage"; $frame_definitions["WXXX"] = "User defined URL link frame"; function asc2bin($char) { // returns 8bit binary value from ASCII char // eg; asc2bin("a") returns 01100001 return str_pad(decbin(ord($char)), 8, "0", STR_PAD_LEFT); } function id3size2dec($size) { // not 100% sure of this part, but seems to work $sizes[0] = asc2bin($size{0}); $sizes[1] = asc2bin($size{1}); $sizes[2] = asc2bin($size{2}); $sizes[3] = asc2bin($size{3}); $size = 0; foreach($sizes as $size_byte) { // knock off MSB $size_byte = substr($size_byte,1,7); $size += bindec($size_byte); } return $size; } function id3encoding($encbyte) { $encoding = ord($encbyte); if($encoding==0) { $encoding = "ISO-8859-1"; } else if($encoding==1){ $encoding = "unicode"; } // else ?? - not defined in standard return $encoding; } function id3getpictype($pic_id) { $pic_id = ord($pic_id); switch($pic_id) { case "": } } function id3_info($file_location) { global $genres,$frame_definitions; // read file $data = file_get_contents($file_location); // get ID3v1 tag: $v1data = substr($data,-128); if(substr($v1data,0,3)!="TAG") { // no v1 tag $id3v1 = false; } else { // get v1 tag $id3v1['title'] = substr($v1data,3,30); $id3v1['artist'] = substr($v1data,33,30); $id3v1['album'] = substr($v1data,63,30); $id3v1['year'] = substr($v1data,93,4); // lookup genre-id (@ if index out of range) $id3v1['genre_id'] = @$genres[ord(substr($v1data,127,1))]; $id3v1['comment'] = substr($v1data,97,30); } // get ID3v2 tag: $v2data = substr($data,0,2048); if(substr($v2data,0,3)!="ID3") { // no v2 tag $id3v2 = false; } else { // get v2 tag // id3 v2 is incredibly complicated, a testament to this being that // the standard (www.id3.org) is nearly 1000 lines long // this script does its best to get the v2 data // ID3v2 Header: $id3v2['header']['version'] = "2.".ord(substr($v2data,3,1)).".".ord(substr($v2data,4,1)); $flags = asc2bin(substr($v2data,5,1)); $id3v2['header']['flags']['unsynchronisation'] = (substr($flags,0,1)=="1"); $id3v2['header']['flags']['extended'] = (substr($flags,1,1)=="1"); $id3v2['header']['flags']['experimental'] = (substr($flags,2,1)=="1"); $id3v2['header']['flags']['other-d'] = (substr($flags,3,1)=="1"); $id3v2['header']['flags']['other-e'] = (substr($flags,4,1)=="1"); $id3v2['header']['flags']['other-f'] = (substr($flags,5,1)=="1"); $id3v2['header']['flags']['other-g'] = (substr($flags,6,1)=="1"); $id3v2['header']['flags']['other-h'] = (substr($flags,7,1)=="1"); $id3v2['header']['size'] = id3size2dec(substr($v2data,6,4)); if($id3v2['header']['flags']['extended']) { // get extended header info // i don't have any files with extended headers, so haven't tested this *AT ALL* // it should be considered at best beta, at worst totally meaningless // if you want me to code it, send me mp3s with extended headers! $id3v2['header']['extended']['size'] = id3size2dec(substr($v2data,10,4)); $flags = asc2bin(substr($v2data,14,1)).asc2bin(substr($v2data,15,1)); $id3v2['header']['extended']['flags']['has_crc32'] = (substr($flags,0,1)=="1"); $id3v2['header']['extended']['flags']['other-b'] = (substr($flags,1,1)=="1"); $id3v2['header']['extended']['flags']['other-c'] = (substr($flags,2,1)=="1"); $id3v2['header']['extended']['flags']['other-d'] = (substr($flags,3,1)=="1"); $id3v2['header']['extended']['flags']['other-e'] = (substr($flags,4,1)=="1"); $id3v2['header']['extended']['flags']['other-f'] = (substr($flags,5,1)=="1"); $id3v2['header']['extended']['flags']['other-g'] = (substr($flags,6,1)=="1"); $id3v2['header']['extended']['flags']['other-h'] = (substr($flags,7,1)=="1"); $id3v2['header']['extended']['flags']['other-i'] = (substr($flags,8,1)=="1"); $id3v2['header']['extended']['flags']['other-j'] = (substr($flags,9,1)=="1"); $id3v2['header']['extended']['flags']['other-k'] = (substr($flags,10,1)=="1"); $id3v2['header']['extended']['flags']['other-l'] = (substr($flags,11,1)=="1"); $id3v2['header']['extended']['flags']['other-m'] = (substr($flags,12,1)=="1"); $id3v2['header']['extended']['flags']['other-n'] = (substr($flags,13,1)=="1"); $id3v2['header']['extended']['flags']['other-o'] = (substr($flags,14,1)=="1"); $id3v2['header']['extended']['padding_size'] = substr($v2data,16,4); if($id3v2['header']['extended']['flags']['has_crc32']) { $id3v2['header']['extended']['crc32'] = substr($flags,20,4); $frame_start = 24; } else { $frame_start = 20; } } else { $frame_start = 10; } for($i=0 ; $i<30 ; $i++) { $frame_name = substr($v2data,$frame_start,4); if(array_key_exists($frame_name,$frame_definitions)) { // what's this frame called $id3v2['frames'][$frame_name]['definition'] = $frame_definitions[$frame_name]; // how big is the data? $id3v2['frames'][$frame_name]['size'] = id3size2dec(substr($v2data,$frame_start+4,4)); // get flags $flags = asc2bin(substr($v2data,$frame_start+8,1)).asc2bin(substr($v2data,$frame_start+9,1)); $id3v2['frames'][$frame_name]['flags']['tag_alter'] = (substr($flags,0,1)=="1"); $id3v2['frames'][$frame_name]['flags']['file_alter'] = (substr($flags,1,1)=="1"); $id3v2['frames'][$frame_name]['flags']['read_only'] = (substr($flags,2,1)=="1"); $id3v2['frames'][$frame_name]['flags']['other-d'] = (substr($flags,3,1)=="1"); $id3v2['frames'][$frame_name]['flags']['other-e'] = (substr($flags,4,1)=="1"); $id3v2['frames'][$frame_name]['flags']['other-f'] = (substr($flags,5,1)=="1"); $id3v2['frames'][$frame_name]['flags']['other-g'] = (substr($flags,6,1)=="1"); $id3v2['frames'][$frame_name]['flags']['other-h'] = (substr($flags,7,1)=="1"); $id3v2['frames'][$frame_name]['flags']['compressed'] = (substr($flags,8,1)=="1"); $id3v2['frames'][$frame_name]['flags']['encrypted'] = (substr($flags,9,1)=="1"); $id3v2['frames'][$frame_name]['flags']['grouping'] = (substr($flags,10,1)=="1"); $id3v2['frames'][$frame_name]['flags']['other-l'] = (substr($flags,11,1)=="1"); $id3v2['frames'][$frame_name]['flags']['other-m'] = (substr($flags,12,1)=="1"); $id3v2['frames'][$frame_name]['flags']['other-n'] = (substr($flags,13,1)=="1"); $id3v2['frames'][$frame_name]['flags']['other-o'] = (substr($flags,14,1)=="1"); $id3v2['frames'][$frame_name]['flags']['other-p'] = (substr($flags,15,1)=="1"); // if set, the flags in the second byte add their data to the header // untested $frame_data_start = $frame_start+10; if($id3v2['frames'][$frame_name]['flags']['compressed']) { $id3v2['frames'][$frame_name]['decompressed_size'] = substr($v2data,$frame_data_start,4); $frame_data_start = 20; } if($id3v2['frames'][$frame_name]['flags']['encrypted']) { $id3v2['frames'][$frame_name]['encryption_method'] = substr($v2data,$frame_data_start,1); $frame_data_start +=1; } if($id3v2['frames'][$frame_name]['flags']['grouping']) { $id3v2['frames'][$frame_name]['group_id'] = substr($v2data,$frame_data_start,1); $frame_data_start +=1; } // some frames have different data syntax. this is getting silly. // get raw frame data $frame_data = substr($v2data,$frame_data_start,$id3v2['frames'][$frame_name]['size']); if(substr($frame_name,0,1)=="T" && $frame_name!="TXXX") { // text frame; standard syntax (thank god) $id3v2['frames'][$frame_name]['encoding'] = id3encoding(substr($frame_data,0,1)); $id3v2['frames'][$frame_name]['data'] = substr($frame_data,1); } else if(substr($frame_name,0,1)=="W" && $frame_name!="WXXX") { // URL frame - dead simple $id3v2['frames'][$frame_name]['data'] = $frame_data; } else { // non standard frame syntax- most of these are untested (and rarely found (thank your gods)) switch($frame_name) { case "OWNE": $id3v2['frames'][$frame_name]['encoding'] = id3encoding(substr($frame_data,0,1)); $nullpos = strpos($frame_data,chr(255)); $id3v2['frames'][$frame_name]['price_payed'] = substr($frame_data,1,$nullpos); $id3v2['frames'][$frame_name]['date_bought'] = substr($frame_data,$nullpos,8); $id3v2['frames'][$frame_name]['sold_by'] = substr($frame_data,$nullpos+8); case "USER": $id3v2['frames'][$frame_name]['encoding'] = id3encoding(substr($frame_data,0,1)); $id3v2['frames'][$frame_name]['language'] = substr($frame_data,1,3); $id3v2['frames'][$frame_name]['data'] = substr($frame_data,3); case "PCNT": // in binary $id3v2['frames'][$frame_name]['data'] = $frame_data; case "APIC": // attached picture!?!?! wtf are these guys on? // perhaps more weirdly, I've actually seen an mp3 that had one of these (it was a boring logo) // this code didn't manage to extract it properly.. $id3v2['frames'][$frame_name]['encoding'] = id3encoding(substr($frame_data,0,1)); $nullpos = strpos($frame_data,chr(0)); $id3v2['frames'][$frame_name]['mime_type'] = substr($frame_data,0,$nullpos); $other_pic_data = substr($frame_data,$nullpos); $nullpos = strpos($other_pic_data,chr(0)); $id3v2['frames'][$frame_name]['pic_type'] = id3getpictype(substr($other_pic_data,0,1)); $id3v2['frames'][$frame_name]['description'] = substr($other_pic_data,1,$nullpos); $id3v2['frames'][$frame_name]['data'] = substr($v2data,$frame_data_start,500); case "COMM": $id3v2['frames'][$frame_name]['encoding'] = id3encoding(substr($frame_data,0,1)); $id3v2['frames'][$frame_name]['language'] = substr($frame_data,1,3); $frame_data = substr($frame_data,4); $nullpos = strpos($frame_data,chr(0)); $id3v2['frames'][$frame_name]['short_desc'] = substr($frame_data,0,$nullpos); $id3v2['frames'][$frame_name]['data'] = substr($frame_data,$nullpos); break; case "USLT": $id3v2['frames'][$frame_name]['encoding'] = id3encoding(substr($frame_data,0,1)); $id3v2['frames'][$frame_name]['language'] = substr($frame_data,1,3); $nullpos = strpos($frame_data,chr(255)); $id3v2['frames'][$frame_name]['description'] = substr($frame_data,0,$nullpos); $id3v2['frames'][$frame_name]['data'] = substr($frame_data,$nullpos); break; case "SYTC": $id3v2['frames'][$frame_name]['timestamp_format'] = (ord(substr($frame_data,0,1))=="1") ? "mpeg frames" : "milliseconds"; $id3v2['frames'][$frame_name]['data'] = substr($frame_data,1); break; case "MCDI": $id3v2['frames'][$frame_name]['cd_toc'] = $frame_data; break; case "IPLS": $id3v2['frames'][$frame_name]['encoding'] = id3encoding(substr($frame_data,0,1)); $id3v2['frames'][$frame_name]['data'] = substr($frame_data,1); break; case "TXXX": // user defined text frame $id3v2['frames'][$frame_name]['encoding'] = id3encoding(substr($frame_data,0,1)); $nullpos = strpos($frame_data,chr(255)); $id3v2['frames'][$frame_name]['description'] = substr($frame_data,0,$nullpos); $id3v2['frames'][$frame_name]['data'] = substr($frame_data,$nullpos); break; case "UFID": $nullpos = strpos($frame_data,chr(255)); $id3v2['frames'][$frame_name]['owner'] = substr($frame_data,0,$nullpos); $id3v2['frames'][$frame_name]['id'] = substr($frame_data,$nullpos,64); break; case "WXXX": // unicode or iso? $id3v2['frames'][$frame_name]['encoding'] = id3encoding(substr($frame_data,0,1)); // should be delimited so: description(null)url // but most mp3s I've seen don't even include the descriptor, // so I do a different check $urlpos = strpos($frame_data,"http://"); if($urlpos===false) { $urlpos = strpos($frame_data,"www")-3; } if($urlpos!==false) { $id3v2['frames'][$frame_name]['description'] = substr($frame_data,1,$urlpos-1); $id3v2['frames'][$frame_name]['data'] = substr($frame_data,$urlpos); } else { // totally uncompliant (no descriptor) $id3v2['frames'][$frame_name]['data'] = $frame_data; } break; default: // covers ETCO, MLLT, SYLT, RVAD, EQUA, RVRB, GEOB, POPM, RBUF, AENC, LINK, POSS, COMR, ENCR, GRID, PRIV $id3v2['frames'][$frame_name]['data'] = $frame_data; break; } } $frame_start += $id3v2['frames'][$frame_name]['size']+10; } else { // unknown frame definition - best to ignore $id3v2['unrecognised_frame_titles'][] = $frame_name; } } $id3v2['unrecognised_frame_titles'] = array_unique($id3v2['unrecognised_frame_titles']); } $retval = Array(); $retval['v1'] = $id3v1; $retval['v2'] = $id3v2; return $retval; } if(!empty($_FILES['upfile']['tmp_name'])) { $id3_info = id3_info($_FILES['upfile']['tmp_name']); ?>
var_dump($id3_info); ?>if($id3_info['v2']) { $frames = $id3_info['v2']['frames']; if(is_array($frames)) { ?>
| ".$val['definition']." | [".$val['data']."] |