whole_func_string: function register(ports, log) {
    // Mapped to Storage API: https://developer.mozilla.org/en-US/docs/Web/API/Storage
    ports.storageGetItem.subscribe(storageGetItem);
    ports.storageSetItem.subscribe(storageSetItem);
    ports.storageRemoveItem.subscribe(storageRemoveItem);
    ports.storageClear.subscribe(storageClear);
  
    // Not in Storage API
    ports.storagePushToSet.subscribe(storagePushToSet);
    ports.storageRemoveFromSet.subscribe(storageRemoveFromSet);
  
    // StorageEvent API
    storageEventListenerPorts.push(ports);
  
    log = log || function() {};
  
    function storageGetItem(key) {
      log('storageGetItem', key);
      const response = getLocalStorageItem(key);
  
      log('storageGetItemResponse', key, response);
      ports.storageGetItemResponse.send([key, response]);
    }
  
    function storageSetItem([key, value]) {
      log('storageSetItem', key, value);
      setLocalStorageItem(key, value);
    }
  
    function storageRemoveItem(key) {
      log('storageRemoveItem', key);
      window.localStorage.removeItem(key);
    }
  
    function storageClear() {
      log('storageClear');
      window.localStorage.clear();
    }
  
    // A Set is a list with only unique values. (No duplication.)
    function storagePushToSet([key, value]) {
      log('storagePushToSet', key, value);
  
      const item = getLocalStorageItem(key);
      const list = Array.isArray(item) ? item : [];
  
      if (list.indexOf(value) === -1) {
        list.push(value);
      }
  
      setLocalStorageItem(key, list);
    }
  
    function storageRemoveFromSet([key, value]) {
      log('storageRemoveFromSet', key, value);
  
      const list = getLocalStorageItem(key);
  
      if (!Array.isArray(list)) {
        log('storageRemoveFromSet [aborting; not a list]', key, value, list);
        return;
      }
  
      // Filter based on JSON strings in to ensure equality-by-value instead of equality-by-reference
      const jsonValue = JSON.stringify(value);
      const updatedSet = list.filter(item => jsonValue !== JSON.stringify(item));
  
      setLocalStorageItem(key, updatedSet);
    }
  }
func_code_string: function register(ports, log) {
    // Mapped to Storage API: https://developer.mozilla.org/en-US/docs/Web/API/Storage
    ports.storageGetItem.subscribe(storageGetItem);
    ports.storageSetItem.subscribe(storageSetItem);
    ports.storageRemoveItem.subscribe(storageRemoveItem);
    ports.storageClear.subscribe(storageClear);
  
    // Not in Storage API
    ports.storagePushToSet.subscribe(storagePushToSet);
    ports.storageRemoveFromSet.subscribe(storageRemoveFromSet);
  
    // StorageEvent API
    storageEventListenerPorts.push(ports);
  
    log = log || function() {};
  
    function storageGetItem(key) {
      log('storageGetItem', key);
      const response = getLocalStorageItem(key);
  
      log('storageGetItemResponse', key, response);
      ports.storageGetItemResponse.send([key, response]);
    }
  
    function storageSetItem([key, value]) {
      log('storageSetItem', key, value);
      setLocalStorageItem(key, value);
    }
  
    function storageRemoveItem(key) {
      log('storageRemoveItem', key);
      window.localStorage.removeItem(key);
    }
  
    function storageClear() {
      log('storageClear');
      window.localStorage.clear();
    }
  
    // A Set is a list with only unique values. (No duplication.)
    function storagePushToSet([key, value]) {
      log('storagePushToSet', key, value);
  
      const item = getLocalStorageItem(key);
      const list = Array.isArray(item) ? item : [];
  
      if (list.indexOf(value) === -1) {
        list.push(value);
      }
  
      setLocalStorageItem(key, list);
    }
  
    function storageRemoveFromSet([key, value]) {
      log('storageRemoveFromSet', key, value);
  
      const list = getLocalStorageItem(key);
  
      if (!Array.isArray(list)) {
        log('storageRemoveFromSet [aborting; not a list]', key, value, list);
        return;
      }
  
      // Filter based on JSON strings in to ensure equality-by-value instead of equality-by-reference
      const jsonValue = JSON.stringify(value);
      const updatedSet = list.filter(item => jsonValue !== JSON.stringify(item));
  
      setLocalStorageItem(key, updatedSet);
    }
  }
func_documentation_string: Subscribe the given Elm app ports to ports from the Elm LocalStorage ports module.
  
  @param  {Object}   ports  Ports object from an Elm app
  @param  {Function} log    Function to log ports for the given Elm app