using concurrentusing afIocusing afIocConfig::Configusing afIocEnvusing afBedSheet** (Service) - Creates client-side asset URIs. constmixin ColdFeet {** Converts the given URI into a 'Cold Feet' URI. ** The URI **must** exist on the file system and be mapped by [BedSheet's]`http://www.fantomfactory.org/pods/afBedSheet`** 'FileHandler' service.abstract Uri assetUri(Uri uri) @NoDocabstract File? assetFile(File asset) @NoDocabstract Uri clientUri(Str checksum, Uri absUri)}internalconstclass ColdFeetImpl : ColdFeet { @Inject privateconst FileHandler fileHandler @Inject privateconst HttpRequest httpRequest @Inject privateconst ChecksumStrategy checksumStrategy @Config { id="afColdFeet.assetPrefix"} @Inject privateconst Uri assetPrefix new make(|This|in){ in(this)}override Uri assetUri(Uri uri){if(!uri.isPathOnly)throw ArgErr(ErrMsgs.assetUriMustBePathOnly(uri))if(!uri.isPathAbs)throw ArgErr(ErrMsgs.assetUriMustStartWithSlash(uri)) matchedUri := matchPrefix(fileHandler.directoryMappings.keys, uri.toStr)if(matchedUri == null)throw NotFoundErr(ErrMsgs.assetUriNotMapped(uri), fileHandler.directoryMappings.keys) remainingUri := uri.getRange(matchedUri.path.size..-1).relTo(`/`) file := fileHandler.directoryMappings[matchedUri].plus(remainingUri, false)if(!file.exists)throw ArgErr(ErrMsgs.assetUriDoesNotExist(uri, file)) checksum := checksumStrategy.checksum(file)return clientUri(checksum, uri)}override File? assetFile(File asset){throw Err("Not implemented")}override Uri clientUri(Str checksum, Uri absUri){// add extra WebMod paths - but only if we're part of a web request! clientUri := (Actor.locals["web.req"] != null && httpRequest.modBase != `/`) ? httpRequest.modBase : ``return clientUri.plusSlash + assetPrefix.relTo(`/`).plusSlash + checksum.toUri.plusSlash + absUri.relTo(`/`)}// TODO: Move to BedSheet::FileHandler** Returns the URI with the closest / deepest match.internalstatic Uri? matchPrefix(Uri[] keys, Str uri){ keys.findAll { uri.startsWith(it.toStr)}.sort |u1, u2 -> Int| { u1.toStr.size <=> u2.toStr.size }.last}}