text:
/*! UIkit 3.12.1 | https://www.getuikit.com | (c) 2014 - 2022 YOOtheme | MIT License */

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('uikit-util')) :
    typeof define === 'function' && define.amd ? define('uikitslider', ['uikit-util'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.UIkitSlider = factory(global.UIkit.util));
})(this, (function (uikitUtil) { 'use strict';

    var Class = {
      connected() {
        !uikitUtil.hasClass(this.$el, this.$name) && uikitUtil.addClass(this.$el, this.$name);
      } };

    var SliderAutoplay = {
      props: {
        autoplay: Boolean,
        autoplayInterval: Number,
        pauseOnHover: Boolean },

      data: {
        autoplay: false,
        autoplayInterval: 7000,
        pauseOnHover: true },

      connected() {
        this.autoplay && this.startAutoplay();
      },

      disconnected() {
        this.stopAutoplay();
      },

      update() {
        uikitUtil.attr(this.slides, 'tabindex', '-1');
      },

      events: [
      {
        name: 'visibilitychange',

        el() {
          return document;
        },

        filter() {
          return this.autoplay;
        },

        handler() {
          if (document.hidden) {
            this.stopAutoplay();
          } else {
            this.startAutoplay();
          }
        } }],

      methods: {
        startAutoplay() {
          this.stopAutoplay();

          this.interval = setInterval(
          () =>
          (!this.draggable || !uikitUtil.$(':focus', this.$el)) && (
          !this.pauseOnHover || !uikitUtil.matches(this.$el, ':hover')) &&
          !this.stack.length &&
          this.show('next'),
          this.autoplayInterval);

        },

        stopAutoplay() {
          this.interval && clearInterval(this.interval);
        } } };

    var SliderDrag = {
      props: {
        draggable: Boolean },

      data: {
        draggable: true,
        threshold: 10 },

      created() {
        for (const key of ['start', 'move', 'end']) {
          const fn = this[key];
          this[key] = (e) => {
            const pos = uikitUtil.getEventPos(e).x * (uikitUtil.isRtl ? -1 : 1);

            this.prevPos = pos === this.pos ? this.prevPos : this.pos;
            this.pos = pos;

            fn(e);
          };
        }
      },

      events: [
      {
        name: uikitUtil.pointerDown,

        delegate() {
          return this.selSlides;
        },

        handler(e) {
          if (
          !this.draggable ||
          !uikitUtil.isTouch(e) && hasTextNodesOnly(e.target) ||
          uikitUtil.closest(e.target, uikitUtil.selInput) ||
          e.button > 0 ||
          this.length < 2)
          {
            return;
          }

          this.start(e);
        } },

      {
        name: 'dragstart',

        handler(e) {
          e.preventDefault();
        } }],

      methods: {
        start() {
          this.drag = this.pos;

          if (this._transitioner) {
            this.percent = this._transitioner.percent();
            this.drag += this._transitioner.getDistance() * this.percent * this.dir;

            this._transitioner.cancel();
            this._transitioner.translate(this.percent);

            this.dragging = true;

            this.stack = [];
          } else {
            this.prevIndex = this.index;
          }

          uikitUtil.on(document, uikitUtil.pointerMove, this.move, { passive: false });

          // 'input' event is triggered by video controls
          uikitUtil.on(document, uikitUtil.pointerUp + " " + uikitUtil.pointerCancel + " input", this.end, true);

          uikitUtil.css(this.list, 'userSelect', 'none');
        },

        move(e) {
          const distance = this.pos - this.drag;

          if (
          distance === 0 ||
          this.prevPos === this.pos ||
          !this.dragging && Math.abs(distance) < this.threshold)
          {
            return;
          }

          // prevent click event
          uikitUtil.css(this.list, 'pointerEvents', 'none');

          e.cancelable && e.preventDefault();

          this.dragging = true;
          this.dir = distance < 0 ? 1 : -1;

          const { slides } = this;
          let { prevIndex } = this;
          let dis = Math.abs(distance);
          let nextIndex = this.getIndex(prevIndex + this.dir, prevIndex);
          let width = this._getDistance(prevIndex, nextIndex) || slides[prevIndex].offsetWidth;

          while (nextIndex !== prevIndex && dis > width) {
            this.drag -= width * this.dir;

            prevIndex = nextIndex;
            dis -= width;
            nextIndex = this.getIndex(prevIndex + this.dir, prevIndex);
            width = this._getDistance(prevIndex, nextIndex) || slides[prevIndex].offsetWidth;
          }

          this.percent = dis / width;

          const prev = slides[prevIndex];
          const next = slides[nextIndex];
          const changed = this.index !== nextIndex;
          const edge = prevIndex === nextIndex;

          let itemShown;

          [this.index, this.prevIndex].
          filter((i) => !uikitUtil.includes([nextIndex, prevIndex], i)).
          forEach((i) => {
            uikitUtil.trigger(slides[i], 'itemhidden', [this]);

            if (edge) {
              itemShown = true;
              this.prevIndex = prevIndex;
            }
          });

          if (this.index === prevIndex && this.prevIndex !== prevIndex || itemShown) {
            uikitUtil.trigger(slides[this.index], 'itemshown', [this]);
          }

          if (changed) {
            this.prevIndex = prevIndex;
            this.index = nextIndex;

            !edge && uikitUtil.trigger(prev, 'beforeitemhide', [this]);
            uikitUtil.trigger(next, 'beforeitemshow', [this]);
          }

          this._transitioner = this._translate(Math.abs(this.percent), prev, !edge && next);

          if (changed) {
            !edge && uikitUtil.trigger(prev, 'itemhide', [this]);
            uikitUtil.trigger(next, 'itemshow', [this]);
          }
        },

        end() {
          uikitUtil.off(document, uikitUtil.pointerMove, this.move, { passive: false });
          uikitUtil.off(document, uikitUtil.pointerUp + " " + uikitUtil.pointerCancel + " input", this.end, true);

          if (this.dragging) {
            this.dragging = null;

            if (this.index === this.prevIndex) {
              this.percent = 1 - this.percent;
              this.dir *= -1;
              this._show(false, this.index, true);
              this._transitioner = null;
            } else {
              const dirChange =
              (uikitUtil.isRtl ? this.dir * (uikitUtil.isRtl ? 1 : -1) : this.dir) < 0 ===
              this.prevPos > this.pos;
              this.index = dirChange ? this.index : this.prevIndex;

              if (dirChange) {
                this.percent = 1 - this.percent;
              }

              this.show(
              this.dir > 0 && !dirChange || this.dir < 0 && dirChange ?
              'next' :
              'previous',
              true);

            }
          }

          uikitUtil.css(this.list, { userSelect: '', pointerEvents: '' });

          this.drag = this.percent = null;
        } } };

    function hasTextNodesOnly(el) {
      return !el.children.length && el.childNodes.length;
    }

    var SliderNav = {
      data: {
        selNav: false },

      computed: {
        nav(_ref, $el) {let { selNav } = _ref;
          return uikitUtil.$(selNav, $el);
        },

        selNavItem(_ref2) {let { attrItem } = _ref2;
          return "[" + attrItem + "],[data-" + attrItem + "]";
        },

        navItems(_, $el) {
          return uikitUtil.$$(this.selNavItem, $el);
        } },

      update: {
        write() {
          if (this.nav && this.length !== this.nav.children.length) {
            uikitUtil.html(
            this.nav,
            this.slides.
            map((_, i) => "

").
            join(''));

          }

          this.navItems.concat(this.nav).forEach((el) => el && (el.hidden = !this.maxIndex));

          this.updateNav();
        },

        events: ['resize'] },

      events: [
      {
        name: 'click',

        delegate() {
          return this.selNavItem;
        },

        handler(e) {
          e.preventDefault();
          this.show(uikitUtil.data(e.current, this.attrItem));
        } },

      {
        name: 'itemshow',
        handler: 'updateNav' }],

      methods: {
        updateNav() {
          const i = this.getValidIndex();
          for (const el of this.navItems) {
            const cmd = uikitUtil.data(el, this.attrItem);

            uikitUtil.toggleClass(el, this.clsActive, uikitUtil.toNumber(cmd) === i);
            uikitUtil.toggleClass(
            el,
            'uk-invisible',
            this.finite && (
            cmd === 'previous' && i === 0 || cmd === 'next' && i >= this.maxIndex));

          }
        } } };

    var Slider = {
      mixins: [SliderAutoplay, SliderDrag, SliderNav],

      props: {
        clsActivated: Boolean,
        easing: String,
        index: Number,
        finite: Boolean,
        velocity: Number,
        selSlides: String },

      data: () => ({
        easing: 'ease',
        finite: false,
        velocity: 1,
        index: 0,
        prevIndex: -1,
        stack: [],
        percent: 0,
        clsActive: 'uk-active',
        clsActivated: false,
        Transitioner: false,
        transitionOptions: {} }),

      connected() {
        this.prevIndex = -1;
        this.index = this.getValidIndex(this.$props.index);
        this.stack = [];
      },

      disconnected() {
        uikitUtil.removeClass(this.slides, this.clsActive);
      },

      computed: {
        duration(_ref, $el) {let { velocity } = _ref;
          return speedUp($el.offsetWidth / velocity);
        },

        list(_ref2, $el) {let { selList } = _ref2;
          return uikitUtil.$(selList, $el);
        },

        maxIndex() {
          return this.length - 1;
        },

        selSlides(_ref3) {let { selList, selSlides } = _ref3;
          return selList + " " + (selSlides || '> *');
        },

        slides: {
          get() {
            return uikitUtil.$$(this.selSlides, this.$el);
          },

          watch() {
            this.$reset();
          } },

        length() {
          return this.slides.length;
        } },

      methods: {
        show(index, force) {if (force === void 0) {force = false;}
          if (this.dragging || !this.length) {
            return;
          }

          const { stack } = this;
          const queueIndex = force ? 0 : stack.length;
          const reset = () => {
            stack.splice(queueIndex, 1);

            if (stack.length) {
              this.show(stack.shift(), true);
            }
          };

          stack[force ? 'unshift' : 'push'](index);

          if (!force && stack.length > 1) {
            if (stack.length === 2) {
              this._transitioner.forward(Math.min(this.duration, 200));
            }

            return;
          }

          const prevIndex = this.getIndex(this.index);
          const prev = uikitUtil.hasClass(this.slides, this.clsActive) && this.slides[prevIndex];
          const nextIndex = this.getIndex(index, this.index);
          const next = this.slides[nextIndex];

          if (prev === next) {
            reset();
            return;
          }

          this.dir = getDirection(index, prevIndex);
          this.prevIndex = prevIndex;
          this.index = nextIndex;

          if (
          prev && !uikitUtil.trigger(prev, 'beforeitemhide', [this]) ||
          !uikitUtil.trigger(next, 'beforeitemshow', [this, prev]))
          {
            this.index = this.prevIndex;
            reset();
            return;
          }

          const promise = this._show(prev, next, force).then(() => {
            prev && uikitUtil.trigger(prev, 'itemhidden', [this]);
            uikitUtil.trigger(next, 'itemshown', [this]);

            return new Promise((resolve) => {
              uikitUtil.fastdom.write(() => {
                stack.shift();
                if (stack.length) {
                  this.show(stack.shift(), true);
                } else {
                  this._transitioner = null;
                }
                resolve();
              });
            });
          });

          prev && uikitUtil.trigger(prev, 'itemhide', [this]);
          uikitUtil.trigger(next, 'itemshow', [this]);

          return promise;
        },

        getIndex(index, prev) {if (index === void 0) {index = this.index;}if (prev === void 0) {prev = this.index;}
          return uikitUtil.clamp(uikitUtil.getIndex(index, this.slides, prev, this.finite), 0, this.maxIndex);
        },

        getValidIndex(index, prevIndex) {if (index === void 0) {index = this.index;}if (prevIndex === void 0) {prevIndex = this.prevIndex;}
          return this.getIndex(index, prevIndex);
        },

        _show(prev, next, force) {
          this._transitioner = this._getTransitioner(prev, next, this.dir, {
            easing: force ?
            next.offsetWidth < 600 ?
            'cubic-bezier(0.25, 0.46, 0.45, 0.94)' /* easeOutQuad */ :
            'cubic-bezier(0.165, 0.84, 0.44, 1)' /* easeOutQuart */ :
            this.easing,
            ...this.transitionOptions });

          if (!force && !prev) {
            this._translate(1);
            return Promise.resolve();
          }

          const { length } = this.stack;
          return this._transitioner[length > 1 ? 'forward' : 'show'](
          length > 1 ? Math.min(this.duration, 75 + 75 / (length - 1)) : this.duration,
          this.percent);

        },

        _getDistance(prev, next) {
          return this._getTransitioner(prev, prev !== next && next).getDistance();
        },

        _translate(percent, prev, next) {if (prev === void 0) {prev = this.prevIndex;}if (next === void 0) {next = this.index;}
          const transitioner = this._getTransitioner(prev !== next ? prev : false, next);
          transitioner.translate(percent);
          return transitioner;
        },

        _getTransitioner(
        prev,
        next,
        dir,
        options)
        {if (prev === void 0) {prev = this.prevIndex;}if (next === void 0) {next = this.index;}if (dir === void 0) {dir = this.dir || 1;}if (options === void 0) {options = this.transitionOptions;}
          return new this.Transitioner(
          uikitUtil.isNumber(prev) ? this.slides[prev] : prev,
          uikitUtil.isNumber(next) ? this.slides[next] : next,
          dir * (uikitUtil.isRtl ? -1 : 1),
          options);

        } } };

    function getDirection(index, prevIndex) {
      return index === 'next' ? 1 : index === 'previous' ? -1 : index < prevIndex ? -1 : 1;
    }

    function speedUp(x) {
      return 0.5 * x + 300; // parabola through (400,500; 600,600; 1800,1200)
    }

    var SliderReactive = {
      update: {
        write() {
          if (this.stack.length || this.dragging) {
            return;
          }

          const index = this.getValidIndex(this.index);

          if (!~this.prevIndex || this.index !== index) {
            this.show(index);
          }
        },

        events: ['resize'] } };

    var Lazyload = {
      methods: {
        lazyload(observeTargets, targets) {if (observeTargets === void 0) {observeTargets = this.$el;}if (targets === void 0) {targets = this.$el;}
          this.registerObserver(
          uikitUtil.observeIntersection(observeTargets, (entries, observer) => {
            for (const el of uikitUtil.toNodes(uikitUtil.isFunction(targets) ? targets() : targets)) {
              uikitUtil.$$('[loading="lazy"]', el).forEach((el) => uikitUtil.removeAttr(el, 'loading'));
            }
            for (const el of entries.
            filter((_ref) => {let { isIntersecting } = _ref;return isIntersecting;}).
            map((_ref2) => {let { target } = _ref2;return target;})) {
              observer.unobserve(el);
            }
          }));

        } } };

    var SliderPreload = {
      mixins: [Lazyload],

      connected() {
        this.lazyload(this.slides, this.getAdjacentSlides);
      } };

    function translate(value, unit) {if (value === void 0) {value = 0;}if (unit === void 0) {unit = '%';}
      value += value ? unit : '';
      return "translate3d(" + value + ", 0, 0)";
    }

    function Transitioner (prev, next, dir, _ref) {let { center, easing, list } = _ref;
      const deferred = new uikitUtil.Deferred();

      const from = prev ?
      getLeft(prev, list, center) :
      getLeft(next, list, center) + uikitUtil.dimensions(next).width * dir;
      const to = next ?
      getLeft(next, list, center) :
      from + uikitUtil.dimensions(prev).width * dir * (uikitUtil.isRtl ? -1 : 1);

      return {
        dir,

        show(duration, percent, linear) {if (percent === void 0) {percent = 0;}
          const timing = linear ? 'linear' : easing;
          duration -= Math.round(duration * uikitUtil.clamp(percent, -1, 1));

          this.translate(percent);

          percent = prev ? percent : uikitUtil.clamp(percent, 0, 1);
          triggerUpdate(this.getItemIn(), 'itemin', { percent, duration, timing, dir });
          prev &&
          triggerUpdate(this.getItemIn(true), 'itemout', {
            percent: 1 - percent,
            duration,
            timing,
            dir });

          uikitUtil.Transition.start(
          list,
          { transform: translate(-to * (uikitUtil.isRtl ? -1 : 1), 'px') },
          duration,
          timing).
          then(deferred.resolve, uikitUtil.noop);

          return deferred.promise;
        },

        cancel() {
          uikitUtil.Transition.cancel(list);
        },

        reset() {
          uikitUtil.css(list, 'transform', '');
        },

        forward(duration, percent) {if (percent === void 0) {percent = this.percent();}
          uikitUtil.Transition.cancel(list);
          return this.show(duration, percent, true);
        },

        translate(percent) {
          const distance = this.getDistance() * dir * (uikitUtil.isRtl ? -1 : 1);

          uikitUtil.css(
          list,
          'transform',
          translate(
          uikitUtil.clamp(
          -to + (distance - distance * percent),
          -getWidth(list),
          uikitUtil.dimensions(list).width) * (
          uikitUtil.isRtl ? -1 : 1),
          'px'));

          const actives = this.getActives();
          const itemIn = this.getItemIn();
          const itemOut = this.getItemIn(true);

          percent = prev ? uikitUtil.clamp(percent, -1, 1) : 0;

          for (const slide of uikitUtil.children(list)) {
            const isActive = uikitUtil.includes(actives, slide);
            const isIn = slide === itemIn;
            const isOut = slide === itemOut;
            const translateIn =
            isIn ||
            !isOut && (
            isActive ||
            dir * (uikitUtil.isRtl ? -1 : 1) === -1 ^
            getElLeft(slide, list) > getElLeft(prev || next));

            triggerUpdate(slide, "itemtranslate" + (translateIn ? 'in' : 'out'), {
              dir,
              percent: isOut ? 1 - percent : isIn ? percent : isActive ? 1 : 0 });

          }
        },

        percent() {
          return Math.abs(
          (uikitUtil.css(list, 'transform').split(',')[4] * (uikitUtil.isRtl ? -1 : 1) + from) / (to - from));

        },

        getDistance() {
          return Math.abs(to - from);
        },

        getItemIn(out) {if (out === void 0) {out = false;}
          let actives = this.getActives();
          let nextActives = inView(list, getLeft(next || prev, list, center));

          if (out) {
            const temp = actives;
            actives = nextActives;
            nextActives = temp;
          }

          return nextActives[uikitUtil.findIndex(nextActives, (el) => !uikitUtil.includes(actives, el))];
        },

        getActives() {
          return inView(list, getLeft(prev || next, list, center));
        } };

    }

    function getLeft(el, list, center) {
      const left = getElLeft(el, list);

      return center ? left - centerEl(el, list) : Math.min(left, getMax(list));
    }

    function getMax(list) {
      return Math.max(0, getWidth(list) - uikitUtil.dimensions(list).width);
    }

    function getWidth(list) {
      return uikitUtil.children(list).reduce((right, el) => uikitUtil.dimensions(el).width + right, 0);
    }

    function centerEl(el, list) {
      return uikitUtil.dimensions(list).width / 2 - uikitUtil.dimensions(el).width / 2;
    }

    function getElLeft(el, list) {
      return (
        el &&
        (uikitUtil.position(el).left + (uikitUtil.isRtl ? uikitUtil.dimensions(el).width - uikitUtil.dimensions(list).width : 0)) * (
        uikitUtil.isRtl ? -1 : 1) ||
        0);

    }

    function inView(list, listLeft) {
      listLeft -= 1;
      const listWidth = uikitUtil.dimensions(list).width;
      const listRight = listLeft + listWidth + 2;

      return uikitUtil.children(list).filter((slide) => {
        const slideLeft = getElLeft(slide, list);
        const slideRight = slideLeft + Math.min(uikitUtil.dimensions(slide).width, listWidth);

        return slideLeft >= listLeft && slideRight <= listRight;
      });
    }

    function triggerUpdate(el, type, data) {
      uikitUtil.trigger(el, uikitUtil.createEvent(type, false, false, data));
    }

    var Component = {
      mixins: [Class, Slider, SliderReactive, SliderPreload],

      props: {
        center: Boolean,
        sets: Boolean },

      data: {
        center: false,
        sets: false,
        attrItem: 'uk-slider-item',
        selList: '.uk-slider-items',
        selNav: '.uk-slider-nav',
        clsContainer: 'uk-slider-container',
        Transitioner },

      computed: {
        avgWidth() {
          return getWidth(this.list) / this.length;
        },

        finite(_ref) {let { finite } = _ref;
          return (
            finite ||
            Math.ceil(getWidth(this.list)) <
            Math.floor(uikitUtil.dimensions(this.list).width + getMaxElWidth(this.list) + this.center));

        },

        maxIndex() {
          if (!this.finite || this.center && !this.sets) {
            return this.length - 1;
          }

          if (this.center) {
            return uikitUtil.last(this.sets);
          }

          let lft = 0;
          const max = getMax(this.list);
          const index = uikitUtil.findIndex(this.slides, (el) => {
            if (lft >= max) {
              return true;
            }

            lft += uikitUtil.dimensions(el).width;
          });

          return ~index ? index : this.length - 1;
        },

        sets(_ref2) {let { sets: enabled } = _ref2;
          if (!enabled) {
            return;
          }

          let left = 0;
          const sets = [];
          const width = uikitUtil.dimensions(this.list).width;
          for (let i in this.slides) {
            const slideWidth = uikitUtil.dimensions(this.slides[i]).width;

            if (left + slideWidth > width) {
              left = 0;
            }

            if (this.center) {
              if (
              left < width / 2 &&
              left + slideWidth + uikitUtil.dimensions(this.slides[+i + 1]).width / 2 > width / 2)
              {
                sets.push(+i);
                left = width / 2 - slideWidth / 2;
              }
            } else if (left === 0) {
              sets.push(Math.min(+i, this.maxIndex));
            }

            left += slideWidth;
          }

          if (sets.length) {
            return sets;
          }
        },

        transitionOptions() {
          return {
            center: this.center,
            list: this.list };

        } },

      connected() {
        uikitUtil.toggleClass(this.$el, this.clsContainer, !uikitUtil.$("." + this.clsContainer, this.$el));
      },

      update: {
        write() {
          for (const el of this.navItems) {
            const index = uikitUtil.toNumber(uikitUtil.data(el, this.attrItem));
            if (index !== false) {
              el.hidden =
              !this.maxIndex ||
              index > this.maxIndex ||
              this.sets && !uikitUtil.includes(this.sets, index);
            }
          }

          if (this.length && !this.dragging && !this.stack.length) {
            this.reorder();
            this._translate(1);
          }

          this.updateActiveClasses();
        },

        events: ['resize'] },

      events: {
        beforeitemshow(e) {
          if (
          !this.dragging &&
          this.sets &&
          this.stack.length < 2 &&
          !uikitUtil.includes(this.sets, this.index))
          {
            this.index = this.getValidIndex();
          }

          const diff = Math.abs(
          this.index -
          this.prevIndex + (
          this.dir > 0 && this.index < this.prevIndex ||
          this.dir < 0 && this.index > this.prevIndex ?
          (this.maxIndex + 1) * this.dir :
          0));

          if (!this.dragging && diff > 1) {
            for (let i = 0; i < diff; i++) {
              this.stack.splice(1, 0, this.dir > 0 ? 'next' : 'previous');
            }

            e.preventDefault();
            return;
          }

          const index =
          this.dir < 0 || !this.slides[this.prevIndex] ? this.index : this.prevIndex;
          this.duration =
          speedUp(this.avgWidth / this.velocity) * (
          uikitUtil.dimensions(this.slides[index]).width / this.avgWidth);

          this.reorder();
        },

        itemshow() {
          if (~this.prevIndex) {
            uikitUtil.addClass(this._getTransitioner().getItemIn(), this.clsActive);
          }
        },

        itemshown() {
          this.updateActiveClasses();
        } },

      methods: {
        reorder() {
          if (this.finite) {
            uikitUtil.css(this.slides, 'order', '');
            return;
          }

          const index = this.dir > 0 && this.slides[this.prevIndex] ? this.prevIndex : this.index;

          this.slides.forEach((slide, i) =>
          uikitUtil.css(
          slide,
          'order',
          this.dir > 0 && i < index ? 1 : this.dir < 0 && i >= this.index ? -1 : ''));

          if (!this.center) {
            return;
          }

          const next = this.slides[index];
          let width = uikitUtil.dimensions(this.list).width / 2 - uikitUtil.dimensions(next).width / 2;
          let j = 0;

          while (width > 0) {
            const slideIndex = this.getIndex(--j + index, index);
            const slide = this.slides[slideIndex];

            uikitUtil.css(slide, 'order', slideIndex > index ? -2 : -1);
            width -= uikitUtil.dimensions(slide).width;
          }
        },

        updateActiveClasses() {
          const actives = this._getTransitioner(this.index).getActives();
          const activeClasses = [
          this.clsActive,
          (!this.sets || uikitUtil.includes(this.sets, uikitUtil.toFloat(this.index))) && this.clsActivated ||
          ''];

          for (const slide of this.slides) {
            uikitUtil.toggleClass(slide, activeClasses, uikitUtil.includes(actives, slide));
          }
        },

        getValidIndex(index, prevIndex) {if (index === void 0) {index = this.index;}if (prevIndex === void 0) {prevIndex = this.prevIndex;}
          index = this.getIndex(index, prevIndex);

          if (!this.sets) {
            return index;
          }

          let prev;

          do {
            if (uikitUtil.includes(this.sets, index)) {
              return index;
            }

            prev = index;
            index = this.getIndex(index + this.dir, prevIndex);
          } while (index !== prev);

          return index;
        },

        getAdjacentSlides() {
          const { width } = uikitUtil.dimensions(this.list);
          const left = -width;
          const right = width * 2;
          const slideWidth = uikitUtil.dimensions(this.slides[this.index]).width;
          const slideLeft = this.center ? width / 2 - slideWidth / 2 : 0;
          const slides = new Set();
          for (const i of [-1, 1]) {
            let currentLeft = slideLeft + (i > 0 ? slideWidth : 0);
            let j = 0;
            do {
              const slide = this.slides[this.getIndex(this.index + i + j++ * i)];
              currentLeft += uikitUtil.dimensions(slide).width * i;
              slides.add(slide);
            } while (this.slides.length > j && currentLeft > left && currentLeft < right);
          }
          return Array.from(slides);
        } } };

    function getMaxElWidth(list) {
      return Math.max(0, ...uikitUtil.children(list).map((el) => uikitUtil.dimensions(el).width));
    }

    if (typeof window !== 'undefined' && window.UIkit) {
      window.UIkit.component('slider', Component);
    }

    return Component;

}));


text:
package org.sagebionetworks.repo.util;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * http://stackoverflow.com/questions/221525/how-would-you-implement-an-lru-cache-in-java-6
 *
 * @author deflaux
 *
 * @param
 * @param
 */
@SuppressWarnings("serial")
public class LruCache extends LinkedHashMap {
	private final int maxEntries;

	/**
	 * Be sure to use a thread-safe instance of the cache
	 * Map<String, String> example = Collections.synchronizedMap(new LruCache<String, String>(CACHE_SIZE));
	 *
	 * @param maxEntries
	 */
	public LruCache(final int maxEntries) {
		super(maxEntries + 1, 1.0f, true);
		this.maxEntries = maxEntries;
	}

	/**
	 * Returns <tt>true</tt> if this LruCache has more entries than
	 * the maximum specified when it was created.
	 *
	 *

	 * This method does not modify the underlying Map; it
	 * relies on the implementation of LinkedHashMap to do that,
	 * but that behavior is documented in the JavaDoc for
	 * LinkedHashMap.
	 *

	 *
	 * @param eldest
	 *            the Entry in question; this implementation
	 *            doesn't care what it is, since the implementation is only
	 *            dependent on the size of the cache
	 * @return <tt>true</tt> if the oldest
	 * @see java.util.LinkedHashMap#removeEldestEntry(Map.Entry)
	 */
	@Override
	protected boolean removeEldestEntry(final Map.Entry eldest) {
		return super.size() > maxEntries;
	}
}

redpajama_set_name: RedPajamaGithub


text:
package org.apache.oodt.commons;

import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.rmi.registry.Registry;
import java.rmi.server.RemoteObject;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.spi.NamingManager;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.oodt.commons.util.LogInit;
import org.apache.oodt.commons.util.XML;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * The MultiServer runs multiple server objects in a single JVM.  Instead of running a
 * separate product server, profile server, query server, and so forth, in their own JVMs,
 * which are extremely heavy-weight operating system processes, we can put them into one
 * JVM which reduces the memory footprint on a single computer enormously.
 *
 *
Specifying the Configuration

 *
 * The MultiServer configuration is an XML document.  Here's
 * a sample:
 *
<multiserver
 *   xmlns="http://oodt.jpl.nasa.gov/edm-commons/xml/multiserver"
 *   id="My Multi Server">
 *   <server
 *     class="org.apache.oodt.commons.product.rmi.ProductServiceImpl"
 *     id="urn:eda:rmi:BioServer"
 *     bind="rebind" />
 *   <server
 *     class="org.apache.oodt.commons.product.rmi.ProductServiceImpl"
 *     id="urn:eda:rmi:SpaceServer"
 *     bind="1800000" />
 *   <server
 *     class="org.apache.oodt.commons.profile.rmi.ProfileServiceImpl"
 *     id="urn:eda:rmi:Resource"
 *     bind="bind" />
 *   <properties>
 *     <property name="urn:eda:rmi:BioServer.handlers">
 *       edrn.MedHandler,edrn.SpecimenHandler
 *     </property>
 *     <property name="urn:eda:rmi:SpaceServer.handlers">
 *       pds.PlanetoidHandler
 *     </property>
 *     <property name="org.apache.oodt.commons.profile.Handlers">
 *       com.sun.ResourceHandler
 *     </property>
 *   </properties>
 * </multiserver>

 *
 *
This would start three servers (two products, one profile) with the various property
 * settings indicated.  The MultiServer expects the property
 * org.apache.oodt.commons.MultiServer.config to identify the URL of the configuration.  You
 * can shorten that to MultiServer.config or multiserver.config
 * or even just config, in that order.  If none of those properties are
 * specified then the MultiServer will expect the URL to be the first (and only) command
 * line argument.
 *
 *
The id attribute on the multiserver element tells the name
 * of the whole application; it's used to prefix log messages.
 *
 *
Server Specification

 *
 *
Each <server> entry names a server to start.  The
 * class attribute is the name of the RMI-compatible Java class that the
 * server will run.  (Note that currently only RMI servers are supported.)  The
 * id attribute tells the name the server should use to register with the
 * naming context.  And the bind attribute tells how the registration should
 * proceed.  It can take on the following values:
 *
 *

 *
true meaning the object will attempt a bind.  If the ID is already
 *   bound in the context, the MultiServer fails.

 *
 *
false meaning the object won't be bound.

 *
 *
rebind meaning the object will rebind its ID in the context,
 *   overwriting any previous binding.
 *
 *
<var>number</var> meaining the object will rebind its ID once at starup, and
 *   every <var>number</var> milliseconds thereafter.  This is, in OODT's experience, the
 *   most useful option as it helps an entire dpeloyed network of servers self-heal after
 *   a naming context restart.
 *

 *
 *
Propery Specification

 *
 *
For convenience, System Properties may be specified in the configirutaion as well.
 * However, any properties already defined (such as using the -D command-line
 * argument) get priority and their values won't be overridden.  To specify properties,
 * list any number of <property> elements under the
 * <properties> element with a name attribute naming the
 * System Property key and the text of the element naming its value.  Note that the text
 * will be unwrapped.
 *
 * @author Kelly
 * @version $Revision: 1.3 $
 */
public class MultiServer {
	/**
	 * Start the multi server.
	 *
	 * @param argv Command-line arguments.
	 * @throws Throwable if an error occurs.
	 */
	public static void main(String[] argv) throws Throwable {
		String config = System.getProperty("org.apache.oodt.commons.MultiServer.config", System.getProperty("MultiServer.config",
			System.getProperty("multiserver.config", System.getProperty("config"))));
		if (config == null) {
			if (argv.length != 1)
				throw new IllegalStateException("No org.apache.oodt.commons.MultiServer.config property or config URL argument");
			else
				config = argv[0];
		}

		StringReader reader = new StringReader(CONFIG);
		Configuration.configuration = new Configuration(new InputSource(reader));
		reader.close();
		parseConfig(new InputSource(config));

		Hashtable t = new Hashtable();
		t.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.oodt.commons.object.jndi.ObjectCtxFactory");
		String registryList = System.getProperty("org.apache.oodt.commons.rmiregistries", System.getProperty("rmiregistries"));
		if (registryList == null) {
			String host = System.getProperty("rmiregistry.host", "localhost");
			int port = Integer.getInteger("rmiregistry.port", Registry.REGISTRY_PORT).intValue();
			registryList = "rmi://" + host + ":" + port;
		}
		t.put("rmiregistries", registryList);
		context = NamingManager.getInitialContext(t);
		ExecServer.runInitializers();
		try {
			LogInit.init(System.getProperties(), getAppName());
			if (servers.isEmpty()) throw new IllegalStateException("No servers defined in config");

			Runtime.getRuntime().addShutdownHook(new Thread() {
				public void run() {
					shutdown();
				}
			});
			startup();
		} catch (Throwable ex) {
			ex.printStackTrace();
			try {
				shutdown();
			} catch (Throwable ignore) {}
			System.exit(1);
		}
		for (;;) try {
			Thread.currentThread().join();
		} catch (InterruptedException ignore) {}
	}

	/**
	 * Parse the MultiServer configuration.
	 *
	 * @param is Source of the configuration.
	 * @throws ParserConfigurationException If we can't create a parser.
	 * @throws SAXException If there's a parse error.
	 * @throws IOException If there's a problem reading the configuration.
	 * @throws ClassNotFoundException If we can't find a server class.
	 * @throws NoSuchMethodException If the server class doesn't have the right constructor.
	 * @throws InstantiationException If we can create a server object.
	 * @throws IllegalAccessException If the server constructor isn't accessible.
	 * @throws InvocationTargetException If the server constructor throws an exception.
	 */
	static void parseConfig(InputSource is) throws ParserConfigurationException, SAXException, IOException,
		ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException,
		InvocationTargetException {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setIgnoringComments(true);
		factory.setIgnoringElementContentWhitespace(true);
		factory.setNamespaceAware(true);
		factory.setValidating(false);
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.parse(is);
		Element root = doc.getDocumentElement();
		appName = root.getAttribute("id");
		if (appName == null) throw new SAXException("id attribute missing from multiserver element");

		// Set properties
		NodeList children = root.getChildNodes();
		for (int i = 0; i < children.getLength(); ++i) {
			Node node = (Node) children.item(i);
			if ("properties".equals(node.getNodeName())) {
				NodeList props = ((Element) node).getElementsByTagName("property");
				for (int j = 0; j < props.getLength(); ++j) {
					Element property = (Element) props.item(j);
					String name = property.getAttribute("name");
					if (!System.getProperties().containsKey(name)) {
						String value = XML.unwrappedText(property);
						System.setProperty(name, value);
					}
				}
			}
		}

		// Create servers
		NodeList serverNodes = root.getElementsByTagName("server");
		servers = new HashMap();
		for (int i = 0; i < serverNodes.getLength(); ++i) {
			Element serverElem = (Element) serverNodes.item(i);
			String name = serverElem.getAttribute("id");
			if (name == null) throw new SAXException("id attribute missing from server element");
			String className = serverElem.getAttribute("class");
			if (className == null) throw new SAXException("class attribute missing from server element");
			String bindKind = serverElem.getAttribute("bind");
			if (bindKind == null) throw new SAXException("bind attribute missing from server element");
			Server server;
			if ("true".equals(bindKind))
				server = new BindingServer(name, className);
			else if ("false".equals(bindKind))
				server = new NonbindingServer(name, className);
			else if ("rebind".equals(bindKind))
				server = new RebindingServer(name, className);
			else try {
				long period = Long.parseLong(bindKind);
				server = new AutobindingServer(name, className, period);
			} catch (NumberFormatException ex) {
				throw new SAXException("Expected true, false, rebind, or auto for bind attribute but got `"
					+ bindKind + "'");
			}
			servers.put(name, server);
		}

	}

	/**
	 * Start each server.
	 *
	 * @throws NamingException if an error occurs.
	 */
	static void startup() throws NamingException {
		for (Iterator i = servers.values().iterator(); i.hasNext();) {
			Server s = (Server) i.next();
			s.start();
		}
	}

	/**
	 * Stop each server.
	 */
	static void shutdown() {
		for (Iterator i = servers.values().iterator(); i.hasNext();) try {
			Server s = (Server) i.next();
			s.stop();
		} catch (NamingException ignore) {}
		TIMER.cancel();
	}

	/**
	 * Get the name of the application.
	 *
	 * @return a {@link String} value.
	 */
	static String getAppName() {
		return appName;
	}

	/**
	 * Get the servers.  Keys are {@String} names and values are {@link #Server}s.
	 *
	 * @return a {@link Map} of the defined servers.
	 */
	static Map getServers() {
		return servers;
	}

	/**
	 * A server.
	 */
	static abstract class Server extends ExecServer {
		/**
		 * Creates a new {@link Server} instance.
		 *
		 * @param name ID under which to register.
		 * @param className Class of server to instantiate.
		 * @throws ClassNotFoundException If we can't find the server class.
		 * @throws NoSuchMethodException If the server class doesn't have the right constructor.
		 * @throws InstantiationException If we can create the server object.
		 * @throws IllegalAccessException If the server constructor isn't accessible.
		 * @throws InvocationTargetException If the server constructor throws an exception.
		 */
		protected Server(String name, String className) throws ClassNotFoundException, NoSuchMethodException,
			InstantiationException, IllegalAccessException, InvocationTargetException {
			super(name);
			this.className = className;
			Class clazz = Class.forName(className);
			Constructor ctor = clazz.getConstructor(new Class[]{ ExecServer.class });
			servant = (RemoteObject) ctor.newInstance(new Object[]{ this });
		}

		/**
		 * Get the name of the server class to instantiate.
		 *
		 * @return a {@link String} value.
		 */
		public String getClassName() {
			return className;
		}

		/**
		 * Get the type of binding this server will perform.  Possible values are
		 * {@link #BINDING}, {@link #NONBINDING}, {@link #REBINDING}, or {@link
		 * #AUTO}.
		 *
		 * @return An integer identifiying the binding behavior.
		 */
		public abstract int getBindingBehavior();

		/**
		 * Start this server.
		 *
		 * @throws NamingException if an error occurs during the binding.
		 */
		public abstract void start() throws NamingException;

		/**
		 * Stop this server.
		 *
		 * @throws NamingException if an error occurs during unbinding.
		 */
		public abstract void stop() throws NamingException;

		/** Name of server class. */
		protected String className;

		/** Server object. */
		protected RemoteObject servant;
	}

	/** Inidcates server will try a bind. */
	public static final int BINDING = 1;

	/** Indicates server won't be bound. */
	public static final int NONBINDING = 2;

	/** Indicates server will try a rebind. */
	public static final int REBINDING = 3;

	/** Indicates server will try periodic rebinding. */
	public static final int AUTO = 4;

	/** Timer to schedule periodic rebinind. */
	private static final Timer TIMER = new Timer(/*isDaemon*/true);

	/** Name of this application. */
	private static String appName;

	/** Known servers.  Keys are {@String} names and values are {@link #Server}s. */
	private static Map servers;

	/** The naming context. */
	private static Context context;

	/** The edarc.xml file to satisfy the MultiServer's servers. */
	private static final String CONFIG = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE configuration PUBLIC"
		+ " \"-//JPL//DTD EDA Configuration 1.0//EN\" \"http://enterprise.jpl.nasa.gov/dtd/configuration.dtd\">\n"
		+ "<configuration><webServer><host>localhost</host><port>80</port></webServer>"
		+ "<nameServer><iiop><host>localhost</host><port>10000</port></iiop></nameServer></configuration>";

	/**
	 * A server that tries a single bind.
	 */
	static class BindingServer extends Server {
		/**
		 * Creates a new {@link BindingServer} instance.
		 *
		 * @param name ID under which to register.
		 * @param className Class of server to instantiate.
		 * @throws ClassNotFoundException If we can't find the server class.
		 * @throws NoSuchMethodException If the server class doesn't have the right constructor.
		 * @throws InstantiationException If we can create the server object.
		 * @throws IllegalAccessException If the server constructor isn't accessible.
		 * @throws InvocationTargetException If the server constructor throws an exception.
		 */
		BindingServer(String name, String className) throws ClassNotFoundException, NoSuchMethodException,
			InstantiationException, IllegalAccessException, InvocationTargetException {
			super(name, className);
		}

		public int getBindingBehavior() {
			return BINDING;
		}

		/**
		 * Start by binding.
		 *
		 * @throws NamingException if an error occurs.
		 */
		public void start() throws NamingException {
			context.bind(name, servant);
		}

		/**
		 * Stop by unbinding.
		 *
		 * @throws NamingException if an error occurs.
		 */
		public void stop() throws NamingException {
			context.unbind(name);
		}
	}

	/**
	 * A (named, but anonymous) server that isn't bound to a naming context.
	 */
	static class NonbindingServer extends Server {
		/**
		 * Creates a new {@link NonbindingServer} instance.
		 *
		 * @param name ID under which to register.
		 * @param className Class of server to instantiate.
		 * @throws ClassNotFoundException If we can't find the server class.
		 * @throws NoSuchMethodException If the server class doesn't have the right constructor.
		 * @throws InstantiationException If we can create the server object.
		 * @throws IllegalAccessException If the server constructor isn't accessible.
		 * @throws InvocationTargetException If the server constructor throws an exception.
		 */
		NonbindingServer(String name, String className) throws ClassNotFoundException, NoSuchMethodException,
			InstantiationException, IllegalAccessException, InvocationTargetException {
			super(name, className);
		}

		public int getBindingBehavior() {
			return NONBINDING;
		}

		/**
		 * Start by taking no action.
		 */
		public void start() {}

		/**
		 * Stop by taking no action.
		 */
		public void stop() {}
	}

	/**
	 * A server that rebinds its ID in the naming context.
	 */
	static class RebindingServer extends BindingServer {
		/**
		 * Creates a new {@link RebindingServer} instance.
		 *
		 * @param name ID under which to register.
		 * @param className Class of server to instantiate.
		 * @throws ClassNotFoundException If we can't find the server class.
		 * @throws NoSuchMethodException If the server class doesn't have the right constructor.
		 * @throws InstantiationException If we can create the server object.
		 * @throws IllegalAccessException If the server constructor isn't accessible.
		 * @throws InvocationTargetException If the server constructor throws an exception.
		 */
		RebindingServer(String name, String className) throws ClassNotFoundException, NoSuchMethodException,
			InstantiationException, IllegalAccessException, InvocationTargetException {
			super(name, className);
		}

		public int getBindingBehavior() {
			return REBINDING;
		}

		/**
		 * Start by rebinding in naming context.
		 *
		 * @throws NamingException if an error occurs.
		 */
		public void start() throws NamingException {
			context.rebind(name, servant);
		}
	}

	/**
	 * A server that periodically rebinds its ID in the naming context.
	 */
	static class AutobindingServer extends Server {
		/**
		 * Creates a new {@link AutobindingServer} instance.
		 *
		 * @param name ID under which to register.
		 * @param className Class of server to instantiate.
		 * @throws ClassNotFoundException If we can't find the server class.
		 * @throws NoSuchMethodException If the server class doesn't have the right constructor.
		 * @throws InstantiationException If we can create the server object.
		 * @throws IllegalAccessException If the server constructor isn't accessible.
		 * @throws InvocationTargetException If the server constructor throws an exception.
		 */
		AutobindingServer(String name, String className, long period) throws ClassNotFoundException, NoSuchMethodException,
			InstantiationException, IllegalAccessException, InvocationTargetException {
			super(name, className);
			this.period = period;
		}

		public int getBindingBehavior() {
			return AUTO;
		}

		/**
		 * Start by scheduling the timer task that rebinds this server.
		 */
		public void start() {
			TIMER.schedule(binder = new Binder(), /*delay*/0L, /*period*/period);
		}

		/**
		 * Stop by canceling the timer task and unbinding from the server.
		 *
		 * @throws NamingException if an error occurs.
		 */
		public void stop() throws NamingException {
			if (binder != null) binder.cancel();
			context.unbind(name);
		}

		/**
		 * Get how often this server process will be rebound.
		 *
		 * @return Period in milliseconds.
		 */
		public long getPeriod() {
			return period;
		}

		/** How often to rebind in milliseconds. */
		private long period;

		/** Timer task that rebinds. */
		private Binder binder;

		/**
		 * Timer task that rebinds this server to the naming context.
		 */
		private class Binder extends TimerTask {
			public void run() {
				try {
					context.rebind(name, servant);
				} catch (NamingException ex) {}
			}
		}
	}
}


text:
html {
    height: 100%;
    width: 100%;
}

body {
    color: #eee;
    font-family: Helvetica, Arial, sans-serif;
    font-size: 18pt;
    background: url('../img/bo_play_pattern.png') repeat;
    height: 100%;
    margin: 0;
    padding: 0;
    position: absolute;
    text-align: center;
    width: 100%;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

x-layout {
    border: 0;
}

#story {
    line-height: 125%;
    max-height: 60%;
    max-width: 400px;
    margin: 2em auto 0;
    overflow: scroll;
    padding: 0 .5em;
    position: relative;
}
#story.long:before {
    content: '↑';
    font-size: 60%;
    position: absolute;
    right: .1em;
    top: 0;
}
#story.long:after {
    content: '↓';
    font-size: 60%;
    position: absolute;
    right: .1em;
    top: 2em;
}

