'use strict';

const datoramaAkita = require('./datorama-akita-bb801820.js');
const Option = require('./Option-98dab0b8.js');
const index = require('./index-4f00f593.js');
const apiClient = require('./api-client-00edc9b6.js');
const promise = require('./promise-f77cab90.js');
const benefits_api = require('./benefits.api-a4bd9804.js');
const index$1 = require('./index-889ce6c6.js');

/**
 * TS adaption of https://github.com/pillarjs/path-to-regexp/blob/master/index.js
 */
/**
 * Default configs.
 */
const DEFAULT_DELIMITER = '/';
const DEFAULT_DELIMITERS = './';
/**
 * The main path matching regexp utility.
 */
const PATH_REGEXP = new RegExp([
    // Match escaped characters that would otherwise appear in future matches.
    // This allows the user to escape special characters that won't transform.
    '(\\\\.)',
    // Match Express-style parameters and un-named parameters with a prefix
    // and optional suffixes. Matches appear as:
    //
    // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?"]
    // "/route(\\d+)"  => [undefined, undefined, undefined, "\d+", undefined]
    '(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?'
].join('|'), 'g');
/**
 * Parse a string for the raw tokens.
 */
const parse = (str, options) => {
    var tokens = [];
    var key = 0;
    var index = 0;
    var path = '';
    var defaultDelimiter = (options && options.delimiter) || DEFAULT_DELIMITER;
    var delimiters = (options && options.delimiters) || DEFAULT_DELIMITERS;
    var pathEscaped = false;
    var res;
    while ((res = PATH_REGEXP.exec(str)) !== null) {
        var m = res[0];
        var escaped = res[1];
        var offset = res.index;
        path += str.slice(index, offset);
        index = offset + m.length;
        // Ignore already escaped sequences.
        if (escaped) {
            path += escaped[1];
            pathEscaped = true;
            continue;
        }
        var prev = '';
        var next = str[index];
        var name = res[2];
        var capture = res[3];
        var group = res[4];
        var modifier = res[5];
        if (!pathEscaped && path.length) {
            var k = path.length - 1;
            if (delimiters.indexOf(path[k]) > -1) {
                prev = path[k];
                path = path.slice(0, k);
            }
        }
        // Push the current path onto the tokens.
        if (path) {
            tokens.push(path);
            path = '';
            pathEscaped = false;
        }
        var partial = prev !== '' && next !== undefined && next !== prev;
        var repeat = modifier === '+' || modifier === '*';
        var optional = modifier === '?' || modifier === '*';
        var delimiter = prev || defaultDelimiter;
        var pattern = capture || group;
        tokens.push({
            name: name || key++,
            prefix: prev,
            delimiter: delimiter,
            optional: optional,
            repeat: repeat,
            partial: partial,
            pattern: pattern ? escapeGroup(pattern) : '[^' + escapeString(delimiter) + ']+?'
        });
    }
    // Push any remaining characters.
    if (path || index < str.length) {
        tokens.push(path + str.substr(index));
    }
    return tokens;
};
/**
 * Escape a regular expression string.
 */
const escapeString = (str) => {
    return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, '\\$1');
};
/**
 * Escape the capturing group by escaping special characters and meaning.
 */
const escapeGroup = (group) => {
    return group.replace(/([=!:$/()])/g, '\\$1');
};
/**
 * Get the flags for a regexp from the options.
 */
const flags = (options) => {
    return options && options.sensitive ? '' : 'i';
};
/**
 * Pull out keys from a regexp.
 */
