1/** 2 * Copyright 2016 Google Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15*/ 16 17// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY! 18// This file should be overwritten as part of your build process. 19// If you need to extend the behavior of the generated service worker, the best approach is to write 20// additional code and include it using the importScripts option: 21// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring 22// 23// Alternatively, it's possible to make changes to the underlying template file and then use that as the 24// new base for generating output, via the templateFilePath option: 25// https://github.com/GoogleChrome/sw-precache#templatefilepath-string 26// 27// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any 28// changes made to this original template file with your modified copy. 29 30// This generated service worker JavaScript will precache your site's resources. 31// The code needs to be saved in a .js file at the top-level of your site, and registered 32// from your pages in order to be used. See 33// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js 34// for an example of how you can register this script and handle various service worker events. 35 36/* eslint-env worker, serviceworker */ 37/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */ 38'use strict'; 39 40var precacheConfig = [["assets/fonts/metropolis-bold-webfont-b8a2d0fcf6.woff2","b8a2d0fcf64b2b12fd7c66fd24f8c53b"],["assets/fonts/metropolis-bold-webfont-d74a1a7aaf.woff","d74a1a7aafc485d5a071dec00e5484fd"],["assets/fonts/metropolis-medium-webfont-e2609ec6c5.woff2","e2609ec6c58fe8f32886d56be57047c9"],["assets/fonts/metropolis-medium-webfont-e67a2ba8a4.woff","e67a2ba8a4471c4d74a9715abdd5a6da"],["assets/fonts/metropolis-semibold-webfont-9694394e90.woff2","9694394e90af699b99cfeedcbbc38f34"],["assets/fonts/metropolis-semibold-webfont-a73a34269f.woff","a
4073a34269f3338c51c6980e6b2666ece"],["assets/fonts/rakkas-regular-webfont-2748489b43.woff","2748489b431ac702502401d75cbf8970"],["assets/fonts/rakkas-regular-webfont-e41858088f.woff2","e41858088fe0e9ba7231af5bce2371d2"],["assets/images/conferences/davy-mourier-46c2e07bb7.jpg","46c2e07bb7a04539e5f23891bce8b5a0"],["assets/images/conferences/[email protected]","ac11d053963c9eff9b606d43ee3dd1ce"],["assets/images/conferences/nexus-vi-b5a03d6ea5.jpg","b5a03d6ea574f43116aa5d8c50382b26"],["assets/images/conferences/[email protected]","f184724f363a48cb138d8e87a27c52a5"],["assets/images/conferences/pacome-thiellement-faef1d2f67.jpg","faef1d2f67e36c8d15b6ff3a2beac6b9"],["assets/images/conferences/[email protected]","c2db9ff7a0b80391a434db9cd3765658"],["assets/images/conferences/rafik-djoumi-0bd770861c.jpg","0bd770861c1fab0ed53dfd61c4c1d17c"],["assets/images/conferences/[email protected]","bdc8126911aad0ec85ff91aa8c900850"],["assets/images/conferences/sebastien-guitton-f7931fa317.jpg","f7931fa317f99e22994b1f58ddc9bc3f"],["assets/images/conferences/[email protected]","71ecfe61baf30e6fc62cd9d1c92a3e67"],["assets/images/conferences/thomas-desenne-0f6825e109.jpg","0f6825e1094bbd445568eb7f49b07db7"],["assets/images/conferences/[email protected]","cc82752c5f70023a5aa60c6f685e6e83"],["assets/images/events/heuredujeu-936341ec36.jpg","936341ec36e1ea7837c90f44b1e52fc6"],["assets/images/events/[email protected]","0654790f6588c428209ec7eaf1fdeaba"],["assets/images/events/warpzone-1-ed0039349b.jpg","ed0039349b6ce6afb366ec33242f8c52"],["assets/images/events/[email protected]","a4127211a1dde76bdb052924103843cf"],["assets/images/events/warpzone-2-141ee44c7b.jpg","141ee44c7b0a5b8b06d2ccb7cc36a6c5"],["assets/images/events/[email protected]","51f5c9ee6fba63b9b2a3c9dd61d8c32a"],["assets/images/networks/apple-podcasts-582698a526.png","582698a526e14d4f22d0b64b711783d8"],["assets/images/networks/[email protected]","944ed2902bc430462c10362e2acfb066"],["assets/images/networks/canal-b-4dcf87e09b.png","4dcf87e09b8b4b5e414d8a822ead6beb"],["assets/images/networks/[email protected]","33db4cc5159f15e8e687042cbd3d80b3"],["assets/images/networks/deezer-564be7106e.png","564be7106e7a35350232717ca5726259"],["assets/images/networks/[email protected]","141975d2176ce7b40240086a7675def2"],["assets/images/networks/google-podcasts-175195a928.png","175195a92803e3696467aa3c44a4237b"],["assets/images/networks/[email protected]","a5dec967ae82f1d8e3ea386fa7bf49ff"],["assets/images/networks/podcloud-4a0cb8327c.png","4a0cb8327c49bbe37daf77db9c15320f"],["assets/images/networks/[email protected]","1478e05a342f506ddfc313b87069ec80"],["assets/images/networks/spotify-ac5f1de595.png","ac5f1de5958072d8bbb04e20b754c9f2"],["assets/images/networks/[email protected]","faa8302642bee9d7e9be30de4f03e44a"],["assets/images/partners/court-metrange-67fe2cab14.png","67fe2cab14c682668f8b8263ddab8712"],["assets/images/partners/[email protected]","ef44c7c1fb7e51b74c4c6cd4608ee487"],["assets/images/partners/heure-du-jeu-8edd0c20f2.png","8edd0c20f2011571c4a455d54a1a5fd9"],["assets/images/partners/[email protected]","7ca54ee6622c1de81b0dd55bbed18208"],["assets/images/partners/kifim-d3019bf8b2.png","d3019bf8b2e2dc20ed72428b6328d6f4"],["assets/images/partners/[email protected]","68155f97711d46e0681f9cc9d061d95f"],["assets/images/partners/magic-hall-e92dda558e.png","e92dda558eb962c0f41c12afbf596f42"],["assets/images/partners/[email protected]","6aabda7299fdb92a2949cde43c23f905"],["assets/images/partners/raptors-32721537fa.png","32721537fa680878a77663fb1d2f130d"],["assets/images/partners/[email protected]","a82c04468f1b481c3da948e15b5eb00b"],["assets/images/partners/rennes-2-fc54fedde9.png","fc54fedde97e882bf347bb679a3d432c"],["assets/images/partners/[email protected]","901f91eb95d0731eb34ad27e31f20649"],["assets/images/partners/saute-requin-ee2f0901f1.png","ee2f0901f1b4968023297ab5189c7a38"],["assets/images/partners/[email protected]","11a18ecb99e69482472492457888d118"],["assets/images/partners/syfantasy-cb46b6ec5f.png","cb46b6ec5f631feb2c848e181e9f02d0"],["assets/images/partners/[email protected]","2e95b14a6600eba68454e489ee0993cf"],["assets/images/partners/warpzone-b01e60c542.png","b01e60c542ab3aea532efb198134f7c7"],["assets/images/partners/[email protected]","1a9ef56ba96873d57a8ab9c70caf876d"],["assets/images/pictures/cafe-debat-1-4dfcb5f1be.jpg","4dfcb5f1be1cda1c30d080a64117f199"],["assets/images/pictures/cafe-debat-1-thumb-8eb1acad6f.jpg","8eb1acad6f1a9a1b8b4ee8678c3e48d2"],["assets/images/pictures/cafe-debat-2-05243ac8a7.jpg","05243ac8a7356bd90f64118e623ea98e"],["assets/images/pictures/cafe-debat-2-thumb-417cc8b8cb.jpg","417cc8b8cb89d60797034753136e5dba"],["assets/images/pictures/cafe-debat-3-23d79f334c.jpg","23d79f334c1781251877d54811796940"],["assets/images/pictures/cafe-debat-3-thumb-85459aaa58.jpg","85459aaa58e85fcd8b68fe7165454bee"],["assets/images/pictures/cafe-debat-4-cc2cc58cc5.jpg","cc2cc58cc531b80e24e66108efc86d5e"],["assets/images/pictures/cafe-debat-4-thumb-d3e66c9f34.jpg","d3e66c9f344ff4d385e7bd1b153d3350"],["assets/images/pictures/lets-play-1-2fb6ff43a6.jpg","2fb6ff43a68517bea735887c98fdfa10"],["assets/images/pictures/lets-play-1-thumb-d5256d081b.jpg","d5256d081b46733458d18f82b707ea1d"],["assets/images/pictures/lets-play-2-68415fb4d1.jpg","68415fb4d1e0d0d534b29a0f45f4283c"],["assets/images/pictures/lets-play-2-thumb-04156f7a0f.jpg","04156f7a0f9753047a0a85a529586d43"],["assets/images/pictures/quiz-heure-du-jeu-1-58bd7b25b7.jpg","58bd7b25b76dc00bbea35a575b68b8f7"],["assets/images/pictures/quiz-heure-du-jeu-1-thumb-a129876604.jpg","a12987660432a4f80f3a411ce4a2d2d1"],["assets/images/pictures/quiz-heure-du-jeu-2-9ecf8ecd06.jpg","9ecf8ecd0631f6d03e16a31f9148d68d"],["assets/images/pictures/quiz-heure-du-jeu-2-thumb-1ef0302852.jpg","1ef0302852ee2445fdbd8fcfb515acdf"],["assets/images/pictures/rafik-djoumi-1-6310a1559a.jpg","6310a1559acbfd698c770da3549c9f37"],["assets/images/pictures/rafik-djoumi-1-thumb-06255e1002.jpg","06255e10022d33e0015f910f8c6b4674"],["assets/images/pictures/rafik-djoumi-2-d4a7f1b49f.jpg","d4a7f1b49f8bb3d2955e105425abb2cb"],["assets/images/pictures/rafik-djoumi-2-thumb-e17ec5237b.jpg","e17ec5237b86d403169a9911f89a3f11"],["assets/images/pictures/rafik-djoumi-3-ba75d89db6.jpg","ba75d89db60e9573aec2a5b54297ecc0"],["assets/images/pictures/rafik-djoumi-3-thumb-0477d88a57.jpg","0477d88a57d1adf7fdf93a06c34ec8b3"],["assets/images/pictures/rafik-djoumi-4-2a7e0eade2.jpg","2a7e0eade23c901be8f019f497ee2318"],["assets/images/pictures/rafik-djoumi-4-thumb-370cc59471.jpg","370cc59471f57043c420e0431f7d413d"],["assets/images/pictures/retrospoilers-1-b0a7691b76.jpg","b0a7691b76a64e19e7d2dfc06ad52cc0"],["assets/images/pictures/retrospoilers-1-thumb-f07bbf0d3f.jpg","f07bbf0d3f8f56b21aacb139437f960d"],["assets/images/pictures/retrospoilers-2-b117d4d7b0.jpg","b117d4d7b0116984ea68f1b83dad9ac0"],["assets/images/pictures/retrospoilers-2-thumb-b2ee2c8b1a.jpg","b2ee2c8b1a8b9c7924d34311171f8528"],["assets/images/pictures/spoilist-1-7932ef90cf.jpg","7932ef90cf15f803cdf20ccdc6a641b6"],["assets/images/pictures/spoilist-1-thumb-5dd3ab491b.jpg","5dd3ab491bfb0cd160eca89f3f4e99ad"],["assets/images/pictures/spoilist-2-bf8280ec71.jpg","bf8280ec7167c577c2b8b15e4f4cd7a3"],["assets/images/pictures/spoilist-2-thumb-6eeba1bb78.jpg","6eeba1bb78af8cef4bf03c9ab4fad7fc"],["assets/images/pictures/spoilist-3-64cc77978e.jpg","64cc77978ebc0ec97d043be22aab5350"],["assets/images/pictures/spoilist-3-thumb-5f42d57581.jpg","5f42d575815790567744944bbacef467"],["assets/images/pictures/table-ronde-1-26c390d04a.jpg","26c390d04adbe55f028bc8e3f3f8de7d"],["assets/images/pictures/table-ronde-1-thumb-f01798424a.jpg","f01798424a8dad256910262e62119d44"],["assets/images/pictures/table-ronde-2-5c818afde1.jpg","5c818afde1fde115d2bf09e81d028b36"],["assets/images/pictures/table-ronde-2-thumb-0cca602b3f.jpg","0cca602b3f61903d1288fe9d0b56c530"],["assets/images/pictures/table-ronde-3-a390802c87.jpg","a390802c874ce924443d9cff16ae551b"],["assets/images/pictures/table-ronde-3-thumb-5d9bef6c0f.jpg","5d9bef6c0f8b911b0ec6ced7dae8673a"],["assets/images/pictures/video-fb-rafik-djoumi-thumb-19f83bfd51.jpg","19f83bfd51f30a1239d095b10ad6979f"],["assets/images/pictures/video-fb-table-ronde-thumb-804027360e.jpg","804027360e08af82f26a8a538a1c3274"],["assets/images/pictures/video-zr-rafik-djoumi-thumb-420bcdb5f1.jpg","420bcdb5f1190f406f2cbf23b4cb431d"],["assets/images/pictures/video-zr-table-ronde-thumb-88d3a3ca05.jpg","88d3a3ca05bccfcb52c6f884ecfe3638"],["assets/images/projections/buffy-vampire-slayer-2b81fee647.jpg","2b81fee647f8f7803836
40abd44719c408"],["assets/images/projections/[email protected]","807ef3a3cbabff491511717c65fce43c"],["assets/images/projections/calls-c60fb7b10f.jpg","c60fb7b10fa82f6e734bf24cb5cb23b7"],["assets/images/projections/[email protected]","a293c2cc104d60d88d1ebb6aec017073"],["assets/images/projections/la-petite-mort-d9cd1e1999.jpg","d9cd1e19992e12adf92aeec4525bf784"],["assets/images/projections/[email protected]","cd80e07d6421300036639bf3cb823601"],["assets/images/projections/reboot-7a90e78521.jpg","7a90e78521717a36c989a588241baca6"],["assets/images/projections/[email protected]","312b5875b04a9bccaf41550878e445d8"],["assets/images/projections/supa-supa-5c7df551a0.jpg","5c7df551a05a0e7bd5e1ddd1470a0681"],["assets/images/projections/[email protected]","4e34833c4c73723cfae1b7fbb9846b8e"],["assets/images/projections/zone-42-d344233b57.jpg","d344233b57cb87b0b49f43a6d26eb077"],["assets/images/projections/[email protected]","8d2341e64321ae630033a43e845b47ac"],["assets/images/slides/d1-buffy-9a3305a8c8.jpg","9a3305a8c8112bcc3dffd64c988fb8ce"],["assets/images/slides/d1-rafik-djoumi-d3777eda1d.jpg","d3777eda1da17fdee7f22b8628eae863"],["assets/images/slides/d2-spoilist-735384ba4f.jpg","735384ba4f6c934a2f1e4b9e64028d80"],["assets/images/slides/d2-table-ronde-599e9f15ff.jpg","599e9f15ff83e49b0c44948a595a31d7"],["assets/images/slides/hj-quiz-1-25bfb56276.jpg","25bfb5627683199ae66213cefa755714"],["assets/images/slides/hj-quiz-2-321d21041a.jpg","321d21041a9a9835e9eea563e787231b"],["assets/images/slides/wz-cafe-debat-e9fa0025d3.jpg","e9fa0025d3e363e6f02a3f9a7cf75955"],["assets/images/slides/wz-lets-play-8ec39ca2d2.jpg","8ec39ca2d25051066d15280beac173b9"],["assets/images/spoilers-7ad75f6b12.jpg","7ad75f6b12d14c37def6c83454c2446f"],["assets/scripts/main-d159d3a416.js","d159d3a41673b042e4793469b157e513"],["assets/styles/main-bc61db73f1.css","bc61db73f1c4d92bf19ced6710a206f8"],["google9e393335c9263734.html","38050ee6a5c7f130299f99957c7f4c86"],["index.html","63311ab92e8d2cdd2ce035da800fc11a"]]; 41var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : ''); 42 43 44var ignoreUrlParametersMatching = [/^utm_/]; 45 46 47 48var addDirectoryIndex = function(originalUrl, index) { 49 var url = new URL(originalUrl); 50 if (url.pathname.slice(-1) === '/') { 51 url.pathname += index; 52 } 53 return url.toString(); 54 }; 55 56var cleanResponse = function(originalResponse) { 57 // If this is not a redirected response, then we don't have to do anything. 58 if (!originalResponse.redirected) { 59 return Promise.resolve(originalResponse); 60 } 61 62 // Firefox 50 and below doesn't support the Response.body stream, so we may 63 // need to read the entire body to memory as a Blob. 64 var bodyPromise = 'body' in originalResponse ? 65 Promise.resolve(originalResponse.body) : 66 originalResponse.blob(); 67 68 return bodyPromise.then(function(body) { 69 // new Response() is happy when passed either a stream or a Blob. 70 return new Response(body, { 71 headers: originalResponse.headers, 72 status: originalResponse.status, 73 statusText: originalResponse.statusText 74 }); 75 }); 76 }; 77 78var createCacheKey = function(originalUrl, paramName, paramValue, 79 dontCacheBustUrlsMatching) { 80 // Create a new URL object to avoid modifying originalUrl. 81 var url = new URL(originalUrl); 82 83 // If dontCacheBustUrlsMatching is not set, or if we don't have a match, 84 // then add in the extra cache-busting URL parameter. 85 if (!dontCacheBustUrlsMatching || 86 !(url.pathname.match(dontCacheBustUrlsMatching))) { 87 url.search += (url.search ? '&' : '') + 88 encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue); 89 } 90 91 return url.toString(); 92 }; 93 94var isPathWhitelisted = function(whitelist, absoluteUrlString) { 95 // If the whitelist is empty, then consider all URLs to be whitelisted. 96 if (whitelist.length === 0) { 97 return true; 98 } 99 100 // Otherwise compare each path regex to the path of the URL passed in. 101 var path = (new URL(absoluteUrlString)).pathname; 102 return whitelist.some(function(whitelistedPathRegex) { 103 return path.match(whitelistedPathRegex); 104 }); 105 }; 106 107var stripIgnoredUrlParameters = function(originalUrl, 108 ignoreUrlParametersMatching) { 109 var url = new URL(originalUrl); 110 // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290 111 url.hash = ''; 112 113 url.search = url.search.slice(1) // Exclude initial '?' 114 .split('&') // Split into an array of 'key=value' strings 115 .map(function(kv) { 116 return kv.split('='); // Split each 'key=value' string into a [key, value] array 117 }) 118 .filter(function(kv) { 119 return ignoreUrlParametersMatching.every(function(ignoredRegex) { 120 return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes. 121 }); 122 }) 123 .map(function(kv) { 124 return kv.join('='); // Join each [key, value] array into a 'key=value' string 125 }) 126 .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each 127 128 return url.toString(); 129 }; 130 131 132var hashParamName = '_sw-precache'; 133var urlsToCacheKeys = new Map( 134 precacheConfig.map(function(item) { 135 var relativeUrl = item[0]; 136 var hash = item[1]; 137 var absoluteUrl = new URL(relativeUrl, self.location); 138 var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, /\-[A-Fa-f0-9]{10}\./); 139 return [absoluteUrl.toString(), cacheKey]; 140 }) 141); 142 143function setOfCachedUrls(cache) { 144 return cache.keys().then(function(requests) { 145 return requests.map(function(request) { 146 return request.url; 147 }); 148 }).then(function(urls) { 149 return new Set(urls); 150 }); 151} 152 153self.addEventListener('install', function(event) { 154 event.waitUntil( 155 caches.open(cacheName).then(function(cache) { 156 return setOfCachedUrls(cache).then(function(cachedUrls) { 157 return Promise.all( 158 Array.from(urlsToCacheKeys.values()).map(function(cacheKey) { 159 // If we don't have a key matching url in the cache already, add it. 160 if (!cachedUrls.has(cacheKey)) {
161 var request = new Request(cacheKey, {credentials: 'same-origin'}); 162 return fetch(request).then(function(response) { 163 // Bail out of installation unless we get back a 200 OK for 164 // every request. 165 if (!response.ok) { 166 throw new Error('Request for ' + cacheKey + ' returned a ' + 167 'response with status ' + response.status); 168 } 169 170 return cleanResponse(response).then(function(responseToCache) { 171 return cache.put(cacheKey, responseToCache); 172 }); 173 }); 174 } 175 }) 176 ); 177 }); 178 }).then(function() { 179 180 // Force the SW to transition from installing -> active state 181 return self.skipWaiting(); 182 183 }) 184 ); 185}); 186 187self.addEventListener('activate', function(event) { 188 var setOfExpectedUrls = new Set(urlsToCacheKeys.values()); 189 190 event.waitUntil( 191 caches.open(cacheName).then(function(cache) { 192 return cache.keys().then(function(existingRequests) { 193 return Promise.all( 194 existingRequests.map(function(existingRequest) { 195 if (!setOfExpectedUrls.has(existingRequest.url)) { 196 return cache.delete(existingRequest); 197 } 198 }) 199 ); 200 }); 201 }).then(function() { 202 203 return self.clients.claim(); 204 205 }) 206 ); 207}); 208 209 210self.addEventListener('fetch', function(event) { 211 if (event.request.method === 'GET') { 212 // Should we call event.respondWith() inside this fetch event handler? 213 // This needs to be determined synchronously, which will give other fetch 214 // handlers a chance to handle the request if need be. 215 var shouldRespond; 216 217 // First, remove all the ignored parameters and hash fragment, and see if we 218 // have that URL in our cache. If so, great! shouldRespond will be true. 219 var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching); 220 shouldRespond = urlsToCacheKeys.has(url); 221 222 // If shouldRespond is false, check again, this time with 'index.html' 223 // (or whatever the directoryIndex option is set to) at the end. 224 var directoryIndex = 'index.html'; 225 if (!shouldRespond && directoryIndex) { 226 url = addDirectoryIndex(url, directoryIndex); 227 shouldRespond = urlsToCacheKeys.has(url); 228 } 229 230 // If shouldRespond is still false, check to see if this is a navigation 231 // request, and if so, whether the URL matches navigateFallbackWhitelist. 232 var navigateFallback = ''; 233 if (!shouldRespond && 234 navigateFallback && 235 (event.request.mode === 'navigate') && 236 isPathWhitelisted([], event.request.url)) { 237 url = new URL(navigateFallback, self.location).toString(); 238 shouldRespond = urlsToCacheKeys.has(url); 239 } 240 241 // If shouldRespond was set to true at any point, then call 242 // event.respondWith(), using the appropriate cache key. 243 if (shouldRespond) { 244 event.respondWith( 245 caches.open(cacheName).then(function(cache) { 246 return cache.match(urlsToCacheKeys.get(url)).then(function(response) { 247 if (response) { 248 return response; 249 } 250 throw Error('The cached response that was expected is missing.'); 251 }); 252 }).catch(function(e) { 253 // Fall back to just fetch()ing the request if some unexpected error 254 // prevented the cached response from being valid. 255 console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e); 256 return fetch(event.request); 257 }) 258 ); 259 } 260 } 261}); 262 263 264 265 266 267 268
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.