(function(){var replacementNumbers = [];var mc = { cookieKey : 'comMatchCraftTestingNumber=',
           ignoreMutationChanges : false,
           pendingReplacementHandler : null,
           pendingReplacementNodes : [],
           phoneNumberReplacements : [],
           minNumberLength : 20 };

mc.onLoad = function() {
  mc.init();

  if (0 < mc.phoneNumberReplacements.length) {
    mc.replacePhoneNumbers();
    mc.ignoreMutationChanges = false;
    mc.observeMutationEvents();
  }
};

mc.observeMutationEvents = function() {
  if (window.MutationObserver) {
    new MutationObserver(mc.mutationObserverHandler).observe(document.body, { characterData: true, childList: true, subtree: true });

  } else if (window.WebKitMutationObserver) {
    new WebKitMutationObserver(mc.mutationObserverHandler).observe(document.body, { characterData: true, childList: true, subtree: true });

  } else if (window.MozMutationObserver) {
    new MozMutationObserver(mc.mutationObserverHandler).observe(document.body, { characterData: true, childList: true, subtree: true });

  } else if (document.body.addEventListener) {
    document.body.addEventListener('DOMCharacterDataModified', mc.mutationEventHandler, false);
    document.body.addEventListener('DOMNodeInserted', mc.mutationEventHandler, false);
    document.body.addEventListener('DOMNodeInsertedIntoDocument', mc.mutationEventHandler, false);
  }
};

mc.init = function() {
  var phoneNumbers = mc.getPhoneNumbers();
  for (var i = 0; i < phoneNumbers.length; ++i) {
    mc.minNumberLength = Math.min(mc.minNumberLength, phoneNumbers[i].from.length);
    mc.phoneNumberReplacements.push(mc.composeReplacementPattern(phoneNumbers[i]));
  }
};

mc.composeReplacementPattern = function(replacement) {
  var letters = new RegExp(/\D/);
  if (letters.test(replacement.from) || letters.test(replacement.to)) {
    var from = '';
    var specialChars = ['(',')','.','\u2010','-','[',']'];
    for (var i = 0; i < replacement.from.length; ++i) {
      var currentChar = replacement.from.charAt(i);
      if (-1 < specialChars.indexOf(currentChar)) {
        from += '\\' + currentChar;
      } else {
        from += currentChar;
      }
    }

    return { from: new RegExp(from, 'g'),
	     to: replacement.to };
  } else {
    var from = '';
    var to = '';
    replacement.from = replacement.from.replace(/[,\.\u2010\- ()\[\]]/g, '');
    replacement.to = replacement.to.replace(/[,\.\u2010\- ()\[\]]/g, '');

    for (var i = 0; i < replacement.from.length; ++i) {
      from += replacement.from.charAt(i) + '(\\s*[,\\.\\u2010\\u2011\\u2022\\u00AD\\-()\\[\\]]{0,2}\\s*)';
      if (i < replacement.to.length) {
	to += replacement.to.charAt(i) + '$' + (i < 9
						? ('0' + (i + 1))
						: (i + 1));
      }
    }

    if (replacement.from.length < replacement.to.length) {
      to += replacement.to.substring(replacement.from.length);
    }

    return { from: new RegExp(from, 'g'), to: to };
  }
};

mc.getPhoneNumbers = function() {
  var numbers = (typeof(replacementNumbers) !== 'undefined'
                 ? replacementNumbers
                 : []);

  if (!numbers || 0 === numbers.length) {
    numbers = [];
    //get the prefefined test phone number
    var encodedNumber= mc.getTestPhoneNumberFromSearch();
    if (encodedNumber) {
      mc.storeTestPhoneNumberInCookie(encodedNumber);
    } else {
      encodedNumber= mc.getTestPhoneNumberFromCookie();
    }

    if (encodedNumber) {
      var values = atob(encodedNumber
			.replace(/\./g, '=')
			.replace(/-/g, '+')
			.replace(/_/g, '/'))
	.split('|');
      for (var i = 0; i < values.length; i += 2) {
        var pair = mc.composePhoneNumbersOrNull([values[i], values[i+1]]);
        if (pair) {
          numbers.push(pair);
        }
      }
    }
  }

  return numbers;
};

mc.getTestPhoneNumberFromSearch = function() {
  var queryString = (top.location.search
                     ? top.location.search.substring(1)
                     : null);
  if (queryString) {
    var queryStringArray = queryString.split('&');
    for (var i = 0; i < queryStringArray.length; i++) {
      if (new RegExp("^" + mc.cookieKey + ".*", "i").test(queryStringArray[i])) {
        return queryStringArray[i].substring(mc.cookieKey.length);
      }
    }
  }

  return '';
};

mc.storeTestPhoneNumberInCookie = function(numbers) {
  var value = mc.cookieKey + numbers;

  var date = new Date();
  date.setDate(date.getDate() + 1);

  value += ';expires=' + date.toGMTString() + ';path=/';

  document.cookie = value;
};

mc.getTestPhoneNumberFromCookie = function() {
  var encodedNumber;

  if (document.cookie) {
    var crumbs = document.cookie.split('; ');
    for (var i = 0; i < crumbs.length; ++i) {
      if (mc.cookieKey == crumbs[i].substring(0, mc.cookieKey.length)) {
        encodedNumber = crumbs[i].substring(mc.cookieKey.length);
        break;
      }
    }
  }

  return encodedNumber;
};


mc.composePhoneNumbersOrNull = function(numbers) {
  if (2 == numbers.length) {
    var first = numbers[0];
    var second = numbers[1];

    if (''.trim) {
      first = first.trim();
      second = second.trim();
    } else {
      first = first.replace(/^\s+|\s+$/g, '');
      second = second.replace(/^\s+|\s+$/g, '');
    }

    if (0 != first.length && 0 != second.length) {
      return { from: first, to: second };
    }
  }

  return null;
};

mc.replacePhoneNumbers = function() {
  mc.ignoreMutationChanges = true;

  if (0 < mc.pendingReplacementNodes.length && document.createTreeWalker) {
    mc.pendingReplacementNodes.forEach(function(node) {
      var walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, null, false);
      while(node = walker.nextNode()) {
        mc.replacePhoneNumbersAtNode(node);
      }
    });

  } else if (0 < mc.pendingReplacementNodes.length) {
    for (var i = 0; i < mc.pendingReplacementNodes.length; ++i) {
      mc.replacePhoneNumbersInNodes(mc.pendingReplacementNodes[i]);
    }

  } else if (document.createTreeWalker) {
    var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, null, false);
    while(node = walker.nextNode()) {
      mc.replacePhoneNumbersAtNode(node);
    }

  } else {
    mc.replacePhoneNumbersFromNodes(document.body);
  }

  window.setTimeout(function() {
    mc.ignoreMutationChanges = false;
  }, 1);
};