const regexpToRegexp = (path, keys) => {
    if (!keys)
        return path;
    // Use a negative lookahead to match only capturing groups.
    var groups = path.source.match(/\((?!\?)/g);
    if (groups) {
        for (var i = 0; i < groups.length; i++) {
            keys.push({
                name: i,
                prefix: null,
                delimiter: null,
                optional: false,
                repeat: false,
                partial: false,
                pattern: null
            });
        }
    }
    return path;
};
/**
 * Transform an array into a regexp.
 */
const arrayToRegexp = (path, keys, options) => {
    var parts = [];
    for (var i = 0; i < path.length; i++) {
        parts.push(pathToRegexp(path[i], keys, options).source);
    }
    return new RegExp('(?:' + parts.join('|') + ')', flags(options));
};
/**
 * Create a path regexp from string input.
 */
const stringToRegexp = (path, keys, options) => {
    return tokensToRegExp(parse(path, options), keys, options);
};
/**
 * Expose a function for taking tokens and returning a RegExp.
 */
const tokensToRegExp = (tokens, keys, options) => {
    options = options || {};
    var strict = options.strict;
    var end = options.end !== false;
    var delimiter = escapeString(options.delimiter || DEFAULT_DELIMITER);
    var delimiters = options.delimiters || DEFAULT_DELIMITERS;
    var endsWith = [].concat(options.endsWith || []).map(escapeString).concat('$').join('|');
    var route = '';
    var isEndDelimited = false;
    // Iterate over the tokens and create our regexp string.
    for (var i = 0; i < tokens.length; i++) {
        var token = tokens[i];
        if (typeof token === 'string') {
            route += escapeString(token);
            isEndDelimited = i === tokens.length - 1 && delimiters.indexOf(token[token.length - 1]) > -1;
        }
        else {
            var prefix = escapeString(token.prefix || '');
            var capture = token.repeat
                ? '(?:' + token.pattern + ')(?:' + prefix + '(?:' + token.pattern + '))*'
                : token.pattern;
            if (keys)
                keys.push(token);
            if (token.optional) {
                if (token.partial) {
                    route += prefix + '(' + capture + ')?';
                }
                else {
                    route += '(?:' + prefix + '(' + capture + '))?';
                }
            }
            else {
                route += prefix + '(' + capture + ')';
            }
        }
    }
    if (end) {
        if (!strict)
            route += '(?:' + delimiter + ')?';
        route += endsWith === '$' ? '$' : '(?=' + endsWith + ')';
    }
    else {
        if (!strict)
            route += '(?:' + delimiter + '(?=' + endsWith + '))?';
        if (!isEndDelimited)
            route += '(?=' + delimiter + '|' + endsWith + ')';
    }
    return new RegExp('^' + route, flags(options));
};
/**
 * Normalize the given path string, returning a regular expression.
 *
 * An empty array can be passed in for the keys, which will hold the
 * placeholder key descriptions. For example, using `/user/:id`, `keys` will
 * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
 */
const pathToRegexp = (path, keys, options) => {
    if (path instanceof RegExp) {
        return regexpToRegexp(path, keys);
    }
    if (Array.isArray(path)) {
        return arrayToRegexp(path, keys, options);
    }
    return stringToRegexp(path, keys, options);
};

const hasBasename = (path, prefix) => {
    return (new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i')).test(path);
};
const stripBasename = (path, prefix) => {
    return hasBasename(path, prefix) ? path.substr(prefix.length) : path;
};
const stripTrailingSlash = (path) => {
    return path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path;
};
const addLeadingSlash = (path) => {
    return path.charAt(0) === '/' ? path : '/' + path;
};
const stripLeadingSlash = (path) => {
    return path.charAt(0) === '/' ? path.substr(1) : path;
};
const parsePath = (path) => {
    let pathname = path || '/';
    let search = '';
    let hash = '';
    const hashIndex = pathname.indexOf('#');
    if (hashIndex !== -1) {
        hash = pathname.substr(hashIndex);
        pathname = pathname.substr(0, hashIndex);
    }
    const searchIndex = pathname.indexOf('?');
    if (searchIndex !== -1) {
        search = pathname.substr(searchIndex);
        pathname = pathname.substr(0, searchIndex);
    }
    return {
        pathname,
        search: search === '?' ? '' : search,
        hash: hash === '#' ? '' : hash,
        query: {},
        key: ''
    };
};
const createPath = (location) => {
    const { pathname, search, hash } = location;
    let path = pathname || '/';
    if (search && search !== '?') {
        path += (search.charAt(0) === '?' ? search : `?${search}`);
    }
    if (hash && hash !== '#') {
        path += (hash.charAt(0) === '#' ? hash : `#${hash}`);
    }
    return path;
};
const parseQueryString = (query) => {
    if (!query) {
        return {};
    }
    return (/^[?#]/.test(query) ? query.slice(1) : query)
        .split('&')
        .reduce((params, param) => {
        let [key, value] = param.split('=');
        params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
        return params;
    }, {});
};

const isAbsolute = (pathname) => {
    return pathname.charAt(0) === '/';
};
const createKey = (keyLength) => {
    return Math.random().toString(36).substr(2, keyLength);
};
// About 1.5x faster than the two-arg version of Array#splice()
const spliceOne = (list, index) => {
    for (let i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) {
        list[i] = list[k];
    }
    list.pop();
};
// This implementation is based heavily on node's url.parse
const resolvePathname = (to, from = '') => {
    let fromParts = from && from.split('/') || [];
    let hasTrailingSlash;
    let up = 0;
    const toParts = to && to.split('/') || [];
    const isToAbs = to && isAbsolute(to);
    const isFromAbs = from && isAbsolute(from);
    const mustEndAbs = isToAbs || isFromAbs;
    if (to && isAbsolute(to)) {
        // to is absolute
        fromParts = toParts;
    }
    else if (toParts.length) {
        // to is relative, drop the filename
        fromParts.pop();
        fromParts = fromParts.concat(toParts);
    }
    if (!fromParts.length) {
        return '/';
    }
    if (fromParts.length) {
        const last = fromParts[fromParts.length - 1];
        hasTrailingSlash = (last === '.' || last === '..' || last === '');
    }
    else {
        hasTrailingSlash = false;
    }
    for (let i = fromParts.length; i >= 0; i--) {
        const part = fromParts[i];
        if (part === '.') {
            spliceOne(fromParts, i);
        }
        else if (part === '..') {
            spliceOne(fromParts, i);
            up++;
        }
        else if (up) {
            spliceOne(fromParts, i);
            up--;
        }
    }
    if (!mustEndAbs) {
        for (; up--; up) {
            fromParts.unshift('..');
        }
    }
    if (mustEndAbs && fromParts[0] !== '' && (!fromParts[0] || !isAbsolute(fromParts[0]))) {
        fromParts.unshift('');
    }
    let result = fromParts.join('/');
    if (hasTrailingSlash && result.substr(-1) !== '/') {
        result += '/';
    }
    return result;
};
const valueEqual = (a, b) => {
    if (a === b) {
        return true;
    }
    if (a == null || b == null) {
        return false;
    }
    if (Array.isArray(a)) {
        return Array.isArray(b) && a.length === b.length && a.every((item, index) => {
            return valueEqual(item, b[index]);
        });
    }
    const aType = typeof a;
    const bType = typeof b;
    if (aType !== bType) {
        return false;
    }
    if (aType === 'object') {
        const aValue = a.valueOf();
        const bValue = b.valueOf();
        if (aValue !== a || bValue !== b) {
            return valueEqual(aValue, bValue);
        }
        const aKeys = Object.keys(a);
        const bKeys = Object.keys(b);
        if (aKeys.length !== bKeys.length) {
            return false;
        }
        return aKeys.every((key) => {
            return valueEqual(a[key], b[key]);
        });
    }
    return false;
};
const locationsAreEqual = (a, b) => {
    return a.pathname === b.pathname &&
        a.search === b.search &&
        a.hash === b.hash &&
        a.key === b.key &&
        valueEqual(a.state, b.state);
};
const createLocation = (path, state, key, currentLocation) => {
    let location;
    if (typeof path === 'string') {
        // Two-arg form: push(path, state)
        location = parsePath(path);
        if (state !== undefined) {
            location.state = state;
        }
    }
    else {
        // One-arg form: push(location)
        location = Object.assign({ pathname: '' }, path);
        if (location.search && location.search.charAt(0) !== '?') {
            location.search = '?' + location.search;
        }
        if (location.hash && location.hash.charAt(0) !== '#') {
            location.hash = '#' + location.hash;
        }
        if (state !== undefined && location.state === undefined) {
            location.state = state;
        }
    }
    try {
        location.pathname = decodeURI(location.pathname);
    }
    catch (e) {
        if (e instanceof URIError) {
            throw new URIError('Pathname "' + location.pathname + '" could not be decoded. ' +
                'This is likely caused by an invalid percent-encoding.');
        }
        else {
            throw e;
        }
    }
    location.key = key;
    if (currentLocation) {
        // Resolve incomplete/relative pathname relative to current location.
        if (!location.pathname) {
            location.pathname = currentLocation.pathname;
        }
        else if (location.pathname.charAt(0) !== '/') {
            location.pathname = resolvePathname(location.pathname, currentLocation.pathname);
        }
    }
    else {
        // When there is no prior location and pathname is empty, set it to /
        if (!location.pathname) {
            location.pathname = '/';
        }
    }
    location.query = parseQueryString(location.search || '');
    return location;
};

let cacheCount = 0;
const patternCache = {};
const cacheLimit = 10000;
// Memoized function for creating the path match regex
const compilePath = (pattern, options) => {
    const cacheKey = `${options.end}${options.strict}`;
    const cache = patternCache[cacheKey] || (patternCache[cacheKey] = {});
    const cachePattern = JSON.stringify(pattern);
    if (cache[cachePattern]) {
        return cache[cachePattern];
    }
    const keys = [];
    const re = pathToRegexp(pattern, keys, options);
    const compiledPattern = { re, keys };
    if (cacheCount < cacheLimit) {
        cache[cachePattern] = compiledPattern;
        cacheCount += 1;
    }
    return compiledPattern;
};
/**
 * Public API for matching a URL pathname to a path pattern.
 */
const matchPath = (pathname, options = {}) => {
    if (typeof options === 'string') {
        options = { path: options };
    }
    const { path = '/', exact = false, strict = false } = options;
    const { re, keys } = compilePath(path, { end: exact, strict });
    const match = re.exec(pathname);
    if (!match) {
        return null;
    }
    const [url, ...values] = match;
    const isExact = pathname === url;
    if (exact && !isExact) {
        return null;
    }
    return {
        path,
        url: path === '/' && url === '' ? '/' : url,
        isExact,
        params: keys.reduce((memo, key, index) => {
            memo[key.name] = values[index];
            return memo;
        }, {})
    };
};
const matchesAreEqual = (a, b) => {
    if (a == null && b == null) {
        return true;
    }
    if (b == null) {
        return false;
    }
    return a && b &&
        a.path === b.path &&
        a.url === b.url &&
        valueEqual(a.params, b.params);
};

var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const BenefitCategories = [
  'Appliances & Electronics',
  'Automotive',
  'Banking',
  'Clothing & Footwear',
  'Clubs',
  'Entertainment',
  'Food, Drink & Groceries',
  'Fuel',
  'Health, Beauty & Fitness',
  'Homeware & Hardware',
  'Learning',
  'Pets',
  'Shopping & Retail',
  'Social',
  'Sports & Leisure',
  'Technology',
  'Travel & Accommodation',
  'Wellbeing & Health Services',
  'Other',
  'None'
];
function createInitialState() {
  return {
    manageBenefitsPageState: {
      enabledBenefits: [],
      disabledBenefits: []
    },
    selectedBenefit: index.none,
    draftBenefit: index.none
  };
}
let ManageBenefitsStore = class ManageBenefitsStore extends datoramaAkita.Store {
  constructor() {
    super(createInitialState());
  }
};
ManageBenefitsStore = __decorate([
  datoramaAkita.StoreConfig({ name: 'manage-benefits', resettable: true, producerFn: apiClient.fn })
], ManageBenefitsStore);
const manageBenefitsStore = new ManageBenefitsStore();

class ManageBenefitsQuery$1 extends datoramaAkita.Query {
  constructor(store) {
    super(store);
    this.store = store;
    this.managedBenefits$ = this.select((state) => state.manageBenefitsPageState);
    this.selectedBenefit$ = this.select((state) => state.selectedBenefit);
    this.draftBenefit$ = this.select((state) => state.draftBenefit);
    this.draftBenefitUrl$ = this.select((state) => Option._function.pipe(state.draftBenefit, index.chain((draft) => draft.url)));
    this.draftBenefitIcon$ = this.select((state) => Option._function.pipe(state.draftBenefit, index.chain((draft) => draft.icon)));
    this.draftBenefitAttachment$ = this.select((state) => Option._function.pipe(state.draftBenefit, index.chain((draft) => draft.attachment)));
    this.isLoading$ = this.selectLoading();
  }
}
const editBenefitQuery = new ManageBenefitsQuery$1(manageBenefitsStore);

class BenefitItemDto {
  static fromDraftBenefit(draft) {
    return {
      title: index$1.getOrError(draft.title),
      subtitle: index$1.getOrError(draft.subtitle),
      category: index$1.getOrError(draft.category),
      description: index.toNullable(draft.description),
      url: index.toNullable(draft.url),
      attachments: index.fold(() => [], (value) => [value])(draft.attachment),
      icon: index.toNullable(draft.icon),
      backdrop: null
    };
  }
}

class ManageBenefitsApi {
  async getPageStateAsync() {
    return apiClient.BackendApiClient.instance.url(`benefits/ui/manage-page`).get().json();
  }
  async loadBenefitForEditingAsync(benefitId) {
    return apiClient.BackendApiClient.instance.url(`benefits/edit/${benefitId}`).get().json();
  }
  async postCommandAsync(benefitId, commandDto) {
    const request = {
      command: commandDto
    };
    return apiClient.BackendApiClient.instance
      .url(`benefits/edit/${index.getOrElse(() => '')(benefitId)}`)
      .post(request)
      .badRequest(() => {
      throw new Error('Failed to execute benefit command');
    })
      .text();
  }
}
const manageBenefitsApi = new ManageBenefitsApi();

class AccountBenefitWithIdDto {
  static toCustomBenefitsListEntry(dto) {
    return {
      id: dto.benefitId,
      title: dto.benefit.title,
      category: dto.benefit.category,
      lastModifiedDate: index.some(dto.metadata.updatedAt),
      visibility: dto.visibility
    };
  }
  static toBenefit(dto) {
    const firstAttachment = dto.benefit.attachments !== null && dto.benefit.attachments.length > 0
      ? index.some(dto.benefit.attachments[0])
      : index.none;
    return {
      id: index$1.assertSome(dto.benefitId),
      title: index$1.assertSome(dto.benefit.title),
      subtitle: index$1.assertSome(dto.benefit.subtitle),
      category: index$1.assertSome(dto.benefit.category),
      description: index.fromNullable(dto.benefit.description),
      url: index.fromNullable(dto.benefit.url),
      attachment: firstAttachment,
      icon: index.fromNullable(dto.benefit.icon)
    };
  }
}
class ManageBenefitsPageStateDto {
  static toDomain(dto) {
    return {
      enabledBenefits: dto.activeAccountBenefits.map(AccountBenefitWithIdDto.toCustomBenefitsListEntry),
      disabledBenefits: dto.inactiveAccountBenefits.map(AccountBenefitWithIdDto.toCustomBenefitsListEntry)
    };
  }
}

class ManageBenefitsQuery extends datoramaAkita.Query {
  constructor(store) {
    super(store);
    this.store = store;
    this.manageBenefitsPageState$ = this.select((state) => state.manageBenefitsPageState);
    this.isLoading$ = this.selectLoading();
  }
}
const manageBenefitsQuery = new ManageBenefitsQuery(manageBenefitsStore);

class EditBenefitService {
  async loadExistingBenefitForEditingAsync(benefitId) {
    manageBenefitsStore.update((state) => {
      state.selectedBenefit = index.none;
    });
    manageBenefitsStore.setLoading(true);
    const existingBenefit = AccountBenefitWithIdDto.toBenefit(await manageBenefitsApi.loadBenefitForEditingAsync(benefitId));
    manageBenefitsStore.update((state) => {
      state.selectedBenefit = index.some(existingBenefit);
      state.draftBenefit = index.some(this.existingBenefitToDraft(existingBenefit));
    });
    manageBenefitsStore.setLoading(false);
  }
  createDraftBenefit() {
    const newDraft = {
      title: index.none,
      category: index.none,
      subtitle: index.none,
      description: index.none,
      url: index.none,
      attachment: index.none,
      icon: index.none,
      isValid: false,
      isDirty: false
    };
    manageBenefitsStore.update((state) => {
      state.selectedBenefit = index.none;
      state.draftBenefit = index.some(newDraft);
    });
  }
  clearDraftBenefit() {
    manageBenefitsStore.update((state) => {
      state.draftBenefit = index.none;
    });
  }
  updateDraftBenefit(newDraft) {
    manageBenefitsStore.update((state) => {
      state.draftBenefit = index.some(newDraft);
    });
  }
  async publishDraftBenefitAsync() {
    const draftBenefit = manageBenefitsQuery.getValue().draftBenefit;
    if (index.isNone(draftBenefit)) {
      return;
    }
    this.assertDraftIsValid(draftBenefit.value);
    manageBenefitsStore.setLoading(true);
    const selectedBenefit = manageBenefitsQuery.getValue().selectedBenefit;
    if (index.isSome(selectedBenefit)) {
      const updateBenefitCommandDto = {
        updateAccountBenefit: BenefitItemDto.fromDraftBenefit(draftBenefit.value)
      };
      await manageBenefitsApi.postCommandAsync(selectedBenefit.value.id, updateBenefitCommandDto);
    }
    else {
      const createBenefitCommmandDto = {
        createAccountBenefit: BenefitItemDto.fromDraftBenefit(draftBenefit.value)
      };
      await manageBenefitsApi.postCommandAsync(index.none, createBenefitCommmandDto);
    }
    manageBenefitsStore.setLoading(false);
  }
  async deleteSelectedBenefitAsync() {
    const selectedBenefit = manageBenefitsQuery.getValue().selectedBenefit;
    if (index.isSome(selectedBenefit)) {
      manageBenefitsStore.setLoading(true);
      await manageBenefitsApi.postCommandAsync(selectedBenefit.value.id, 'deleteAccountBenefit');
      manageBenefitsStore.setLoading(false);
    }
  }
  updateDraftUrl(url) {
    this.updateDraft((draft) => {
      draft.url = index.fromNullable(url);
      draft.isDirty = true;
    });
  }
  clearDraftUrl() {
    this.updateDraft((draft) => {
      draft.url = index.none;
      draft.isDirty = true;
    });
  }
  async uploadAttachmentAsync(file) {
    manageBenefitsStore.setLoading(true);
    try {
      const attachmentProperties = await promise.withMinimalDuration(benefits_api.benefitsApi.postDocumentAsync({ file }), 500);
      this.updateDraft((draft) => {
        draft.attachment = index.some(attachmentProperties);
        draft.isDirty = true;
      });
    }
    finally {
      manageBenefitsStore.setLoading(false);
    }
  }
  clearAttachment() {
    this.updateDraft((draft) => {
      draft.attachment = index.none;
      draft.isDirty = true;
    });
  }
  async uploadIconAsync(file) {
    manageBenefitsStore.setLoading(true);
    try {
      const attachmentProperties = await promise.withMinimalDuration(benefits_api.benefitsApi.postIconAsync({ file }), 500);
      this.updateDraft((draft) => {
        draft.icon = index.some(attachmentProperties);
        draft.isDirty = true;
      });
    }
    finally {
      manageBenefitsStore.setLoading(false);
    }
  }
  clearIcon() {
    this.updateDraft((draft) => {
      draft.icon = index.none;
      draft.isDirty = true;
    });
  }
  assertDraftIsValid(draft) {
    const isDraftValid = index.isSome(draft.title) && index.isSome(draft.category);
    if (!isDraftValid)
      throw Error('Draft benefit is not valid');
  }
  updateDraft(producer) {
    manageBenefitsStore.update((state) => {
      state.draftBenefit = Option._function.pipe(state.draftBenefit, index.map(apiClient.fn(producer)));
    });
  }
  existingBenefitToDraft(existingBenefit) {
    return {
      title: existingBenefit.title,
      category: existingBenefit.category,
      subtitle: existingBenefit.subtitle,
      description: existingBenefit.description,
      url: existingBenefit.url,
      attachment: existingBenefit.attachment,
      icon: existingBenefit.icon,
      isValid: true,
      isDirty: false
    };
  }
}
const editBenefitService = new EditBenefitService();

class ManageBenefitsService {
  async loadPageStateAsync() {
    manageBenefitsStore.setLoading(true);
    const pageStateDto = await manageBenefitsApi.getPageStateAsync();
    manageBenefitsStore.update((state) => {
      state.manageBenefitsPageState = ManageBenefitsPageStateDto.toDomain(pageStateDto);
    });
    manageBenefitsStore.setLoading(false);
  }
  async enableBenefitAsync(id) {
    await manageBenefitsApi.postCommandAsync(Option.Option.some(id), 'enableAccountBenefit');
    manageBenefitsStore.update((state) => {
      const targetBenefitIndex = state.manageBenefitsPageState.disabledBenefits.findIndex((benefit) => benefit.id === id);
      if (targetBenefitIndex === -1)
        return;
      const targetBenefit = state.manageBenefitsPageState.disabledBenefits.splice(targetBenefitIndex, 1)[0];
      targetBenefit.visibility.isEnabled = true;
      state.manageBenefitsPageState.enabledBenefits.push(targetBenefit);
    });
  }
  async disableBenefitAsync(id) {
    await manageBenefitsApi.postCommandAsync(Option.Option.some(id), 'disableAccountBenefit');
    manageBenefitsStore.update((state) => {
      const targetBenefitIndex = state.manageBenefitsPageState.enabledBenefits.findIndex((benefit) => benefit.id === id);
      if (targetBenefitIndex === -1)
        return;
      const targetBenefit = state.manageBenefitsPageState.enabledBenefits.splice(targetBenefitIndex, 1)[0];
      targetBenefit.visibility.isEnabled = false;
      state.manageBenefitsPageState.disabledBenefits.push(targetBenefit);
    });
  }
}
const manageBenefitsService = new ManageBenefitsService();

exports.BenefitCategories = BenefitCategories;
exports.addLeadingSlash = addLeadingSlash;
exports.createKey = createKey;
exports.createLocation = createLocation;
exports.createPath = createPath;
exports.editBenefitQuery = editBenefitQuery;
exports.editBenefitService = editBenefitService;
exports.hasBasename = hasBasename;
exports.locationsAreEqual = locationsAreEqual;
exports.manageBenefitsQuery = manageBenefitsQuery;
exports.manageBenefitsService = manageBenefitsService;
exports.matchPath = matchPath;
exports.matchesAreEqual = matchesAreEqual;
exports.stripBasename = stripBasename;
exports.stripLeadingSlash = stripLeadingSlash;
exports.stripTrailingSlash = stripTrailingSlash;
