anchor.diff:  <cfcomponent output="false" extends="org.cfstatic.util.Base" hint="I provide an api for taking css and replacing its relative image paths with full image paths complete with cache busters based on the images last modified date">
  -
  -<!--- properties --->
  -	<cfscript>
  -		variables._baseCssPath	= "";
  -		variables._baseCssUrl	= "";
  -	</cfscript>
   
   <!--- constructor --->
   	<cffunction name="init" access="public" returntype="any" output="false" hint="I am the constructor of the parser. I take the base path and url of the css files, used to calculate full paths from relative paths.">
  
positive.code: 		<cfargument name="baseCssPath" type="string" required="true" />
  
      	<cfscript>
      		_setBaseCssUrl( arguments.baseCssUrl );
      		_setBaseCssPath( arguments.baseCssPath );
  			
      		return this;
      	</cfscript>
      </cffunction>
  
negative.code: 	<cffunction name="_calculateFullUrl" access="public" returntype="string" output="false" hint="I calculate the full path from a relative image path, appending a cachebuster based on the last modified date of the image file">
  		<cfargument name="relativeUrl" type="string" required="true" />
  		<cfargument name="cssFilePath" type="string" required="true" />
  
  		<cfscript>
  			var fullUrl           = relativeUrl;
  			var lastModified      = "";
  			var cssFileUrl        = "";
  			var found             = true;
  			var nTraversals       = 0;
  			var imagePath         = "";
  			var imageLastModified = "";
  			var cacheBuster       = "";
  			var i                 = 0;
  
  			// ignore non relative paths
  			if ( Left( relativeUrl, 1 ) NEQ '/' AND NOT ReFindNoCase( '^(http|https)://', relativeUrl ) AND NOT ReFindNoCase( '^data:.*?;base64,', relativeUrl ) ) {
  				cssFileUrl = _getBaseCssUrl() & Replace( GetDirectoryFromPath( cssFilePath ), _getBaseCssPath(), '' );
  
  				// figure out how to traverse the url
  				while( found ){
  					found = false;
  					if ( Left( relativeUrl, (nTraversals+1) * 3 ) EQ RepeatString( '../', nTraversals+1 ) ) {
  						nTraversals++;
  						found = true;
  					}
  				}
  				for( i=1; i LTE nTraversals; i++ ){
  					cssFileUrl = ListDeleteAt( cssFileUrl, ListLen( cssFileUrl, '/' ), '/' );
  				}
  
  				// build the full url without relative paths
  				if ( nTraversals ){
  					fullUrl = $listAppend( cssFileUrl, Replace( relativeUrl, RepeatString( '../', nTraversals ), '' ), '/' );
  				} else {
  					fullUrl = $listAppend( cssFileUrl, relativeUrl, '/' );
  				}
  
  				// calculate a cache buster if we can
  				imagePath = $listAppend( getDirectoryFromPath( cssFilePath ), relativeUrl, '/' );
  				if ( FileExists( imagePath ) ){
  					imageLastModified = $fileLastModified( imagePath );
  					cacheBuster = DateFormat( imageLastModified, 'yyyymmdd' ) & TimeFormat( imageLastModified, 'hhmmss' );
  					fullUrl = fullUrl & '?' & cacheBuster;
  				}
  			}
  
  			return fullUrl;
  		</cfscript>
      </cffunction>
  