#home .button {
    bottom: 2em;
    left: 0;
    margin: 2em auto 0;
}

#wordpicker {
    padding-top: 2em;
}

#wordpicker input {
    display: block;
    font-size: 120%;
    margin: 1em auto;
    max-width: 400px;
    width: 90%;
}

#word {
    background-color: rgba(0, 0, 0, .5);
    border: 1px dashed lime;
    color: lime;
    font-family: monospace;
    font-size: 120%;
    letter-spacing: .2em;
    margin: 1em 0;
    padding: .5em;
}

#keys {
    margin: 3em auto 0;
    max-width: 90%;
    overflow: scroll;
    white-space: nowrap;
}

#keys button {
    height: 40px;
    width: 40px;
    margin: 4px;
    text-align: center;
}

#game aside {
    font-size: 60%;
}

@media (min-width: 700px) {
    #keys {
        max-width: 400px;
        overflow: visible;
        white-space: normal;
    }
    #keyboard aside {
        display: none;
    }
}

#tries {
    bottom: 1em;
    position: absolute;
    width: 100%;
}

.button {
    -moz-box-shadow:inset 0 1px 0 0 #fff;
    -webkit-box-shadow:inset 0 1px 0 0 #fff;
    box-shadow:inset 0 1px 0 0 #fff;
    background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ededed), color-stop(1, #dfdfdf));
    background:-moz-linear-gradient(center top, #ededed 5%, #dfdfdf 100%);
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed', endColorstr='#dfdfdf');
    background-color:#ededed;
    -moz-border-radius:6px;
    -webkit-border-radius:6px;
    border-radius:6px;
    border:1px solid #dcdcdc;
    display:inline-block;
    color:#777;
    font-family:arial;
    font-size:15px;
    font-weight:bold;
    padding:6px 24px;
    text-decoration:none;
    text-shadow:1px 1px 0 #fff;
}
.button:hover {
    background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #dfdfdf), color-stop(1, #ededed));
    background:-moz-linear-gradient(center top, #dfdfdf 5%, #ededed 100%);
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dfdfdf', endColorstr='#ededed');
    background-color:#dfdfdf;
}
.button:active {
    position:relative;
    top:1px;
}


text:
package groovy.lang;

import groovy.util.GroovyTestCase;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static groovy.lang.Tuple.tuple;

public class TupleTest extends GroovyTestCase {

    final Object[] data = {"a", "b", "c"};
    final Tuple t = new Tuple(data);

    public void testSize() {
        assertEquals("Size of " + t, 3, t.size());

        assertEquals("get(0)", "a", t.get(0));
        assertEquals("get(1)", "b", t.get(1));
    }

    public void testGetOutOfTuple() {
        try {
            t.get(-1);
            fail("Should have thrown IndexOut");
        } catch (IndexOutOfBoundsException e) {
            // worked
        }
        try {
            t.get(10);
            fail("Should have thrown IndexOut");
        } catch (IndexOutOfBoundsException e) {
            // worked
        }

    }

    public void testContains() {
        assertTrue("contains a", t.contains("a"));
        assertTrue("contains b", t.contains("b"));
    }

    public void testSubList() {
        List s = t.subList(1, 2);

        assertTrue("is a Tuple", s instanceof Tuple);

        assertEquals("size", 1, s.size());
    }

    public void testSubTuple() {
        Tuple s = t.subTuple(1, 2);

        assertTrue("is a Tuple", s instanceof Tuple);

        assertEquals("size", 1, s.size());
    }

    public void testHashCodeAndEquals() {
        Tuple a = new Tuple(new Object[]{"a", "b", "c"});
        Tuple b = new Tuple(new Object[]{"a", "b", "c"});
        Tuple c = new Tuple(new Object[]{"d", "b", "c"});
        Tuple d = new Tuple(new Object[]{"a", "b"});
        Tuple2<String, String> e = new Tuple2<String, String>("a", "b");
        Tuple2<String, String> f = new Tuple2<String, String>("a", "c");

        assertEquals("hashcode", a.hashCode(), b.hashCode());
        assertTrue("hashcode", a.hashCode() != c.hashCode());

        assertEquals("a and b", a, b);
        assertFalse("a != c", a.equals(c));

        assertFalse("!a.equals(null)", a.equals(null));

        assertTrue("d.equals(e)", d.equals(e));
        assertTrue("e.equals(d)", e.equals(d));
        assertFalse("!e.equals(f)", e.equals(f));
        assertFalse("!f.equals(e)", f.equals(e));
    }

    public void testIterator() {
    }

    public void testTuple1() {
        Tuple1<Integer> t = new Tuple1<>(1);

        assertEquals(1, t.size());

        assertEquals(new Integer(1), t.getFirst());
        assertEquals(1, t.get(0));

        assertEquals(t, t.subTuple(0, t.size()));
    }

    public void testTuple2() {
        Tuple2<Integer, Integer> t = new Tuple2<>(1, 2);

        assertEquals(2, t.size());

        assertEquals(new Integer(1), t.getFirst());
        assertEquals(1, t.get(0));

        assertEquals(new Integer(2), t.getSecond());
        assertEquals(2, t.get(1));

        assertEquals(t, t.subTuple(0, t.size()));
    }

    public void testTuple3() {
        Tuple3<Integer, Integer, Integer> t = new Tuple3<>(1, 2, 3);

        assertEquals(3, t.size());

        assertEquals(new Integer(1), t.getFirst());
        assertEquals(1, t.get(0));

        assertEquals(new Integer(2), t.getSecond());
        assertEquals(2, t.get(1));

        assertEquals(new Integer(3), t.getThird());
        assertEquals(3, t.get(2));

        assertEquals(t, t.subTuple(0, t.size()));
    }

    public void testTuple4() {
        Tuple4<Integer, Integer, Integer, Integer> t = new Tuple4<>(1, 2, 3, 4);

        assertEquals(4, t.size());

        assertEquals(new Integer(1), t.getFirst());
        assertEquals(1, t.get(0));

        assertEquals(new Integer(2), t.getSecond());
        assertEquals(2, t.get(1));

        assertEquals(new Integer(3), t.getThird());
        assertEquals(3, t.get(2));

        assertEquals(new Integer(4), t.getFourth());
        assertEquals(4, t.get(3));

        assertEquals(t, t.subTuple(0, t.size()));
    }

    public void testTuple5() {
        Tuple5<Integer, Integer, Integer, Integer, Integer> t = new Tuple5<>(1, 2, 3, 4, 5);

        assertEquals(5, t.size());

        assertEquals(new Integer(1), t.getFirst());
        assertEquals(1, t.get(0));

        assertEquals(new Integer(2), t.getSecond());
        assertEquals(2, t.get(1));

        assertEquals(new Integer(3), t.getThird());
        assertEquals(3, t.get(2));

        assertEquals(new Integer(4), t.getFourth());
        assertEquals(4, t.get(3));

        assertEquals(new Integer(5), t.getFifth());
        assertEquals(5, t.get(4));

        assertEquals(t, t.subTuple(0, t.size()));
    }

    public void testTuple6() {
        Tuple6<Integer, Integer, Integer, Integer, Integer, Integer> t = new Tuple6<>(1, 2, 3, 4, 5, 6);

        assertEquals(6, t.size());

        assertEquals(new Integer(1), t.getFirst());
        assertEquals(1, t.get(0));

        assertEquals(new Integer(2), t.getSecond());
        assertEquals(2, t.get(1));

        assertEquals(new Integer(3), t.getThird());
        assertEquals(3, t.get(2));

        assertEquals(new Integer(4), t.getFourth());
        assertEquals(4, t.get(3));

        assertEquals(new Integer(5), t.getFifth());
        assertEquals(5, t.get(4));

        assertEquals(new Integer(6), t.getSixth());
        assertEquals(6, t.get(5));

        assertEquals(t, t.subTuple(0, t.size()));
    }

    public void testTuple7() {
        Tuple7<Integer, Integer, Integer, Integer, Integer, Integer, Integer> t = new Tuple7<>(1, 2, 3, 4, 5, 6, 7);

        assertEquals(7, t.size());

        assertEquals(new Integer(1), t.getFirst());
        assertEquals(1, t.get(0));

        assertEquals(new Integer(2), t.getSecond());
        assertEquals(2, t.get(1));

        assertEquals(new Integer(3), t.getThird());
        assertEquals(3, t.get(2));

        assertEquals(new Integer(4), t.getFourth());
        assertEquals(4, t.get(3));

        assertEquals(new Integer(5), t.getFifth());
        assertEquals(5, t.get(4));

        assertEquals(new Integer(6), t.getSixth());
        assertEquals(6, t.get(5));

        assertEquals(new Integer(7), t.getSeventh());
        assertEquals(7, t.get(6));

        assertEquals(t, t.subTuple(0, t.size()));
    }

    public void testTuple8() {
        Tuple8<Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer> t = new Tuple8<>(1, 2, 3, 4, 5, 6, 7, 8);

        assertEquals(8, t.size());

        assertEquals(new Integer(1), t.getFirst());
        assertEquals(1, t.get(0));

        assertEquals(new Integer(2), t.getSecond());
        assertEquals(2, t.get(1));

        assertEquals(new Integer(3), t.getThird());
        assertEquals(3, t.get(2));

        assertEquals(new Integer(4), t.getFourth());
        assertEquals(4, t.get(3));

        assertEquals(new Integer(5), t.getFifth());
        assertEquals(5, t.get(4));

        assertEquals(new Integer(6), t.getSixth());
        assertEquals(6, t.get(5));

        assertEquals(new Integer(7), t.getSeventh());
        assertEquals(7, t.get(6));

        assertEquals(new Integer(8), t.getEighth());
        assertEquals(8, t.get(7));

        assertEquals(t, t.subTuple(0, t.size()));
    }

    public void testTuple9() {
        Tuple9<Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer> t = new Tuple9<>(1, 2, 3, 4, 5, 6, 7, 8, 9);

        assertEquals(9, t.size());

        assertEquals(new Integer(1), t.getFirst());
        assertEquals(1, t.get(0));

        assertEquals(new Integer(2), t.getSecond());
        assertEquals(2, t.get(1));

        assertEquals(new Integer(3), t.getThird());
        assertEquals(3, t.get(2));

        assertEquals(new Integer(4), t.getFourth());
        assertEquals(4, t.get(3));

        assertEquals(new Integer(5), t.getFifth());
        assertEquals(5, t.get(4));

        assertEquals(new Integer(6), t.getSixth());
        assertEquals(6, t.get(5));

        assertEquals(new Integer(7), t.getSeventh());
        assertEquals(7, t.get(6));

        assertEquals(new Integer(8), t.getEighth());
        assertEquals(8, t.get(7));

        assertEquals(new Integer(9), t.getNinth());
        assertEquals(9, t.get(8));

        assertEquals(t, t.subTuple(0, t.size()));
    }

    public void testEqualsHashCode() {
        Set<Tuple2<Integer, String>> set = new HashSet<>();

        set.add(tuple(1, "abc"));
        assertEquals(1, set.size());
        set.add(tuple(1, "abc"));
        assertEquals(1, set.size());
        set.add(tuple(null, null));
        assertEquals(2, set.size());
        set.add(tuple(null, null));
        assertEquals(2, set.size());
        set.add(tuple(1, null));
        assertEquals(3, set.size());
        set.add(tuple(1, null));
        assertEquals(3, set.size());
    }

    public void testEqualsNull() {
        assertFalse(tuple(1).equals(null));
        assertFalse(tuple(1, 2).equals(null));
        assertFalse(tuple(1, 2, 3).equals(null));
    }

    public void testGroovyStyleAccessor() {
        try {
            assertScript("def t = new Tuple1<String>('Daniel'); assert 'Daniel' == t.v1");
        } catch (Exception e) {
            assert false: e.getMessage();
        }
    }
}


text:
import './_helpers';
import storage, { StorageArea } from '..';
// import { StorageArea, storage } from '../src';

async function collectAsyncIterator (asyncIterator) {
  const array = [];
  for await (const entry of asyncIterator) {
    array.push(entry);
  }
  return array;
}

console.log({ StorageArea, storage });

describe('StorageArea', () => {
  let area;
  afterEach(async () => {
    if (area) {
      await area.clear();
      area = null;
    }
  });

  it('should be a class', () => {
    expect(typeof StorageArea).toBe('function');
  });

  describe('StorageArea#set', () => {
    it('should allow setting a value', async () => {
      area = new StorageArea('test_area');

      const result = await area.set('foo', 'bar');
      expect(result).not.toBeDefined();

      const got = await area.get('foo');
      expect(got).toBe('bar');
    });
  });

  describe('StorageArea#entries', () => {
    it('should return all key-value entry pairs', async () => {
      area = new StorageArea('test_area');

      await area.set('mycat', 'Tom');
      await area.set('mydog', 'Jerry');

      const entries = await collectAsyncIterator(area.entries());
      console.log(entries);
      expect(entries).toEqual([
        ['mycat', 'Tom'],
        ['mydog', 'Jerry']
      ]);
    });
  });

  describe('StorageArea#delete', () => {
    it('should be a thing', async () => {
      area = new StorageArea('test_area');

      await area.set('mycat', 'Tom');
      expect(await area.get('mycat')).toBe('Tom');

      await area.delete('mycat');

      expect(await area.get('mycat')).toBe(undefined);
    });
  });
});

describe('storage', () => {
  it('should be an instance of StorageArea', () => {
    expect(storage instanceof StorageArea).toBe(true);
  });
});


text:
from corehq.apps.groups.models import Group
from corehq.apps.users.models import CommCareUser, CouchUser
from corehq.apps.users.util import WEIRD_USER_IDS
from corehq.elastic import es_query, ES_URLS, stream_es_query, get_es
from corehq.pillows.mappings.user_mapping import USER_MAPPING, USER_INDEX
from couchforms.models import XFormInstance
from dimagi.utils.decorators.memoized import memoized
from pillowtop.listener import AliasedElasticPillow, BulkPillow
from django.conf import settings

class UserPillow(AliasedElasticPillow):
    """
    Simple/Common Case properties Indexer
    """

    document_class = CommCareUser   # while this index includes all users,
                                    # I assume we don't care about querying on properties specific to WebUsers
    couch_filter = "users/all_users"
    es_host = settings.ELASTICSEARCH_HOST
    es_port = settings.ELASTICSEARCH_PORT
    es_timeout = 60
    es_alias = "hqusers"
    es_type = "user"
    es_meta = {
        "settings": {
            "analysis": {
                "analyzer": {
                    "default": {
                        "type": "custom",
                        "tokenizer": "whitespace",
                        "filter": ["lowercase"]
                    },
                }
            }
        }
    }
    es_index = USER_INDEX
    default_mapping = USER_MAPPING

    @memoized
    def calc_meta(self):
        #todo: actually do this correctly

        """
        override of the meta calculator since we're separating out all the types,
        so we just do a hash of the "prototype" instead to determined md5
        """
        return self.calc_mapping_hash({"es_meta": self.es_meta,
                                       "mapping": self.default_mapping})

    def get_unique_id(self):
        return USER_INDEX

    def get_mapping_from_type(self, doc_dict):
        """
        Define mapping uniquely to the user_type document.
        See below on why date_detection is False

        NOTE: DO NOT MODIFY THIS UNLESS ABSOLUTELY NECESSARY. A CHANGE BELOW WILL GENERATE A NEW
        HASH FOR THE INDEX NAME REQUIRING A REINDEX+RE-ALIAS. THIS IS A SERIOUSLY RESOURCE
        INTENSIVE OPERATION THAT REQUIRES SOME CAREFUL LOGISTICS TO MIGRATE
        """
        #the meta here is defined for when the case index + type is created for the FIRST time
        #subsequent data added to it will be added automatically, but date_detection is necessary
        # to be false to prevent indexes from not being created due to the way we store dates
        #all are strings EXCEPT the core case properties which we need to explicitly define below.
        #that way date sort and ranges will work with canonical date formats for queries.
        return {
            self.get_type_string(doc_dict): self.default_mapping
        }

    def get_type_string(self, doc_dict):
        return self.es_type

class GroupToUserPillow(BulkPillow):
    couch_filter = "groups/all_groups"
    document_class = CommCareUser

    def __init__(self, **kwargs):
        super(GroupToUserPillow, self).__init__(**kwargs)
        self.couch_db = Group.get_db()

    def change_trigger(self, changes_dict):
        es = get_es()
        user_ids = changes_dict["doc"].get("users", [])
        q = {"filter": {"and": [{"terms": {"_id": user_ids}}]}}
        for user_source in stream_es_query(es_url=ES_URLS["users"], q=q, fields=["__group_ids", "__group_names"]):
            group_ids = set(user_source.get('fields', {}).get("__group_ids", []))
            group_names = set(user_source.get('fields', {}).get("__group_names", []))
            if changes_dict["doc"]["name"] not in group_names or changes_dict["doc"]["_id"] not in group_ids:
                group_ids.add(changes_dict["doc"]["_id"])
                group_names.add(changes_dict["doc"]["name"])
                doc = {"__group_ids": list(group_ids), "__group_names": list(group_names)}
                es.post("%s/user/%s/_update" % (USER_INDEX, user_source["_id"]), data={"doc": doc})

    def change_transport(self, doc_dict):
        pass

    def send_bulk(self, payload):
        pass

class UnknownUsersPillow(BulkPillow):
    """
        This pillow adds users from xform submissions that come in to the User Index if they don't exist in HQ
    """
    document_class = XFormInstance
    couch_filter = "couchforms/xforms"
    include_docs_when_preindexing = False

    def __init__(self, **kwargs):
        super(UnknownUsersPillow, self).__init__(**kwargs)
        self.couch_db = XFormInstance.get_db()
        self.user_db = CouchUser.get_db()
        self.es = get_es()

    def get_fields_from_emitted_dict(self, emitted_dict):
        domain = emitted_dict['key'][1]
        user_id = emitted_dict['value'].get('user_id')
        username = emitted_dict['value'].get('username')
        xform_id = emitted_dict['id']
        return user_id, username, domain, xform_id

    def get_fields_from_doc(self, doc):
        form_meta = doc.get('form', {}).get('meta', {})
        domain = doc.get('domain')
        user_id = form_meta.get('userID')
        username = form_meta.get('username')
        xform_id = doc.get('_id')
        return user_id, username, domain, xform_id

    @memoized
    def _user_exists(self, user_id):
        return self.user_db.doc_exist(user_id)

    def change_trigger(self, changes_dict):
        if 'key' in changes_dict:
            user_id, username, domain, xform_id = self.get_fields_from_emitted_dict(changes_dict)
        else:
            doc = changes_dict['doc'] if 'doc' in changes_dict else self.couch_db.open_doc(changes_dict['id'])
            user_id, username, domain, xform_id = self.get_fields_from_doc(doc)

        if user_id in WEIRD_USER_IDS:
            user_id = None

        es_path = USER_INDEX + "/user/"
        if (user_id and not self._user_exists(user_id)
                and not self.es.head(es_path + user_id)):
            doc_type = "AdminUser" if username == "admin" else "UnknownUser"
            doc = {
                "_id": user_id,
                "domain": domain,
                "username": username,
                "first_form_found_in": xform_id,
                "doc_type": doc_type,
            }
            if domain:
                doc["domain_membership"] = {"domain": domain}
            self.es.put(es_path + user_id, data=doc)

    def change_transport(self, doc_dict):
        pass

    def send_bulk(self, payload):
        pass

def add_demo_user_to_user_index():
    es = get_es()
    es_path = USER_INDEX + "/user/demo_user"
    es.put(es_path, data={"_id": "demo_user", "username": "demo_user", "doc_type": "DemoUser"})


text:
import { Observable } from 'rxjs/Observable';
import {CloudinaryService} from  './cloudinary.service'
import {CloudinaryModel} from './cloudinary.model';
import {
  inject,
  async,
  TestBed,
  tick,
  fakeAsync
} from '@angular/core/testing'
import {SharedModule} from "../../../shared/shared.module";
import {CloudinarySettingComponent} from "./cloudinary.component";
import {RouterTestingModule} from "@angular/router/testing";
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { By } from '@angular/platform-browser';

class MockService extends CloudinaryService {
  objModel: CloudinaryModel = new CloudinaryModel();

  constructor() {
    super(null);
    this.objModel._id = "123456abcdef";
    this.objModel.cloudinaryApiKey = "12345";
    this.objModel.cloudinaryApiSecret = "secret";
    this.objModel.cloudinaryCloudName = "cloudinay";
  }

  saveCloudinarySettings(objSave: CloudinaryModel): Observable<any> {
    return Observable.of({
      success: true,
      message: 'data saved successfully'
    });
  };

  updateCloudinarySettings(objUpdate: CloudinaryModel, id: string): Observable<any> {
    return Observable.of({
        success: true,
        message: 'data updated successfully'
      });
  }

  getCloudinarySettings(): Observable < CloudinaryModel > {
    return Observable.of(this.objModel);
  }
}

describe('Cloudinary settings', ()=> {

  beforeEach(()=> {
    TestBed.configureTestingModule({
      imports: [SharedModule, RouterTestingModule, BrowserAnimationsModule],
      declarations: [CloudinarySettingComponent],
      providers: [
        {provide: CloudinaryService, useClass: MockService}
      ]
    });
  });
  beforeEach(async(()=> {
    TestBed.compileComponents();
  }));

  it('should call the getCloudinary function after the component initiation', fakeAsync(() => {
    let fixture = TestBed.createComponent(CloudinarySettingComponent);
    let app = fixture.debugElement.componentInstance;
    spyOn(app, 'getCloudinarySetting');
    fixture.detectChanges();
    expect(app.getCloudinarySetting).toHaveBeenCalledTimes(1);
  }));

  it("should save the cloudinary setting if id isn't available", fakeAsync(()=> {
    const fixture = TestBed.createComponent(CloudinarySettingComponent);
    const app = fixture.debugElement.componentInstance;
    app.cloudinaryForm.controls.cloudinaryApiKey.patchValue("123");
    app.cloudinaryForm.controls.cloudinaryCloudName.patchValue("abc");
    app.cloudinaryForm.controls.cloudinaryApiSecret.patchValue("123");
    fixture.detectChanges();
    expect(app.cloudinaryForm.valid).toBeTruthy();
  }));

  it('should get the cloudinary setting if already saved', async(() => {
    let fixture = TestBed.createComponent(CloudinarySettingComponent);
    let component = fixture.debugElement.componentInstance;
    component.id = "123456abcdef";
    fixture.detectChanges();
    expect(component.id).toBeDefined();
    expect(component.cloudinaryForm.valid).toBe(true);
  }));

  it('should get swal message according to response', fakeAsync(() => {
    let fixture = TestBed.createComponent(CloudinarySettingComponent);
    let component = fixture.debugElement.componentInstance;
    expect(component.swalMessage).toBeUndefined();
    // spyOn(component, 'saveCloudinarySetting');
    // fixture.detectChanges();
    // fixture.detectChanges();
    // expect(component.saveCloudinarySetting).toHaveBeenCalledTimes(1);
  }));
});