<commit_before>import has from 'lodash/has';
import cloneDeepWith from 'lodash/cloneDeepWith';
import toArray from 'lodash/toArray';

import { mixed as locale } from './locale';
import Condition from './Condition';
import runTests from './util/runTests';
import prependDeep from './util/prependDeep';
import isSchema from './util/isSchema';
import createValidation from './util/createValidation';
import printValue from './util/printValue';
import Ref from './Reference';
import { getIn } from './util/reach';

class RefSet {
  constructor() {
    this.list = new Set();
    this.refs = new Map();
  }
  get size() {
    return this.list.size + this.refs.size;
  }
  describe() {
    const description = [];

    for (const item of this.list) description.push(item);
    for (const [, ref] of this.refs) description.push(ref.describe());

    return description;
  }
  toArray() {
    return toArray(this.list).concat(toArray(this.refs.values()));
  }
  add(value) {
    Ref.isRef(value) ? this.refs.set(value.key, value) : this.list.add(value);
  }
  delete(value) {
    Ref.isRef(value) ? this.refs.delete(value.key) : this.list.delete(value);
  }
  has(value, resolve) {
    if (this.list.has(value)) return true;

    let item,
      values = this.refs.values();
    while (((item = values.next()), !item.done))
      if (resolve(item.value) === value) return true;

    return false;
  }
  clone() {
    const next = new RefSet();
    next.list = new Set(this.list);
    next.refs = new Map(this.refs);
    return next;
  }
  merge(newItems, removeItems) {
    const next = this.clone();
    newItems.list.forEach((value) => next.add(value));
    newItems.refs.forEach((value) => next.add(value));
    removeItems.list.forEach((value) => next.delete(value));
    removeItems.refs.forEach((value) => next.delete(value));
    return next;
  }
}

export default function SchemaType(options = {}) {
  if (!(this instanceof SchemaType)) return new SchemaType();

  this._deps = [];
  this._conditions = [];
  this._options = { abortEarly: true, recursive: true };
  this._exclusive = Object.create(null);

  this._whitelist = new RefSet();
  this._blacklist = new RefSet();

  this.tests = [];
  this.transforms = [];

  this.withMutation(() => {
    this.typeError(locale.notType);
  });

  if (has(options, 'default')) this._defaultDefault = options.default;

  this.type = options.type || 'mixed';
  // TODO: remove
  this._type = options.type || 'mixed';
}

const proto = (SchemaType.prototype = {
  __isYupSchema__: true,

  constructor: SchemaType,

  clone() {
    if (this._mutate) return this;

    // if the nested value is a schema we can skip cloning, since
    // they are already immutable
    return cloneDeepWith(this, (value) => {
      if (isSchema(value) && value !== this) return value;
    });
  },

  label(label) {
    var next = this.clone();
    next._label = label;
    return next;
  },

  meta(obj) {
    if (arguments.length === 0) return this._meta;

    var next = this.clone();
    next._meta = Object.assign(next._meta || {}, obj);
    return next;
  },

  withMutation(fn) {
    let before = this._mutate;
    this._mutate = true;
    let result = fn(this);
    this._mutate = before;
    return result;
  },

  concat(schema) {<commit_msg>fix: IE11 clone() (#1029)<commit_after>import has from 'lodash/has';
import cloneDeepWith from 'lodash/cloneDeepWith';
import toArray from 'lodash/toArray';

import { mixed as locale } from './locale';
import Condition from './Condition';
import runTests from './util/runTests';
import prependDeep from './util/prependDeep';
import isSchema from './util/isSchema';
import createValidation from './util/createValidation';
import printValue from './util/printValue';
import Ref from './Reference';
import { getIn } from './util/reach';

class RefSet {
  constructor() {
    this.list = new Set();
    this.refs = new Map();
  }
  get size() {
    return this.list.size + this.refs.size;
  }
  describe() {
    const description = [];

    for (const item of this.list) description.push(item);
    for (const [, ref] of this.refs) description.push(ref.describe());

    return description;
  }
  toArray() {
    return toArray(this.list).concat(toArray(this.refs.values()));
  }
  add(value) {
    Ref.isRef(value) ? this.refs.set(value.key, value) : this.list.add(value);
  }
  delete(value) {
    Ref.isRef(value) ? this.refs.delete(value.key) : this.list.delete(value);
  }
  has(value, resolve) {
    if (this.list.has(value)) return true;

    let item,
      values = this.refs.values();
    while (((item = values.next()), !item.done))
      if (resolve(item.value) === value) return true;

    return false;
  }
  clone() {
    const next = new RefSet();
    next.list = new Set(this.list);
    next.refs = new Map(this.refs);
    return next;
  }
  merge(newItems, removeItems) {
    const next = this.clone();
    newItems.list.forEach((value) => next.add(value));
    newItems.refs.forEach((value) => next.add(value));
    removeItems.list.forEach((value) => next.delete(value));
    removeItems.refs.forEach((value) => next.delete(value));
    return next;
  }
}

export default function SchemaType(options = {}) {
  if (!(this instanceof SchemaType)) return new SchemaType();

  this._deps = [];
  this._conditions = [];
  this._options = { abortEarly: true, recursive: true };
  this._exclusive = Object.create(null);

  this._whitelist = new RefSet();
  this._blacklist = new RefSet();

  this.tests = [];
  this.transforms = [];

  this.withMutation(() => {
    this.typeError(locale.notType);
  });

  if (has(options, 'default')) this._defaultDefault = options.default;

  this.type = options.type || 'mixed';
  // TODO: remove
  this._type = options.type || 'mixed';
}

const proto = (SchemaType.prototype = {
  __isYupSchema__: true,

  constructor: SchemaType,

  clone() {
    if (this._mutate) return this;

    // if the nested value is a schema we can skip cloning, since
    // they are already immutable
    return cloneDeepWith(this, (value, key) => {
      if (isSchema(value) && value !== this) return value;

      // fix for ie11 when cloning Set and Map
      if (key === '_whitelist' || key === '_blacklist') {
        return value.clone();
      }
    });
  },

  label(label) {
    var next = this.clone();
    next._label = label;
    return next;
  },

  meta(obj) {
    if (arguments.length === 0) return this._meta;

    var next = this.clone();
    next._meta = Object.assign(next._meta || {}, obj);
    return next;
  },

  withMutation(fn) {
    let before = this._mutate;
    this._mutate = true;
    let result = fn(this);
    this._mutate = before;
    return result;
  },

  concat(schema) {
{'fraction_non_alphanumeric': 0.15844388135340587, 'fraction_numerical': 0.0014905351021016545, 'mean_word_length': 3.2042606516290726, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4897642', 'n_tokens_mistral': 2208, 'n_tokens_neox': 2121, 'n_words': 535}