mc.replacePhoneNumbersInNodes = function(root) {
  var node = root;
  while (null != node) {
    if (3 === node.nodeType || 1 === node.nodeType) {
      mc.replacePhoneNumbersAtNode(node);
    }

    if (node.hasChildNodes()) {
      node = node.firstChild;

    } else {
      while(null == node.nextSibling && node != root) {
        node = node.parentNode;
      }

      node = node.nextSibling;
    }
  }
};

mc.replacePhoneNumbersAtNode = function(node) {
  var newVal;
  if (1 === node.nodeType && ('a' === node.tagName || 'A' === node.tagName)) {
    if (node.href && node.href.indexOf && 0 === node.href.indexOf('tel:')) {
      newVal = mc.replacePhoneNumbersInText(node.href);
      if (node.href !== newVal) node.href = newVal;
    }

    if (node.title) {
      newVal = mc.replacePhoneNumbersInText(node.title);
      if (node.title !== newVal) node.title = newVal;
    }

  } else {
    if (node.nodeValue) {
      if (mc.minNumberLength <= node.nodeValue.length) {
	newVal = mc.replacePhoneNumbersInText(node.nodeValue);
	if (node.nodeValue !== newVal) node.nodeValue = newVal;
      }
    }
  }
};

mc.replacePhoneNumbersInText = function(text) {
  for (var i = 0; i < mc.phoneNumberReplacements.length; ++i) {
    text = text.replace(mc.phoneNumberReplacements[i].from,
                        mc.phoneNumberReplacements[i].to);
  }

  return text;
};

mc.mutationObserverHandler = function(mutations) {
  mc.scheduleHandler(mc.replacePhoneNumbers, mutations);
};

mc.mutationEventHandler = function() {
  mc.scheduleHandler(mc.replacePhoneNumbers, null);
};

mc.scheduleHandler = function(handler, mutations) {
  if (mc.ignoreMutationChanges) {
    return;
  }

  if (mc.pendingReplacementHandler) {
    return;
  }

  mc.pendingReplacementNodes = [];

  if (mutations && mutations.forEach) {
    mutations.forEach(function(mutation) {
      mc.pendingReplacementNodes.push(mutation.target);
    });
  }

  mc.pendingReplacementHandler = handler;

  window.setTimeout(function() {
    if (mc.pendingReplacementHandler) {
      mc.pendingReplacementHandler();
      mc.pendingReplacementHandler = null;
      mc.pendingReplacementNodes = [];
    }
  }, 1);
};

if ('interactive' === document.readyState
    || 'complete' === document.readyState
    || 'loaded' === document.readyState) {
  mc.onLoad();

} else {
  document.addEventListener('DOMContentLoaded', mc.onLoad);
}
})();