     {
         [ length id3v1-offset >= ]
         [ id3v1-length tail-slice* "TAG" head? ]
-    } 1&& ; inline
+    } 1&& ;
 
 : id3v1+? ( seq -- ? )
     {
         [ length id3v1+-offset >= ]
         [ id3v1+-length tail-slice* "TAG+" head? ]
-    } 1&& ; inline
+    } 1&& ;
 
 : pair>frame ( string key -- frame/f )
     over [

        [ [ 181 211 ] dip subseq decode-text >>genre-name ]
        [ [ 211 217 ] dip subseq decode-text >>start-time ]
        [ [ 217 223 ] dip subseq decode-text >>end-time ]
    } cleave ; inline

: read-v1+-tags ( id3 seq -- id3 )
    id3v1+-offset tail-slice* 4 tail-slice
    extract-v1+-tags ; inline

: parse-genre ( string -- n/f )
    dup "(" ?head-slice drop ")" ?tail-slice drop

        [ [ 4 8 ] dip subseq seq>synchsafe >>size ]
        [ [ 8 10 ] dip subseq >byte-array >>flags ]
        [ read-frame-data decode-text >>data ]
    } cleave ;

: read-frame ( seq -- frame/f )
    dup 4 head-slice valid-tag?
    [ (read-frame) ] [ drop f ] if ;

: remove-frame ( seq frame -- seq )
    size>> 10 + tail-slice ;

: frames>assoc ( seq -- assoc )
    [ [ tag>> ] keep ] H{ } map>assoc ;

: read-frames ( seq -- assoc )
    [ dup read-frame dup ] [ [ remove-frame ] keep ] produce 2nip ;
    
: read-v2-header ( seq -- header )
    [ <header> ] dip
