




Function.prototype.bind = function(thisObject)
{
var func = this;
var args = Array.prototype.slice.call(arguments, 1);
function bound()
{
return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0)));
}
bound.toString = function() {
return "bound: " + func;
};
return bound;
}

Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction)
{
var startNode;
var startOffset = 0;
var endNode;
var endOffset = 0;

if (!stayWithinNode)
stayWithinNode = this;

if (!direction || direction === "backward" || direction === "both") {
var node = this;
while (node) {
if (node === stayWithinNode) {
if (!startNode)
startNode = stayWithinNode;
break;
}

if (node.nodeType === Node.TEXT_NODE) {
var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1));
for (var i = start; i >= 0; --i) {
if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
startNode = node;
startOffset = i + 1;
break;
}
}
}

if (startNode)
break;

node = node.traversePreviousNode(stayWithinNode);
}

if (!startNode) {
startNode = stayWithinNode;
startOffset = 0;
}
} else {
startNode = this;
startOffset = offset;
}

if (!direction || direction === "forward" || direction === "both") {
node = this;
while (node) {
if (node === stayWithinNode) {
if (!endNode)
endNode = stayWithinNode;
break;
}

if (node.nodeType === Node.TEXT_NODE) {
var start = (node === this ? offset : 0);
for (var i = start; i < node.nodeValue.length; ++i) {
if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
endNode = node;
endOffset = i;
break;
}
}
}

if (endNode)
break;

node = node.traverseNextNode(stayWithinNode);
}

if (!endNode) {
endNode = stayWithinNode;
endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length : stayWithinNode.childNodes.length;
}
} else {
endNode = this;
endOffset = offset;
}

var result = this.ownerDocument.createRange();
result.setStart(startNode, startOffset);
result.setEnd(endNode, endOffset);

return result;
}

Node.prototype.traverseNextTextNode = function(stayWithin)
{
var node = this.traverseNextNode(stayWithin);
if (!node)
return;

while (node && node.nodeType !== Node.TEXT_NODE)
node = node.traverseNextNode(stayWithin);

return node;
}

Node.prototype.rangeBoundaryForOffset = function(offset)
{
var node = this.traverseNextTextNode(this);
while (node && offset > node.nodeValue.length) {
offset -= node.nodeValue.length;
node = node.traverseNextTextNode(this);
}
if (!node)
return { container: this, offset: 0 };
return { container: node, offset: offset };
}

Element.prototype.removeStyleClass = function(className) 
{

if (this.className === className) {
this.className = "";
return;
}

var index = this.className.indexOf(className);
if (index === -1)
return;

this.className = this.className.split(" ").filter(function(s) {
return s && s !== className;
}).join(" ");
}

Element.prototype.removeMatchingStyleClasses = function(classNameRegex)
{
var regex = new RegExp("(^|\\s+)" + classNameRegex + "($|\\s+)");
if (regex.test(this.className))
this.className = this.className.replace(regex, " ");
}

Element.prototype.addStyleClass = function(className) 
{
if (className && !this.hasStyleClass(className))
this.className += (this.className.length ? " " + className : className);
}

Element.prototype.hasStyleClass = function(className) 
{
if (!className)
return false;

if (this.className === className)
return true;

var index = this.className.indexOf(className);
if (index === -1)
return false;
var toTest = " " + this.className + " ";
return toTest.indexOf(" " + className + " ", index) !== -1;
}

Element.prototype.positionAt = function(x, y)
{
this.style.left = x + "px";
this.style.top = y + "px";
}

Element.prototype.pruneEmptyTextNodes = function()
{
var sibling = this.firstChild;
while (sibling) {
var nextSibling = sibling.nextSibling;
if (sibling.nodeType === this.TEXT_NODE && sibling.nodeValue === "")
this.removeChild(sibling);
sibling = nextSibling;
}
}

Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
{
for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
for (var i = 0; i < nameArray.length; ++i)
if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
return node;
return null;
}

Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
{
return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
}

Node.prototype.enclosingNodeOrSelfWithClass = function(className)
{
for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className))
return node;
return null;
}

Node.prototype.enclosingNodeWithClass = function(className)
{
if (!this.parentNode)
return null;
return this.parentNode.enclosingNodeOrSelfWithClass(className);
}

Element.prototype.query = function(query) 
{
return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

Element.prototype.removeChildren = function()
{
if (this.firstChild)
this.textContent = "";
}

Element.prototype.isInsertionCaretInside = function()
{
var selection = window.getSelection();
if (!selection.rangeCount || !selection.isCollapsed)
return false;
var selectionRange = selection.getRangeAt(0);
return selectionRange.startContainer === this || selectionRange.startContainer.isDescendant(this);
}

Element.prototype.createChild = function(elementName, className)
{
var element = document.createElement(elementName);
if (className)
element.className = className;
this.appendChild(element);
return element;
}

Element.prototype.__defineGetter__("totalOffsetLeft", function()
{
var total = 0;
for (var element = this; element; element = element.offsetParent)
total += element.offsetLeft + (this !== element ? element.clientLeft : 0);
return total;
});

Element.prototype.__defineGetter__("totalOffsetTop", function()
{
var total = 0;
for (var element = this; element; element = element.offsetParent)
total += element.offsetTop + (this !== element ? element.clientTop : 0);
return total;
});

Element.prototype.offsetRelativeToWindow = function(targetWindow)
{
var elementOffset = {x: 0, y: 0};
var curElement = this;
var curWindow = this.ownerDocument.defaultView;
while (curWindow && curElement) {
elementOffset.x += curElement.totalOffsetLeft;
elementOffset.y += curElement.totalOffsetTop;
if (curWindow === targetWindow)
break;

curElement = curWindow.frameElement;
curWindow = curWindow.parent;
}

return elementOffset;
}

KeyboardEvent.prototype.__defineGetter__("data", function()
{


switch (this.type) {
case "keypress":
if (!this.ctrlKey && !this.metaKey)
return String.fromCharCode(this.charCode);
else
return "";
case "keydown":
case "keyup":
if (!this.ctrlKey && !this.metaKey && !this.altKey)
return String.fromCharCode(this.which);
else
return "";
}
});

Text.prototype.select = function(start, end)
{
start = start || 0;
end = end || this.textContent.length;

if (start < 0)
start = end + start;

var selection = window.getSelection();
selection.removeAllRanges();
var range = document.createRange();
range.setStart(this, start);
range.setEnd(this, end);
selection.addRange(range);
return this;
}

Element.prototype.__defineGetter__("selectionLeftOffset", function() {


var selection = window.getSelection();
if (!selection.containsNode(this, true))
return null;

var leftOffset = selection.anchorOffset;
var node = selection.anchorNode;

while (node !== this) {
while (node.previousSibling) {
node = node.previousSibling;
leftOffset += node.textContent.length;
}
node = node.parentNode;
}

return leftOffset;
});

Node.prototype.isWhitespace = isNodeWhitespace;
Node.prototype.displayName = nodeDisplayName;
Node.prototype.isAncestor = function(node)
{
return isAncestorNode(this, node);
};
Node.prototype.isDescendant = isDescendantNode;
Node.prototype.traverseNextNode = traverseNextNode;
Node.prototype.traversePreviousNode = traversePreviousNode;
Node.prototype.onlyTextChild = onlyTextChild;

String.prototype.hasSubstring = function(string, caseInsensitive)
{
if (!caseInsensitive)
return this.indexOf(string) !== -1;
return this.match(new RegExp(string.escapeForRegExp(), "i"));
}

String.prototype.asParsedURL = function()
{






var match = this.match(/^([^:]+):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
if (!match)
return null;
var result = {};
result.scheme = match[1].toLowerCase();
result.host = match[2];
result.port = match[3];
result.path = match[4] || "/";
result.fragment = match[5];
return result;
}

String.prototype.escapeCharacters = function(chars)
{
var foundChar = false;
for (var i = 0; i < chars.length; ++i) {
if (this.indexOf(chars.charAt(i)) !== -1) {
foundChar = true;
break;
}
}

if (!foundChar)
return this;

var result = "";
for (var i = 0; i < this.length; ++i) {
if (chars.indexOf(this.charAt(i)) !== -1)
result += "\\";
result += this.charAt(i);
}

return result;
}

String.prototype.escapeForRegExp = function()
{
return this.escapeCharacters("^[]{}()\\.$*+?|");
}

String.prototype.escapeHTML = function()
{
return this.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
}

String.prototype.collapseWhitespace = function()
{
return this.replace(/[\s\xA0]+/g, " ");
}

String.prototype.trimURL = function(baseURLDomain)
{
var result = this.replace(/^(https|http|file):\/\//i, "");
if (baseURLDomain)
result = result.replace(new RegExp("^" + baseURLDomain.escapeForRegExp(), "i"), "");
return result;
}

function isNodeWhitespace()
{
if (!this || this.nodeType !== Node.TEXT_NODE)
return false;
if (!this.nodeValue.length)
return true;
return this.nodeValue.match(/^[\s\xA0]+$/);
}

function nodeDisplayName()
{
if (!this)
return "";

switch (this.nodeType) {
case Node.DOCUMENT_NODE:
return "Document";

case Node.ELEMENT_NODE:
var name = "<" + this.nodeName.toLowerCase();

if (this.hasAttributes()) {
var value = this.getAttribute("id");
if (value)
name += " id=\"" + value + "\"";
value = this.getAttribute("class");
if (value)
name += " class=\"" + value + "\"";
if (this.nodeName.toLowerCase() === "a") {
value = this.getAttribute("name");
if (value)
name += " name=\"" + value + "\"";
value = this.getAttribute("href");
if (value)
name += " href=\"" + value + "\"";
} else if (this.nodeName.toLowerCase() === "img") {
value = this.getAttribute("src");
if (value)
name += " src=\"" + value + "\"";
} else if (this.nodeName.toLowerCase() === "iframe") {
value = this.getAttribute("src");
if (value)
name += " src=\"" + value + "\"";
} else if (this.nodeName.toLowerCase() === "input") {
value = this.getAttribute("name");
if (value)
name += " name=\"" + value + "\"";
value = this.getAttribute("type");
if (value)
name += " type=\"" + value + "\"";
} else if (this.nodeName.toLowerCase() === "form") {
value = this.getAttribute("action");
if (value)
name += " action=\"" + value + "\"";
}
}

return name + ">";

case Node.TEXT_NODE:
if (isNodeWhitespace.call(this))
return "(whitespace)";
return "\"" + this.nodeValue + "\"";

case Node.COMMENT_NODE:
return "<!--" + this.nodeValue + "-->";

case Node.DOCUMENT_TYPE_NODE:
var docType = "<!DOCTYPE " + this.nodeName;
if (this.publicId) {
docType += " PUBLIC \"" + this.publicId + "\"";
if (this.systemId)
docType += " \"" + this.systemId + "\"";
} else if (this.systemId)
docType += " SYSTEM \"" + this.systemId + "\"";
if (this.internalSubset)
docType += " [" + this.internalSubset + "]";
return docType + ">";
}

return this.nodeName.toLowerCase().collapseWhitespace();
}

function isAncestorNode(ancestor, node)
{
if (!node || !ancestor)
return false;

var currentNode = node.parentNode;
while (currentNode) {
if (ancestor === currentNode)
return true;
currentNode = currentNode.parentNode;
}
return false;
}

function isDescendantNode(descendant)
{
return isAncestorNode(descendant, this);
}

function traverseNextNode(stayWithin)
{
if (!this)
return;

var node = this.firstChild;
if (node)
return node;

if (stayWithin && this === stayWithin)
return null;

node = this.nextSibling;
if (node)
return node;

node = this;
while (node && !node.nextSibling && (!stayWithin || !node.parentNode || node.parentNode !== stayWithin))
node = node.parentNode;
if (!node)
return null;

return node.nextSibling;
}

function traversePreviousNode(stayWithin)
{
if (!this)
return;
if (stayWithin && this === stayWithin)
return null;
var node = this.previousSibling;
while (node && node.lastChild)
node = node.lastChild;
if (node)
return node;
return this.parentNode;
}

function onlyTextChild()
{
if (!this)
return null;

var firstChild = this.firstChild;
if (!firstChild || firstChild.nodeType !== Node.TEXT_NODE)
return null;

var sibling = firstChild.nextSibling;
return sibling ? null : firstChild;
}

function appropriateSelectorForNode(node, justSelector)
{
if (!node)
return "";

var lowerCaseName = node.localName || node.nodeName.toLowerCase();

var id = node.getAttribute("id");
if (id) {
var selector = "#" + id;
return (justSelector ? selector : lowerCaseName + selector);
}

var className = node.getAttribute("class");
if (className) {
var selector = "." + className.replace(/\s+/, ".");
return (justSelector ? selector : lowerCaseName + selector);
}

if (lowerCaseName === "input" && node.getAttribute("type"))
return lowerCaseName + "[type=\"" + node.getAttribute("type") + "\"]";

return lowerCaseName;
}

function getDocumentForNode(node)
{
return node.nodeType == Node.DOCUMENT_NODE ? node : node.ownerDocument;
}

function parentNode(node)
{
return node.parentNode;
}

Number.millisToString = function(ms, formatterFunction, higherResolution)
{
return Number.secondsToString(ms / 1000, formatterFunction, higherResolution);
}

Number.secondsToString = function(seconds, formatterFunction, higherResolution)
{
if (!formatterFunction)
formatterFunction = String.sprintf;

if (seconds === 0)
return "0";

var ms = seconds * 1000;
if (higherResolution && ms < 1000)
return formatterFunction("%.3fms", ms);
else if (ms < 1000)
return formatterFunction("%.0fms", ms);

if (seconds < 60)
return formatterFunction("%.2fs", seconds);

var minutes = seconds / 60;
if (minutes < 60)
return formatterFunction("%.1fmin", minutes);

var hours = minutes / 60;
if (hours < 24)
return formatterFunction("%.1fhrs", hours);

var days = hours / 24;
return formatterFunction("%.1f days", days);
}

Number.bytesToString = function(bytes, formatterFunction, higherResolution)
{
if (!formatterFunction)
formatterFunction = String.sprintf;
if (typeof higherResolution === "undefined")
higherResolution = true;

if (bytes < 1024)
return formatterFunction("%.0fB", bytes);

var kilobytes = bytes / 1024;
if (higherResolution && kilobytes < 1024)
return formatterFunction("%.2fKB", kilobytes);
else if (kilobytes < 1024)
return formatterFunction("%.0fKB", kilobytes);

var megabytes = kilobytes / 1024;
if (higherResolution)
return formatterFunction("%.2fMB", megabytes);
else
return formatterFunction("%.0fMB", megabytes);
}

Number.constrain = function(num, min, max)
{
if (num < min)
num = min;
else if (num > max)
num = max;
return num;
}

HTMLTextAreaElement.prototype.moveCursorToEnd = function()
{
var length = this.value.length;
this.setSelectionRange(length, length);
}

Array.prototype.remove = function(value, onlyFirst)
{
if (onlyFirst) {
var index = this.indexOf(value);
if (index !== -1)
this.splice(index, 1);
return;
}

var length = this.length;
for (var i = 0; i < length; ++i) {
if (this[i] === value)
this.splice(i, 1);
}
}

Array.prototype.keySet = function()
{
var keys = {};
for (var i = 0; i < this.length; ++i)
keys[this[i]] = true;
return keys;
}

Array.diff = function(left, right)
{
var o = left;
var n = right;

var ns = {};
var os = {};

for (var i = 0; i < n.length; i++) {
if (ns[n[i]] == null)
ns[n[i]] = { rows: [], o: null };
ns[n[i]].rows.push(i);
}

for (var i = 0; i < o.length; i++) {
if (os[o[i]] == null)
os[o[i]] = { rows: [], n: null };
os[o[i]].rows.push(i);
}

for (var i in ns) {
if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {
n[ns[i].rows[0]] = { text: n[ns[i].rows[0]], row: os[i].rows[0] };
o[os[i].rows[0]] = { text: o[os[i].rows[0]], row: ns[i].rows[0] };
}
}

for (var i = 0; i < n.length - 1; i++) {
if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && n[i + 1] == o[n[i].row + 1]) {
n[i + 1] = { text: n[i + 1], row: n[i].row + 1 };
o[n[i].row + 1] = { text: o[n[i].row + 1], row: i + 1 };
}
}

for (var i = n.length - 1; i > 0; i--) {
if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && 
n[i - 1] == o[n[i].row - 1]) {
n[i - 1] = { text: n[i - 1], row: n[i].row - 1 };
o[n[i].row - 1] = { text: o[n[i].row - 1], row: i - 1 };
}
}

return { left: o, right: n };
}

Array.convert = function(list)
{

return Array.prototype.slice.call(list);
}

function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction)
{
var first = 0;
var last = aList.length - 1;
var floor = Math.floor;
var mid, c;

while (first <= last) {
mid = floor((first + last) / 2);
c = aFunction(anObject, aList[mid]);

if (c > 0)
first = mid + 1;
else if (c < 0)
last = mid - 1;
else {

while (mid > 0 && aFunction(anObject, aList[mid - 1]) === 0)
mid--;
first = mid;
break;
}
}

return first;
}

String.sprintf = function(format)
{
return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
}

String.tokenizeFormatString = function(format)
{
var tokens = [];
var substitutionIndex = 0;

function addStringToken(str)
{
tokens.push({ type: "string", value: str });
}

function addSpecifierToken(specifier, precision, substitutionIndex)
{
tokens.push({ type: "specifier", specifier: specifier, precision: precision, substitutionIndex: substitutionIndex });
}

var index = 0;
for (var precentIndex = format.indexOf("%", index); precentIndex !== -1; precentIndex = format.indexOf("%", index)) {
addStringToken(format.substring(index, precentIndex));
index = precentIndex + 1;

if (format[index] === "%") {
addStringToken("%");
++index;
continue;
}

if (!isNaN(format[index])) {

var number = parseInt(format.substring(index));
while (!isNaN(format[index]))
++index;


if (number > 0 && format[index] === "$") {
substitutionIndex = (number - 1);
++index;
}
}

var precision = -1;
if (format[index] === ".") {


++index;
precision = parseInt(format.substring(index));
if (isNaN(precision))
precision = 0;
while (!isNaN(format[index]))
++index;
}

addSpecifierToken(format[index], precision, substitutionIndex);

++substitutionIndex;
++index;
}

addStringToken(format.substring(index));

return tokens;
}

String.standardFormatters = {
d: function(substitution)
{
if (typeof substitution == "object" && WebInspector.RemoteObject.type(substitution) === "number")
substitution = substitution.description;
substitution = parseInt(substitution);
return !isNaN(substitution) ? substitution : 0;
},

f: function(substitution, token)
{
if (typeof substitution == "object" && WebInspector.RemoteObject.type(substitution) === "number")
substitution = substitution.description;
substitution = parseFloat(substitution);
if (substitution && token.precision > -1)
substitution = substitution.toFixed(token.precision);
return !isNaN(substitution) ? substitution : (token.precision > -1 ? Number(0).toFixed(token.precision) : 0);
},

s: function(substitution)
{
if (typeof substitution == "object" && WebInspector.RemoteObject.type(substitution) !== "null")
substitution = substitution.description;
return substitution;
},
};

String.vsprintf = function(format, substitutions)
{
return String.format(format, substitutions, String.standardFormatters, "", function(a, b) { return a + b; }).formattedResult;
}

String.format = function(format, substitutions, formatters, initialValue, append)
{
if (!format || !substitutions || !substitutions.length)
return { formattedResult: append(initialValue, format), unusedSubstitutions: substitutions };

function prettyFunctionName()
{
return "String.format(\"" + format + "\", \"" + substitutions.join("\", \"") + "\")";
}

function warn(msg)
{
console.warn(prettyFunctionName() + ": " + msg);
}

function error(msg)
{
console.error(prettyFunctionName() + ": " + msg);
}

var result = initialValue;
var tokens = String.tokenizeFormatString(format);
var usedSubstitutionIndexes = {};

for (var i = 0; i < tokens.length; ++i) {
var token = tokens[i];

if (token.type === "string") {
result = append(result, token.value);
continue;
}

if (token.type !== "specifier") {
error("Unknown token type \"" + token.type + "\" found.");
continue;
}

if (token.substitutionIndex >= substitutions.length) {


error("not enough substitution arguments. Had " + substitutions.length + " but needed " + (token.substitutionIndex + 1) + ", so substitution was skipped.");
result = append(result, "%" + (token.precision > -1 ? token.precision : "") + token.specifier);
continue;
}

usedSubstitutionIndexes[token.substitutionIndex] = true;

if (!(token.specifier in formatters)) {

warn("unsupported format character \u201C" + token.specifier + "\u201D. Treating as a string.");
result = append(result, substitutions[token.substitutionIndex]);
continue;
}

result = append(result, formatters[token.specifier](substitutions[token.substitutionIndex], token));
}

var unusedSubstitutions = [];
for (var i = 0; i < substitutions.length; ++i) {
if (i in usedSubstitutionIndexes)
continue;
unusedSubstitutions.push(substitutions[i]);
}

return { formattedResult: result, unusedSubstitutions: unusedSubstitutions };
}

function isEnterKey(event) {

return event.keyCode !== 229 && event.keyIdentifier === "Enter";
}


function highlightSearchResult(element, offset, length)
{
var lineText = element.textContent;
var endOffset = offset + length;
var highlightNode = document.createElement("span");
highlightNode.className = "webkit-search-result";
highlightNode.textContent = lineText.substring(offset, endOffset);

var boundary = element.rangeBoundaryForOffset(offset);
var textNode = boundary.container;
var text = textNode.textContent;

if (boundary.offset + length < text.length) {

textNode.textContent = text.substring(boundary.offset + length);
textNode.parentElement.insertBefore(highlightNode, textNode);
var prefixNode = document.createTextNode(text.substring(0, boundary.offset));
textNode.parentElement.insertBefore(prefixNode, highlightNode);
return highlightNode;
}

var parentElement = textNode.parentElement;
var anchorElement = textNode.nextSibling;

length -= text.length - boundary.offset;
textNode.textContent = text.substring(0, boundary.offset);
textNode = textNode.traverseNextTextNode(element);

while (textNode) {
var text = textNode.textContent;
if (length < text.length) {
textNode.textContent = text.substring(length);
break;
}

length -= text.length;
textNode.textContent = "";
textNode = textNode.traverseNextTextNode(element);
}

parentElement.insertBefore(highlightNode, anchorElement);
return highlightNode;
}

function createSearchRegex(query)
{
var regex = "";
for (var i = 0; i < query.length; ++i) {
var char = query.charAt(i);
if (char === "]")
char = "\\]";
regex += "[" + char + "]";
}
return new RegExp(regex, "i");
}

function offerFileForDownload(contents)
{
var builder = new BlobBuilder();
builder.append(contents);
var blob = builder.getBlob("application/octet-stream");
var url = window.createObjectURL(blob);
window.open(url);
}





function TreeOutline(listNode)
{
this.children = [];
this.selectedTreeElement = null;
this._childrenListNode = listNode;
this._childrenListNode.removeChildren();
this._knownTreeElements = [];
this._treeElementsExpandedState = [];
this.expandTreeElementsWhenArrowing = false;
this.root = true;
this.hasChildren = false;
this.expanded = true;
this.selected = false;
this.treeOutline = this;

this._childrenListNode.tabIndex = 0;
this._childrenListNode.addEventListener("keydown", this._treeKeyDown.bind(this), true);
}

TreeOutline._knownTreeElementNextIdentifier = 1;

TreeOutline._appendChild = function(child)
{
if (!child)
throw("child can't be undefined or null");

var lastChild = this.children[this.children.length - 1];
if (lastChild) {
lastChild.nextSibling = child;
child.previousSibling = lastChild;
} else {
child.previousSibling = null;
child.nextSibling = null;
}

this.children.push(child);
this.hasChildren = true;
child.parent = this;
child.treeOutline = this.treeOutline;
child.treeOutline._rememberTreeElement(child);

var current = child.children[0];
while (current) {
current.treeOutline = this.treeOutline;
current.treeOutline._rememberTreeElement(current);
current = current.traverseNextTreeElement(false, child, true);
}

if (child.hasChildren && child.treeOutline._treeElementsExpandedState[child.identifier] !== undefined)
child.expanded = child.treeOutline._treeElementsExpandedState[child.identifier];

if (!this._childrenListNode) {
this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
this._childrenListNode.parentTreeElement = this;
this._childrenListNode.addStyleClass("children");
if (this.hidden)
this._childrenListNode.addStyleClass("hidden");
}

child._attach();
}

TreeOutline._insertChild = function(child, index)
{
if (!child)
throw("child can't be undefined or null");

var previousChild = (index > 0 ? this.children[index - 1] : null);
if (previousChild) {
previousChild.nextSibling = child;
child.previousSibling = previousChild;
} else {
child.previousSibling = null;
}

var nextChild = this.children[index];
if (nextChild) {
nextChild.previousSibling = child;
child.nextSibling = nextChild;
} else {
child.nextSibling = null;
}

this.children.splice(index, 0, child);
this.hasChildren = true;
child.parent = this;
child.treeOutline = this.treeOutline;
child.treeOutline._rememberTreeElement(child);

var current = child.children[0];
while (current) {
current.treeOutline = this.treeOutline;
current.treeOutline._rememberTreeElement(current);
current = current.traverseNextTreeElement(false, child, true);
}

if (child.hasChildren && child.treeOutline._treeElementsExpandedState[child.identifier] !== undefined)
child.expanded = child.treeOutline._treeElementsExpandedState[child.identifier];

if (!this._childrenListNode) {
this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
this._childrenListNode.parentTreeElement = this;
this._childrenListNode.addStyleClass("children");
if (this.hidden)
this._childrenListNode.addStyleClass("hidden");
}

child._attach();
}

TreeOutline._removeChildAtIndex = function(childIndex)
{
if (childIndex < 0 || childIndex >= this.children.length)
throw("childIndex out of range");

var child = this.children[childIndex];
this.children.splice(childIndex, 1);

var parent = child.parent;
if (child.deselect()) {
if (child.previousSibling)
child.previousSibling.select();
else if (child.nextSibling)
child.nextSibling.select();
else
parent.select();
}

if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
if (child.nextSibling)
child.nextSibling.previousSibling = child.previousSibling;

if (child.treeOutline) {
child.treeOutline._forgetTreeElement(child);
child.treeOutline._forgetChildrenRecursive(child);
}

child._detach();
child.treeOutline = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}

TreeOutline._removeChild = function(child)
{
if (!child)
throw("child can't be undefined or null");

var childIndex = this.children.indexOf(child);
if (childIndex === -1)
throw("child not found in this node's children");

TreeOutline._removeChildAtIndex.call(this, childIndex);
}

TreeOutline._removeChildren = function()
{
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
child.deselect();

if (child.treeOutline) {
child.treeOutline._forgetTreeElement(child);
child.treeOutline._forgetChildrenRecursive(child);
}

child._detach();
child.treeOutline = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}

this.children = [];
}

TreeOutline._removeChildrenRecursive = function()
{
var childrenToRemove = this.children;

var child = this.children[0];
while (child) {
if (child.children.length)
childrenToRemove = childrenToRemove.concat(child.children);
child = child.traverseNextTreeElement(false, this, true);
}

for (var i = 0; i < childrenToRemove.length; ++i) {
var child = childrenToRemove[i];
child.deselect();
if (child.treeOutline)
child.treeOutline._forgetTreeElement(child);
child._detach();
child.children = [];
child.treeOutline = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}

this.children = [];
}

TreeOutline.prototype._rememberTreeElement = function(element)
{
if (!this._knownTreeElements[element.identifier])
this._knownTreeElements[element.identifier] = [];


var elements = this._knownTreeElements[element.identifier];
if (elements.indexOf(element) !== -1)
return;


elements.push(element);
}

TreeOutline.prototype._forgetTreeElement = function(element)
{
if (this._knownTreeElements[element.identifier])
this._knownTreeElements[element.identifier].remove(element, true);
}

TreeOutline.prototype._forgetChildrenRecursive = function(parentElement)
{
var child = parentElement.children[0];
while (child) {
this._forgetTreeElement(child);
child = child.traverseNextTreeElement(false, this, true);
}
}

TreeOutline.prototype.getCachedTreeElement = function(representedObject)
{
if (!representedObject)
return null;

if ("__treeElementIdentifier" in representedObject) {


var elements = this._knownTreeElements[representedObject.__treeElementIdentifier];
if (elements) {
for (var i = 0; i < elements.length; ++i)
if (elements[i].representedObject === representedObject)
return elements[i];
}
}
return null;
}

TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor, getParent)
{
if (!representedObject)
return null;

var cachedElement = this.getCachedTreeElement(representedObject);
if (cachedElement)
return cachedElement;



var item;
var found = false;
for (var i = 0; i < this.children.length; ++i) {
item = this.children[i];
if (item.representedObject === representedObject || isAncestor(item.representedObject, representedObject)) {
found = true;
break;
}
}

if (!found)
return null;



var ancestors = [];
var currentObject = representedObject;
while (currentObject) {
ancestors.unshift(currentObject);
if (currentObject === item.representedObject)
break;
currentObject = getParent(currentObject);
}


for (var i = 0; i < ancestors.length; ++i) {


if (ancestors[i] === representedObject)
continue;


item = this.findTreeElement(ancestors[i], isAncestor, getParent);
if (item && item.onpopulate)
item.onpopulate(item);
}

return this.getCachedTreeElement(representedObject);
}

TreeOutline.prototype.treeElementFromPoint = function(x, y)
{
var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y);
var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]);
if (listNode)
return listNode.parentTreeElement || listNode.treeElement;
return null;
}

TreeOutline.prototype._treeKeyDown = function(event)
{
if (event.target !== this._childrenListNode)
return;

if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
return;

var handled = false;
var nextSelectedElement;
if (event.keyIdentifier === "Up" && !event.altKey) {
nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);
handled = nextSelectedElement ? true : false;
} else if (event.keyIdentifier === "Down" && !event.altKey) {
nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);
handled = nextSelectedElement ? true : false;
} else if (event.keyIdentifier === "Left") {
if (this.selectedTreeElement.expanded) {
if (event.altKey)
this.selectedTreeElement.collapseRecursively();
else
this.selectedTreeElement.collapse();
handled = true;
} else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
handled = true;
if (this.selectedTreeElement.parent.selectable) {
nextSelectedElement = this.selectedTreeElement.parent;
handled = nextSelectedElement ? true : false;
} else if (this.selectedTreeElement.parent)
this.selectedTreeElement.parent.collapse();
}
} else if (event.keyIdentifier === "Right") {
if (!this.selectedTreeElement.revealed()) {
this.selectedTreeElement.reveal();
handled = true;
} else if (this.selectedTreeElement.hasChildren) {
handled = true;
if (this.selectedTreeElement.expanded) {
nextSelectedElement = this.selectedTreeElement.children[0];
handled = nextSelectedElement ? true : false;
} else {
if (event.altKey)
this.selectedTreeElement.expandRecursively();
else
this.selectedTreeElement.expand();
}
}
} else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Backspace.code || event.keyCode === WebInspector.KeyboardShortcut.Keys.Delete.code) {
if (this.selectedTreeElement.ondelete)
handled = this.selectedTreeElement.ondelete();
} else if (isEnterKey(event)) {
if (this.selectedTreeElement.onenter)
handled = this.selectedTreeElement.onenter();
}

if (nextSelectedElement) {
nextSelectedElement.reveal();
nextSelectedElement.select(false, true);
}

if (handled) {
event.preventDefault();
event.stopPropagation();
}
}

TreeOutline.prototype.expand = function()
{

}

TreeOutline.prototype.collapse = function()
{

}

TreeOutline.prototype.revealed = function()
{
return true;
}

TreeOutline.prototype.reveal = function()
{

}

TreeOutline.prototype.select = function()
{

}

TreeOutline.prototype.appendChild = TreeOutline._appendChild;
TreeOutline.prototype.insertChild = TreeOutline._insertChild;
TreeOutline.prototype.removeChild = TreeOutline._removeChild;
TreeOutline.prototype.removeChildAtIndex = TreeOutline._removeChildAtIndex;
TreeOutline.prototype.removeChildren = TreeOutline._removeChildren;
TreeOutline.prototype.removeChildrenRecursive = TreeOutline._removeChildrenRecursive;

function TreeElement(title, representedObject, hasChildren)
{
this._title = title;
this.representedObject = (representedObject || {});

if (this.representedObject.__treeElementIdentifier)
this.identifier = this.representedObject.__treeElementIdentifier;
else {
this.identifier = TreeOutline._knownTreeElementNextIdentifier++;
this.representedObject.__treeElementIdentifier = this.identifier;
}

this._hidden = false;
this.expanded = false;
this.selected = false;
this.hasChildren = hasChildren;
this.children = [];
this.treeOutline = null;
this.parent = null;
this.previousSibling = null;
this.nextSibling = null;
this._listItemNode = null;
}

TreeElement.prototype = {
selectable: true,
arrowToggleWidth: 10,

get listItemElement() {
return this._listItemNode;
},

get childrenListElement() {
return this._childrenListNode;
},

get title() {
return this._title;
},

set title(x) {
this._title = x;
this._setListItemNodeContent();
},

get titleHTML() {
return this._titleHTML;
},

set titleHTML(x) {
this._titleHTML = x;
this._setListItemNodeContent();
},

get tooltip() {
return this._tooltip;
},

set tooltip(x) {
this._tooltip = x;
if (this._listItemNode)
this._listItemNode.title = x ? x : "";
},

get hasChildren() {
return this._hasChildren;
},

set hasChildren(x) {
if (this._hasChildren === x)
return;

this._hasChildren = x;

if (!this._listItemNode)
return;

if (x)
this._listItemNode.addStyleClass("parent");
else {
this._listItemNode.removeStyleClass("parent");
this.collapse();
}
},

get hidden() {
return this._hidden;
},

set hidden(x) {
if (this._hidden === x)
return;

this._hidden = x;

if (x) {
if (this._listItemNode)
this._listItemNode.addStyleClass("hidden");
if (this._childrenListNode)
this._childrenListNode.addStyleClass("hidden");
} else {
if (this._listItemNode)
this._listItemNode.removeStyleClass("hidden");
if (this._childrenListNode)
this._childrenListNode.removeStyleClass("hidden");
}
},

get shouldRefreshChildren() {
return this._shouldRefreshChildren;
},

set shouldRefreshChildren(x) {
this._shouldRefreshChildren = x;
if (x && this.expanded)
this.expand();
},

_setListItemNodeContent: function()
{
if (!this._listItemNode)
return;

if (!this._titleHTML && !this._title)
this._listItemNode.removeChildren();
else if (typeof this._titleHTML === "string")
this._listItemNode.innerHTML = this._titleHTML;
else if (typeof this._title === "string")
this._listItemNode.textContent = this._title;
else {
this._listItemNode.removeChildren();
if (this._title.parentNode)
this._title.parentNode.removeChild(this._title);
this._listItemNode.appendChild(this._title);
}
}
}

TreeElement.prototype.appendChild = TreeOutline._appendChild;
TreeElement.prototype.insertChild = TreeOutline._insertChild;
TreeElement.prototype.removeChild = TreeOutline._removeChild;
TreeElement.prototype.removeChildAtIndex = TreeOutline._removeChildAtIndex;
TreeElement.prototype.removeChildren = TreeOutline._removeChildren;
TreeElement.prototype.removeChildrenRecursive = TreeOutline._removeChildrenRecursive;

TreeElement.prototype._attach = function()
{
if (!this._listItemNode || this.parent._shouldRefreshChildren) {
if (this._listItemNode && this._listItemNode.parentNode)
this._listItemNode.parentNode.removeChild(this._listItemNode);

this._listItemNode = this.treeOutline._childrenListNode.ownerDocument.createElement("li");
this._listItemNode.treeElement = this;
this._setListItemNodeContent();
this._listItemNode.title = this._tooltip ? this._tooltip : "";

if (this.hidden)
this._listItemNode.addStyleClass("hidden");
if (this.hasChildren)
this._listItemNode.addStyleClass("parent");
if (this.expanded)
this._listItemNode.addStyleClass("expanded");
if (this.selected)
this._listItemNode.addStyleClass("selected");

this._listItemNode.addEventListener("mousedown", TreeElement.treeElementMouseDown, false);
this._listItemNode.addEventListener("click", TreeElement.treeElementToggled, false);
this._listItemNode.addEventListener("dblclick", TreeElement.treeElementDoubleClicked, false);

if (this.onattach)
this.onattach(this);
}

var nextSibling = null;
if (this.nextSibling && this.nextSibling._listItemNode && this.nextSibling._listItemNode.parentNode === this.parent._childrenListNode)
nextSibling = this.nextSibling._listItemNode;
this.parent._childrenListNode.insertBefore(this._listItemNode, nextSibling);
if (this._childrenListNode)
this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
if (this.selected)
this.select();
if (this.expanded)
this.expand();
}

TreeElement.prototype._detach = function()
{
if (this._listItemNode && this._listItemNode.parentNode)
this._listItemNode.parentNode.removeChild(this._listItemNode);
if (this._childrenListNode && this._childrenListNode.parentNode)
this._childrenListNode.parentNode.removeChild(this._childrenListNode);
}

TreeElement.treeElementMouseDown = function(event)
{
var element = event.currentTarget;
if (!element || !element.treeElement || !element.treeElement.selectable)
return;

if (element.treeElement.isEventWithinDisclosureTriangle(event))
return;

element.treeElement.selectOnMouseDown(event);
}

TreeElement.treeElementToggled = function(event)
{
var element = event.currentTarget;
if (!element || !element.treeElement)
return;

if (!element.treeElement.isEventWithinDisclosureTriangle(event))
return;

if (element.treeElement.expanded) {
if (event.altKey)
element.treeElement.collapseRecursively();
else
element.treeElement.collapse();
} else {
if (event.altKey)
element.treeElement.expandRecursively();
else
element.treeElement.expand();
}
event.stopPropagation();
}

TreeElement.treeElementDoubleClicked = function(event)
{
var element = event.currentTarget;
if (!element || !element.treeElement)
return;

if (element.treeElement.ondblclick)
element.treeElement.ondblclick.call(element.treeElement, event);
else if (element.treeElement.hasChildren && !element.treeElement.expanded)
element.treeElement.expand();
}

TreeElement.prototype.collapse = function()
{
if (this._listItemNode)
this._listItemNode.removeStyleClass("expanded");
if (this._childrenListNode)
this._childrenListNode.removeStyleClass("expanded");

this.expanded = false;
if (this.treeOutline)
this.treeOutline._treeElementsExpandedState[this.identifier] = true;

if (this.oncollapse)
this.oncollapse(this);
}

TreeElement.prototype.collapseRecursively = function()
{
var item = this;
while (item) {
if (item.expanded)
item.collapse();
item = item.traverseNextTreeElement(false, this, true);
}
}

TreeElement.prototype.expand = function()
{
if (!this.hasChildren || (this.expanded && !this._shouldRefreshChildren && this._childrenListNode))
return;

if (this.treeOutline && (!this._childrenListNode || this._shouldRefreshChildren)) {
if (this._childrenListNode && this._childrenListNode.parentNode)
this._childrenListNode.parentNode.removeChild(this._childrenListNode);

this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
this._childrenListNode.parentTreeElement = this;
this._childrenListNode.addStyleClass("children");

if (this.hidden)
this._childrenListNode.addStyleClass("hidden");

if (this.onpopulate)
this.onpopulate(this);

for (var i = 0; i < this.children.length; ++i)
this.children[i]._attach();

delete this._shouldRefreshChildren;
}

if (this._listItemNode) {
this._listItemNode.addStyleClass("expanded");
if (this._childrenListNode && this._childrenListNode.parentNode != this._listItemNode.parentNode)
this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
}

if (this._childrenListNode)
this._childrenListNode.addStyleClass("expanded");

this.expanded = true;
if (this.treeOutline)
this.treeOutline._treeElementsExpandedState[this.identifier] = true;

if (this.onexpand)
this.onexpand(this);
}

TreeElement.prototype.expandRecursively = function(maxDepth)
{
var item = this;
var info = {};
var depth = 0;




if (typeof maxDepth === "undefined" || typeof maxDepth === "null")
maxDepth = 3;

while (item) {
if (depth < maxDepth)
item.expand();
item = item.traverseNextTreeElement(false, this, (depth >= maxDepth), info);
depth += info.depthChange;
}
}

TreeElement.prototype.hasAncestor = function(ancestor) {
if (!ancestor)
return false;

var currentNode = this.parent;
while (currentNode) {
if (ancestor === currentNode)
return true;
currentNode = currentNode.parent;
}

return false;
}

TreeElement.prototype.reveal = function()
{
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded)
currentAncestor.expand();
currentAncestor = currentAncestor.parent;
}

if (this.onreveal)
this.onreveal(this);
}

TreeElement.prototype.revealed = function()
{
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded)
return false;
currentAncestor = currentAncestor.parent;
}

return true;
}

TreeElement.prototype.selectOnMouseDown = function(event)
{
this.select(false, true);
}

TreeElement.prototype.select = function(supressOnSelect, selectedByUser)
{
if (!this.treeOutline || !this.selectable || this.selected)
return;

if (this.treeOutline.selectedTreeElement)
this.treeOutline.selectedTreeElement.deselect();

this.selected = true;
this.treeOutline._childrenListNode.focus();
this.treeOutline.selectedTreeElement = this;
if (this._listItemNode)
this._listItemNode.addStyleClass("selected");

if (this.onselect && !supressOnSelect)
this.onselect(this, selectedByUser);
}

TreeElement.prototype.deselect = function(supressOnDeselect)
{
if (!this.treeOutline || this.treeOutline.selectedTreeElement !== this || !this.selected)
return false;

this.selected = false;
this.treeOutline.selectedTreeElement = null;
if (this._listItemNode)
this._listItemNode.removeStyleClass("selected");

if (this.ondeselect && !supressOnDeselect)
this.ondeselect(this);
return true;
}

TreeElement.prototype.traverseNextTreeElement = function(skipHidden, stayWithin, dontPopulate, info)
{
if (!dontPopulate && this.hasChildren && this.onpopulate)
this.onpopulate(this);

if (info)
info.depthChange = 0;

var element = skipHidden ? (this.revealed() ? this.children[0] : null) : this.children[0];
if (element && (!skipHidden || (skipHidden && this.expanded))) {
if (info)
info.depthChange = 1;
return element;
}

if (this === stayWithin)
return null;

element = skipHidden ? (this.revealed() ? this.nextSibling : null) : this.nextSibling;
if (element)
return element;

element = this;
while (element && !element.root && !(skipHidden ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) && element.parent !== stayWithin) {
if (info)
info.depthChange -= 1;
element = element.parent;
}

if (!element)
return null;

return (skipHidden ? (element.revealed() ? element.nextSibling : null) : element.nextSibling);
}

TreeElement.prototype.traversePreviousTreeElement = function(skipHidden, dontPopulate)
{
var element = skipHidden ? (this.revealed() ? this.previousSibling : null) : this.previousSibling;
if (!dontPopulate && element && element.hasChildren && element.onpopulate)
element.onpopulate(element);

while (element && (skipHidden ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1])) {
if (!dontPopulate && element.hasChildren && element.onpopulate)
element.onpopulate(element);
element = (skipHidden ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1]);
}

if (element)
return element;

if (!this.parent || this.parent.root)
return null;

return this.parent;
}

TreeElement.prototype.isEventWithinDisclosureTriangle = function(event)
{
var left = this._listItemNode.totalOffsetLeft;
return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
}






;(function preloadImages()
{
(new Image()).src = "Images/clearConsoleButtonGlyph.png";
(new Image()).src = "Images/consoleButtonGlyph.png";
(new Image()).src = "Images/dockButtonGlyph.png";
(new Image()).src = "Images/enableOutlineButtonGlyph.png";
(new Image()).src = "Images/enableSolidButtonGlyph.png";
(new Image()).src = "Images/excludeButtonGlyph.png";
(new Image()).src = "Images/focusButtonGlyph.png";
(new Image()).src = "Images/largerResourcesButtonGlyph.png";
(new Image()).src = "Images/nodeSearchButtonGlyph.png";
(new Image()).src = "Images/pauseOnExceptionButtonGlyph.png";
(new Image()).src = "Images/percentButtonGlyph.png";
(new Image()).src = "Images/recordButtonGlyph.png";
(new Image()).src = "Images/recordToggledButtonGlyph.png";
(new Image()).src = "Images/reloadButtonGlyph.png";
(new Image()).src = "Images/undockButtonGlyph.png";
})();

var WebInspector = {
resources: {},
missingLocalizedStrings: {},
pendingDispatches: 0,

get platform()
{
if (!("_platform" in this))
this._platform = InspectorFrontendHost.platform();

return this._platform;
},

get platformFlavor()
{
if (!("_platformFlavor" in this))
this._platformFlavor = this._detectPlatformFlavor();

return this._platformFlavor;
},

_detectPlatformFlavor: function()
{
const userAgent = navigator.userAgent;

if (this.platform === "windows") {
var match = userAgent.match(/Windows NT (\d+)\.(?:\d+)/);
if (match && match[1] >= 6)
return WebInspector.PlatformFlavor.WindowsVista;
return null;
} else if (this.platform === "mac") {
var match = userAgent.match(/Mac OS X\s*(?:(\d+)_(\d+))?/);
if (!match || match[1] != 10)
return WebInspector.PlatformFlavor.MacSnowLeopard;
switch (Number(match[2])) {
case 4:
return WebInspector.PlatformFlavor.MacTiger;
case 5:
return WebInspector.PlatformFlavor.MacLeopard;
case 6:
default:
return WebInspector.PlatformFlavor.MacSnowLeopard;
}
}

return null;
},

get port()
{
if (!("_port" in this))
this._port = InspectorFrontendHost.port();

return this._port;
},

get previousFocusElement()
{
return this._previousFocusElement;
},

get currentFocusElement()
{
return this._currentFocusElement;
},

set currentFocusElement(x)
{
if (this._currentFocusElement !== x)
this._previousFocusElement = this._currentFocusElement;
this._currentFocusElement = x;

if (this._currentFocusElement) {
this._currentFocusElement.focus();



var selection = window.getSelection();
if (selection.isCollapsed && !this._currentFocusElement.isInsertionCaretInside()) {
var selectionRange = this._currentFocusElement.ownerDocument.createRange();
selectionRange.setStart(this._currentFocusElement, 0);
selectionRange.setEnd(this._currentFocusElement, 0);

selection.removeAllRanges();
selection.addRange(selectionRange);
}
} else if (this._previousFocusElement)
this._previousFocusElement.blur();
},

get currentPanel()
{
return this._currentPanel;
},

set currentPanel(x)
{
if (this._currentPanel === x)
return;

if (this._currentPanel)
this._currentPanel.hide();

this._currentPanel = x;

this.updateSearchLabel();

if (x) {
x.show();

if (this.currentQuery) {
if (x.performSearch) {
function performPanelSearch()
{
this.updateSearchMatchesCount();

x.currentQuery = this.currentQuery;
x.performSearch(this.currentQuery);
}


setTimeout(performPanelSearch.bind(this), 0);
} else {

this.updateSearchMatchesCount();
}
}
}

for (var panelName in WebInspector.panels) {
if (WebInspector.panels[panelName] === x) {
WebInspector.settings.lastActivePanel = panelName;
this._panelHistory.setPanel(panelName);
}
}
},

createJSBreakpointsSidebarPane: function()
{
var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("Breakpoints"));
function breakpointAdded(event)
{
pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data));
}
WebInspector.breakpointManager.addEventListener("breakpoint-added", breakpointAdded);
return pane;
},

createDOMBreakpointsSidebarPane: function()
{
var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints"));
function breakpointAdded(event)
{
pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data));
}
WebInspector.breakpointManager.addEventListener("dom-breakpoint-added", breakpointAdded);
return pane;
},

createXHRBreakpointsSidebarPane: function()
{
var pane = new WebInspector.XHRBreakpointsSidebarPane();
function breakpointAdded(event)
{
pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data));
}
WebInspector.breakpointManager.addEventListener("xhr-breakpoint-added", breakpointAdded);
return pane;
},

_createPanels: function()
{
var hiddenPanels = (InspectorFrontendHost.hiddenPanels() || "").split(',');
if (hiddenPanels.indexOf("elements") === -1)
this.panels.elements = new WebInspector.ElementsPanel();
if (hiddenPanels.indexOf("resources") === -1)
this.panels.resources = new WebInspector.ResourcesPanel();
if (hiddenPanels.indexOf("network") === -1)
this.panels.network = new WebInspector.NetworkPanel();
if (hiddenPanels.indexOf("scripts") === -1)
this.panels.scripts = new WebInspector.ScriptsPanel();
if (hiddenPanels.indexOf("timeline") === -1)
this.panels.timeline = new WebInspector.TimelinePanel();
if (hiddenPanels.indexOf("profiles") === -1) {
this.panels.profiles = new WebInspector.ProfilesPanel();
this.panels.profiles.registerProfileType(new WebInspector.CPUProfileType());
if (Preferences.heapProfilerPresent)
this.panels.profiles.registerProfileType(new WebInspector.HeapSnapshotProfileType());
}
if (hiddenPanels.indexOf("audits") === -1)
this.panels.audits = new WebInspector.AuditsPanel();
if (hiddenPanels.indexOf("console") === -1)
this.panels.console = new WebInspector.ConsolePanel();
},

get attached()
{
return this._attached;
},

set attached(x)
{
if (this._attached === x)
return;

this._attached = x;

this.updateSearchLabel();

var dockToggleButton = document.getElementById("dock-status-bar-item");
var body = document.body;

if (x) {
body.removeStyleClass("detached");
body.addStyleClass("attached");
dockToggleButton.title = WebInspector.UIString("Undock into separate window.");
} else {
body.removeStyleClass("attached");
body.addStyleClass("detached");
dockToggleButton.title = WebInspector.UIString("Dock to main window.");
}
if (this.drawer)
this.drawer.resize();
},

get errors()
{
return this._errors || 0;
},

set errors(x)
{
x = Math.max(x, 0);

if (this._errors === x)
return;
this._errors = x;
this._updateErrorAndWarningCounts();
},

get warnings()
{
return this._warnings || 0;
},

set warnings(x)
{
x = Math.max(x, 0);

if (this._warnings === x)
return;
this._warnings = x;
this._updateErrorAndWarningCounts();
},

_updateErrorAndWarningCounts: function()
{
var errorWarningElement = document.getElementById("error-warning-count");
if (!errorWarningElement)
return;

if (!this.errors && !this.warnings) {
errorWarningElement.addStyleClass("hidden");
return;
}

errorWarningElement.removeStyleClass("hidden");

errorWarningElement.removeChildren();

if (this.errors) {
var errorElement = document.createElement("span");
errorElement.id = "error-count";
errorElement.textContent = this.errors;
errorWarningElement.appendChild(errorElement);
}

if (this.warnings) {
var warningsElement = document.createElement("span");
warningsElement.id = "warning-count";
warningsElement.textContent = this.warnings;
errorWarningElement.appendChild(warningsElement);
}

if (this.errors) {
if (this.warnings) {
if (this.errors == 1) {
if (this.warnings == 1)
errorWarningElement.title = WebInspector.UIString("%d error, %d warning", this.errors, this.warnings);
else
errorWarningElement.title = WebInspector.UIString("%d error, %d warnings", this.errors, this.warnings);
} else if (this.warnings == 1)
errorWarningElement.title = WebInspector.UIString("%d errors, %d warning", this.errors, this.warnings);
else
errorWarningElement.title = WebInspector.UIString("%d errors, %d warnings", this.errors, this.warnings);
} else if (this.errors == 1)
errorWarningElement.title = WebInspector.UIString("%d error", this.errors);
else
errorWarningElement.title = WebInspector.UIString("%d errors", this.errors);
} else if (this.warnings == 1)
errorWarningElement.title = WebInspector.UIString("%d warning", this.warnings);
else if (this.warnings)
errorWarningElement.title = WebInspector.UIString("%d warnings", this.warnings);
else
errorWarningElement.title = null;
},

get styleChanges()
{
return this._styleChanges;
},

set styleChanges(x)
{
x = Math.max(x, 0);

if (this._styleChanges === x)
return;
this._styleChanges = x;
this._updateChangesCount();
},

_updateChangesCount: function()
{

return;

var changesElement = document.getElementById("changes-count");
if (!changesElement)
return;

if (!this.styleChanges) {
changesElement.addStyleClass("hidden");
return;
}

changesElement.removeStyleClass("hidden");
changesElement.removeChildren();

if (this.styleChanges) {
var styleChangesElement = document.createElement("span");
styleChangesElement.id = "style-changes-count";
styleChangesElement.textContent = this.styleChanges;
changesElement.appendChild(styleChangesElement);
}

if (this.styleChanges) {
if (this.styleChanges === 1)
changesElement.title = WebInspector.UIString("%d style change", this.styleChanges);
else
changesElement.title = WebInspector.UIString("%d style changes", this.styleChanges);
}
},

highlightDOMNode: function(nodeId)
{
if ("_hideDOMNodeHighlightTimeout" in this) {
clearTimeout(this._hideDOMNodeHighlightTimeout);
delete this._hideDOMNodeHighlightTimeout;
}

if (this._highlightedDOMNodeId === nodeId)
return;

this._highlightedDOMNodeId = nodeId;
if (nodeId)
InspectorBackend.highlightDOMNode(nodeId);
else
InspectorBackend.hideDOMNodeHighlight();
},

highlightDOMNodeForTwoSeconds: function(nodeId)
{
this.highlightDOMNode(nodeId);
this._hideDOMNodeHighlightTimeout = setTimeout(this.highlightDOMNode.bind(this, 0), 2000);
},

wireElementWithDOMNode: function(element, nodeId)
{
element.addEventListener("click", this._updateFocusedNode.bind(this, nodeId), false);
element.addEventListener("mouseover", this.highlightDOMNode.bind(this, nodeId), false);
element.addEventListener("mouseout", this.highlightDOMNode.bind(this, 0), false);
},

_updateFocusedNode: function(nodeId)
{
this.currentPanel = this.panels.elements;
this.panels.elements.updateFocusedNode(nodeId);
},

get networkResources()
{
return this.panels.network.resources;
},

forAllResources: function(callback)
{
WebInspector.resourceManager.forAllResources(callback);
},

resourceForURL: function(url)
{
return this.resourceManager.resourceForURL(url);
}
}

WebInspector.PlatformFlavor = {
WindowsVista: "windows-vista",
MacTiger: "mac-tiger",
MacLeopard: "mac-leopard",
MacSnowLeopard: "mac-snowleopard"
};

(function parseQueryParameters()
{
WebInspector.queryParamsObject = {};
var queryParams = window.location.search;
if (!queryParams)
return;
var params = queryParams.substring(1).split("&");
for (var i = 0; i < params.length; ++i) {
var pair = params[i].split("=");
WebInspector.queryParamsObject[pair[0]] = pair[1];
}
})();

WebInspector.loaded = function()
{
if ("page" in WebInspector.queryParamsObject) {
WebInspector.socket = new WebSocket("ws://" + window.location.host + "/devtools/page/" + WebInspector.queryParamsObject.page);
WebInspector.socket.onmessage = function(message) { WebInspector_syncDispatch(message.data); }
WebInspector.socket.onerror = function(error) { console.error(error); }
WebInspector.socket.onopen = function() {
InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket);
InspectorFrontendHost.loaded = WebInspector.socket.send.bind(WebInspector.socket, "loaded");
WebInspector.doLoadedDone();
}
return;
}
WebInspector.doLoadedDone();
}

WebInspector.doLoadedDone = function()
{
InspectorBackend.setInjectedScriptSource("(" + injectedScriptConstructor + ");");

var platform = WebInspector.platform;
document.body.addStyleClass("platform-" + platform);
var flavor = WebInspector.platformFlavor;
if (flavor)
document.body.addStyleClass("platform-" + flavor);
var port = WebInspector.port;
document.body.addStyleClass("port-" + port);

InspectorFrontendHost.loaded();
WebInspector.settings = new WebInspector.Settings();

this._registerShortcuts();


WebInspector.shortcutsHelp.section(WebInspector.UIString("Console"));
WebInspector.shortcutsHelp.section(WebInspector.UIString("Elements Panel"));

this.drawer = new WebInspector.Drawer();
this.console = new WebInspector.ConsoleView(this.drawer);



this.drawer.visibleView = this.console;
this.resourceManager = new WebInspector.ResourceManager();
this.domAgent = new WebInspector.DOMAgent();

this.resourceCategories = {
documents: new WebInspector.ResourceCategory("documents", WebInspector.UIString("Documents"), "rgb(47,102,236)"),
stylesheets: new WebInspector.ResourceCategory("stylesheets", WebInspector.UIString("Stylesheets"), "rgb(157,231,119)"),
images: new WebInspector.ResourceCategory("images", WebInspector.UIString("Images"), "rgb(164,60,255)"),
scripts: new WebInspector.ResourceCategory("scripts", WebInspector.UIString("Scripts"), "rgb(255,121,0)"),
xhr: new WebInspector.ResourceCategory("xhr", WebInspector.UIString("XHR"), "rgb(231,231,10)"),
fonts: new WebInspector.ResourceCategory("fonts", WebInspector.UIString("Fonts"), "rgb(255,82,62)"),
websockets: new WebInspector.ResourceCategory("websockets", WebInspector.UIString("WebSocket"), "rgb(186,186,186)"), 
other: new WebInspector.ResourceCategory("other", WebInspector.UIString("Other"), "rgb(186,186,186)")
};

this.breakpointManager = new WebInspector.BreakpointManager();
this.cssModel = new WebInspector.CSSStyleModel();

this.panels = {};
this._createPanels();
this._panelHistory = new WebInspector.PanelHistory();

var toolbarElement = document.getElementById("toolbar");
var previousToolbarItem = toolbarElement.children[0];

this.panelOrder = [];
for (var panelName in this.panels)
previousToolbarItem = WebInspector.addPanelToolbarIcon(toolbarElement, this.panels[panelName], previousToolbarItem);

this.Tips = {
ResourceNotCompressed: {id: 0, message: WebInspector.UIString("You could save bandwidth by having your web server compress this transfer with gzip or zlib.")}
};

this.Warnings = {
IncorrectMIMEType: {id: 0, message: WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s.")}
};

this.addMainEventListeners(document);

window.addEventListener("resize", this.windowResize.bind(this), true);

document.addEventListener("focus", this.focusChanged.bind(this), true);
document.addEventListener("keydown", this.documentKeyDown.bind(this), false);
document.addEventListener("beforecopy", this.documentCanCopy.bind(this), true);
document.addEventListener("copy", this.documentCopy.bind(this), true);
document.addEventListener("contextmenu", this.contextMenuEventFired.bind(this), true);

var dockToggleButton = document.getElementById("dock-status-bar-item");
dockToggleButton.addEventListener("click", this.toggleAttach.bind(this), false);

if (this.attached)
dockToggleButton.title = WebInspector.UIString("Undock into separate window.");
else
dockToggleButton.title = WebInspector.UIString("Dock to main window.");

var errorWarningCount = document.getElementById("error-warning-count");
errorWarningCount.addEventListener("click", this.showConsole.bind(this), false);
this._updateErrorAndWarningCounts();

this.styleChanges = 0;





var searchField = document.getElementById("search");
searchField.addEventListener("search", this.performSearch.bind(this), false); 
searchField.addEventListener("mousedown", this._searchFieldManualFocus.bind(this), false); 
searchField.addEventListener("keydown", this._searchKeyDown.bind(this), true);

toolbarElement.addEventListener("mousedown", this.toolbarDragStart, true);
document.getElementById("close-button-left").addEventListener("click", this.close, true);
document.getElementById("close-button-right").addEventListener("click", this.close, true);

this.extensionServer.initExtensions();

function populateInspectorState(inspectorState)
{
WebInspector.monitoringXHREnabled = inspectorState.monitoringXHREnabled;
if ("pauseOnExceptionsState" in inspectorState)
WebInspector.panels.scripts.updatePauseOnExceptionsState(inspectorState.pauseOnExceptionsState);
}
InspectorBackend.getInspectorState(populateInspectorState);

function onPopulateScriptObjects()
{
if (!WebInspector.currentPanel)
WebInspector.showPanel(WebInspector.settings.lastActivePanel);
}
InspectorBackend.populateScriptObjects(onPopulateScriptObjects);

InspectorBackend.setConsoleMessagesEnabled(true);


InspectorBackend.getSupportedCSSProperties(WebInspector.CSSCompletions._load);
}

WebInspector.addPanelToolbarIcon = function(toolbarElement, panel, previousToolbarItem)
{
var panelToolbarItem = panel.toolbarItem;
this.panelOrder.push(panel);
panelToolbarItem.addEventListener("click", this._toolbarItemClicked.bind(this));
if (previousToolbarItem)
toolbarElement.insertBefore(panelToolbarItem, previousToolbarItem.nextSibling);
else
toolbarElement.insertBefore(panelToolbarItem, toolbarElement.firstChild);
return panelToolbarItem;
}

var windowLoaded = function()
{
var localizedStringsURL = InspectorFrontendHost.localizedStringsURL();
if (localizedStringsURL) {
var localizedStringsScriptElement = document.createElement("script");
localizedStringsScriptElement.addEventListener("load", WebInspector.loaded.bind(WebInspector), false);
localizedStringsScriptElement.type = "text/javascript";
localizedStringsScriptElement.src = localizedStringsURL;
document.head.appendChild(localizedStringsScriptElement);
} else
WebInspector.loaded();

window.removeEventListener("DOMContentLoaded", windowLoaded, false);
delete windowLoaded;
};

window.addEventListener("DOMContentLoaded", windowLoaded, false);

WebInspector.dispatch = function(message) {


function delayDispatch()
{
WebInspector_syncDispatch(message);
WebInspector.pendingDispatches--;
}
WebInspector.pendingDispatches++;
setTimeout(delayDispatch, 0);
}


WebInspector_syncDispatch = function(message)
{
if (window.dumpInspectorProtocolMessages)
console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));

var messageObject = (typeof message === "string") ? JSON.parse(message) : message;

var arguments = [];
if (messageObject.data)
for (var key in messageObject.data)
arguments.push(messageObject.data[key]);

if ("seq" in messageObject) { 
if (messageObject.success)
WebInspector.processResponse(messageObject.seq, arguments);
else {
WebInspector.removeResponseCallbackEntry(messageObject.seq)
WebInspector.reportProtocolError(messageObject);
}
return;
}

if (messageObject.type === "event") {
if (!(messageObject.event in WebInspector)) {
console.error("Protocol Error: Attempted to dispatch an unimplemented WebInspector method '%s'", messageObject.event);
return;
}
WebInspector[messageObject.event].apply(WebInspector, arguments);
}
}

WebInspector.dispatchMessageFromBackend = function(messageObject)
{
WebInspector.dispatch(messageObject);
}

WebInspector.reportProtocolError = function(messageObject)
{
console.error("Protocol Error: InspectorBackend request with seq = %d failed.", messageObject.seq);
for (var i = 0; i < messageObject.errors.length; ++i)
console.error("    " + messageObject.errors[i]);
WebInspector.removeResponseCallbackEntry(messageObject.seq);
}

WebInspector.windowResize = function(event)
{
if (this.currentPanel)
this.currentPanel.resize();
this.drawer.resize();
}

WebInspector.windowFocused = function(event)
{



if (event.target.document.nodeType === Node.DOCUMENT_NODE)
document.body.removeStyleClass("inactive");
}

WebInspector.windowBlurred = function(event)
{



if (event.target.document.nodeType === Node.DOCUMENT_NODE)
document.body.addStyleClass("inactive");
}

WebInspector.focusChanged = function(event)
{
this.currentFocusElement = event.target;
}

WebInspector.setAttachedWindow = function(attached)
{
this.attached = attached;
}

WebInspector.close = function(event)
{
if (this._isClosing)
return;
this._isClosing = true;
InspectorFrontendHost.closeWindow();
}

WebInspector.disconnectFromBackend = function()
{
InspectorFrontendHost.disconnectFromBackend();
}

WebInspector.documentClick = function(event)
{
var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
if (!anchor || anchor.target === "_blank")
return;


event.preventDefault();
event.stopPropagation();

function followLink()
{

if (WebInspector.canShowSourceLine(anchor.href, anchor.getAttribute("line_number"), anchor.getAttribute("preferred_panel"))) {
if (anchor.hasStyleClass("webkit-html-external-link")) {
anchor.removeStyleClass("webkit-html-external-link");
anchor.addStyleClass("webkit-html-resource-link");
}

WebInspector.showSourceLine(anchor.href, anchor.getAttribute("line_number"), anchor.getAttribute("preferred_panel"));
return;
}

const profileMatch = WebInspector.ProfileType.URLRegExp.exec(anchor.href);
if (profileMatch) {
WebInspector.showProfileForURL(anchor.href);
return;
}

var parsedURL = anchor.href.asParsedURL();
if (parsedURL && parsedURL.scheme === "webkit-link-action") {
if (parsedURL.host === "show-panel") {
var panel = parsedURL.path.substring(1);
if (WebInspector.panels[panel])
WebInspector.showPanel(panel);
}
return;
}

WebInspector.showPanel("resources");
}

if (WebInspector.followLinkTimeout)
clearTimeout(WebInspector.followLinkTimeout);

if (anchor.preventFollowOnDoubleClick) {


if (event.detail === 1)
WebInspector.followLinkTimeout = setTimeout(followLink, 333);
return;
}

followLink();
}

WebInspector.openResource = function(resourceURL, inResourcesPanel)
{
var resource = WebInspector.resourceForURL(resourceURL);
if (inResourcesPanel && resource) {
WebInspector.panels.resources.showResource(resource);
WebInspector.showPanel("resources");
} else
InspectorBackend.openInInspectedWindow(resource ? resource.url : resourceURL);
}

WebInspector._registerShortcuts = function()
{
var shortcut = WebInspector.KeyboardShortcut;
var section = WebInspector.shortcutsHelp.section(WebInspector.UIString("All Panels"));
var keys = [
shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta),
shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous panel"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Esc), WebInspector.UIString("Toggle console"));
section.addKey(shortcut.shortcutToString("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
if (WebInspector.isMac()) {
keys = [
shortcut.shortcutToString("g", shortcut.Modifiers.Meta),
shortcut.shortcutToString("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
}
}

WebInspector.documentKeyDown = function(event)
{
var isInputElement = event.target.nodeName === "INPUT";
var isInEditMode = event.target.enclosingNodeOrSelfWithClass("text-prompt") || WebInspector.isEditingAnyField();
const helpKey = WebInspector.isMac() ? "U+003F" : "U+00BF"; 

if (event.keyIdentifier === "F1" ||
(event.keyIdentifier === helpKey && event.shiftKey && (!isInEditMode && !isInputElement || event.metaKey))) {
WebInspector.shortcutsHelp.show();
event.stopPropagation();
event.preventDefault();
return;
}

if (WebInspector.isEditingAnyField())
return;

if (this.currentFocusElement && this.currentFocusElement.handleKeyEvent) {
this.currentFocusElement.handleKeyEvent(event);
if (event.handled) {
event.preventDefault();
return;
}
}

if (this.currentPanel && this.currentPanel.handleShortcut) {
this.currentPanel.handleShortcut(event);
if (event.handled) {
event.preventDefault();
return;
}
}

var isMac = WebInspector.isMac();
switch (event.keyIdentifier) {
case "Left":
var isBackKey = !isInEditMode && (isMac ? event.metaKey : event.ctrlKey);
if (isBackKey && this._panelHistory.canGoBack()) {
this._panelHistory.goBack();
event.preventDefault();
}
break;

case "Right":
var isForwardKey = !isInEditMode && (isMac ? event.metaKey : event.ctrlKey);
if (isForwardKey && this._panelHistory.canGoForward()) {
this._panelHistory.goForward();
event.preventDefault();
}
break;

case "U+001B": 
event.preventDefault();
if (this.drawer.fullPanel)
return;

this.drawer.visible = !this.drawer.visible;
break;

case "U+0046": 
if (isMac)
var isFindKey = event.metaKey && !event.ctrlKey && !event.altKey && !event.shiftKey;
else
var isFindKey = event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey;

if (isFindKey) {
WebInspector.focusSearchField();
event.preventDefault();
}
break;

case "F3":
if (!isMac) {
WebInspector.focusSearchField();
event.preventDefault();
}
break;

case "U+0047": 
if (isMac && event.metaKey && !event.ctrlKey && !event.altKey) {
if (event.shiftKey) {
if (this.currentPanel.jumpToPreviousSearchResult)
this.currentPanel.jumpToPreviousSearchResult();
} else if (this.currentPanel.jumpToNextSearchResult)
this.currentPanel.jumpToNextSearchResult();
event.preventDefault();
}
break;


case "U+005B":
case "U+00DB": 
if (isMac)
var isRotateLeft = event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey;
else
var isRotateLeft = event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;

if (isRotateLeft) {
var index = this.panelOrder.indexOf(this.currentPanel);
index = (index === 0) ? this.panelOrder.length - 1 : index - 1;
this.panelOrder[index].toolbarItem.click();
event.preventDefault();
}

break;


case "U+005D":
case "U+00DD":  
if (isMac)
var isRotateRight = event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey;
else
var isRotateRight = event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;

if (isRotateRight) {
var index = this.panelOrder.indexOf(this.currentPanel);
index = (index + 1) % this.panelOrder.length;
this.panelOrder[index].toolbarItem.click();
event.preventDefault();
}

break;

case "U+0052": 
if ((event.metaKey && isMac) || (event.ctrlKey && !isMac)) {
InspectorBackend.reloadPage();
event.preventDefault();
}
break;
case "F5":
if (!isMac)
InspectorBackend.reloadPage();
break;
}
}

WebInspector.documentCanCopy = function(event)
{
if (this.currentPanel && this.currentPanel.handleCopyEvent)
event.preventDefault();
}

WebInspector.documentCopy = function(event)
{
if (this.currentPanel && this.currentPanel.handleCopyEvent)
this.currentPanel.handleCopyEvent(event);
}

WebInspector.contextMenuEventFired = function(event)
{
if (event.handled || event.target.hasStyleClass("popup-glasspane"))
event.preventDefault();
}

WebInspector.animateStyle = function(animations, duration, callback)
{
var interval;
var complete = 0;

const intervalDuration = (1000 / 30); 
const animationsLength = animations.length;
const propertyUnit = {opacity: ""};
const defaultUnit = "px";

function cubicInOut(t, b, c, d)
{
if ((t/=d/2) < 1) return c/2*t*t*t + b;
return c/2*((t-=2)*t*t + 2) + b;
}


for (var i = 0; i < animationsLength; ++i) {
var animation = animations[i];
var element = null, start = null, end = null, key = null;
for (key in animation) {
if (key === "element")
element = animation[key];
else if (key === "start")
start = animation[key];
else if (key === "end")
end = animation[key];
}

if (!element || !end)
continue;

if (!start) {
var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element);
start = {};
for (key in end)
start[key] = parseInt(computedStyle.getPropertyValue(key));
animation.start = start;
} else
for (key in start)
element.style.setProperty(key, start[key] + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
}

function animateLoop()
{

complete += intervalDuration;
var next = complete + intervalDuration;


for (var i = 0; i < animationsLength; ++i) {
var animation = animations[i];
var element = animation.element;
var start = animation.start;
var end = animation.end;
if (!element || !end)
continue;

var style = element.style;
for (key in end) {
var endValue = end[key];
if (next < duration) {
var startValue = start[key];
var newValue = cubicInOut(complete, startValue, endValue - startValue, duration);
style.setProperty(key, newValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
} else
style.setProperty(key, endValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
}
}


if (complete >= duration) {
clearInterval(interval);
if (callback)
callback();
}
}

interval = setInterval(animateLoop, intervalDuration);
return interval;
}

WebInspector.updateSearchLabel = function()
{
if (!this.currentPanel)
return;

var newLabel = WebInspector.UIString("Search %s", this.currentPanel.toolbarItemLabel);
if (this.attached)
document.getElementById("search").setAttribute("placeholder", newLabel);
else {
document.getElementById("search").removeAttribute("placeholder");
document.getElementById("search-toolbar-label").textContent = newLabel;
}
}

WebInspector.focusSearchField = function()
{
var searchField = document.getElementById("search");
searchField.focus();
searchField.select();
}

WebInspector.toggleAttach = function()
{
if (!this.attached)
InspectorFrontendHost.requestAttachWindow();
else
InspectorFrontendHost.requestDetachWindow();
}

WebInspector.toolbarDragStart = function(event)
{
if ((!WebInspector.attached && WebInspector.platformFlavor !== WebInspector.PlatformFlavor.MacLeopard && WebInspector.platformFlavor !== WebInspector.PlatformFlavor.MacSnowLeopard) || WebInspector.port == "qt")
return;

var target = event.target;
if (target.hasStyleClass("toolbar-item") && target.hasStyleClass("toggleable"))
return;

var toolbar = document.getElementById("toolbar");
if (target !== toolbar && !target.hasStyleClass("toolbar-item"))
return;

toolbar.lastScreenX = event.screenX;
toolbar.lastScreenY = event.screenY;

WebInspector.elementDragStart(toolbar, WebInspector.toolbarDrag, WebInspector.toolbarDragEnd, event, (WebInspector.attached ? "row-resize" : "default"));
}

WebInspector.toolbarDragEnd = function(event)
{
var toolbar = document.getElementById("toolbar");

WebInspector.elementDragEnd(event);

delete toolbar.lastScreenX;
delete toolbar.lastScreenY;
}

WebInspector.toolbarDrag = function(event)
{
var toolbar = document.getElementById("toolbar");

if (WebInspector.attached) {
var height = window.innerHeight - (event.screenY - toolbar.lastScreenY);

InspectorFrontendHost.setAttachedWindowHeight(height);
} else {
var x = event.screenX - toolbar.lastScreenX;
var y = event.screenY - toolbar.lastScreenY;



InspectorFrontendHost.moveWindowBy(x, y);
}

toolbar.lastScreenX = event.screenX;
toolbar.lastScreenY = event.screenY;

event.preventDefault();
}

WebInspector.elementDragStart = function(element, dividerDrag, elementDragEnd, event, cursor)
{
if (this._elementDraggingEventListener || this._elementEndDraggingEventListener)
this.elementDragEnd(event);

this._elementDraggingEventListener = dividerDrag;
this._elementEndDraggingEventListener = elementDragEnd;

document.addEventListener("mousemove", dividerDrag, true);
document.addEventListener("mouseup", elementDragEnd, true);

document.body.style.cursor = cursor;

event.preventDefault();
}

WebInspector.elementDragEnd = function(event)
{
document.removeEventListener("mousemove", this._elementDraggingEventListener, true);
document.removeEventListener("mouseup", this._elementEndDraggingEventListener, true);

document.body.style.removeProperty("cursor");

delete this._elementDraggingEventListener;
delete this._elementEndDraggingEventListener;

event.preventDefault();
}

WebInspector.toggleSearchingForNode = function()
{
if (this.panels.elements) {
this.showPanel("elements");
this.panels.elements.toggleSearchingForNode();
}
}

WebInspector.showConsole = function()
{
this.drawer.showView(this.console);
}

WebInspector.showChanges = function()
{
this.drawer.showView(this.changes);
}

WebInspector.showPanel = function(panel)
{
if (!(panel in this.panels))
panel = "elements";
this.currentPanel = this.panels[panel];
}

WebInspector.selectDatabase = function(o)
{
WebInspector.showPanel("resources");
WebInspector.panels.resources.selectDatabase(o);
}

WebInspector.consoleMessagesCleared = function()
{
WebInspector.console.clearMessages();
}

WebInspector.selectDOMStorage = function(o)
{
WebInspector.showPanel("resources");
WebInspector.panels.resources.selectDOMStorage(o);
}

WebInspector.domContentEventFired = function(time)
{
this.panels.audits.mainResourceDOMContentTime = time;
if (this.panels.network)
this.panels.network.mainResourceDOMContentTime = time;
this.extensionServer.notifyPageDOMContentLoaded((time - WebInspector.mainResource.startTime) * 1000);
this.mainResourceDOMContentTime = time;
}

WebInspector.loadEventFired = function(time)
{
this.panels.audits.mainResourceLoadTime = time;
if (this.panels.network)
this.panels.network.mainResourceLoadTime = time;
this.extensionServer.notifyPageLoaded((time - WebInspector.mainResource.startTime) * 1000);
this.mainResourceLoadTime = time;
}

WebInspector.addDatabase = function(payload)
{
if (!this.panels.resources)
return;
var database = new WebInspector.Database(
payload.id,
payload.domain,
payload.name,
payload.version);
this.panels.resources.addDatabase(database);
}

WebInspector.addDOMStorage = function(payload)
{
if (!this.panels.resources)
return;
var domStorage = new WebInspector.DOMStorage(
payload.id,
payload.host,
payload.isLocalStorage);
this.panels.resources.addDOMStorage(domStorage);
}

WebInspector.updateDOMStorage = function(storageId)
{
this.panels.resources.updateDOMStorage(storageId);
}

WebInspector.updateApplicationCacheStatus = function(status)
{
this.panels.resources.updateApplicationCacheStatus(status);
}

WebInspector.didGetFileSystemPath = function(root, type, origin)
{
this.panels.resources.updateFileSystemPath(root, type, origin);
}

WebInspector.didGetFileSystemError = function(type, origin)
{
this.panels.resources.updateFileSystemError(type, origin);
}

WebInspector.didGetFileSystemDisabled = function()
{
this.panels.resources.setFileSystemDisabled();
}

WebInspector.updateNetworkState = function(isNowOnline)
{
this.panels.resources.updateNetworkState(isNowOnline);
}

WebInspector.searchingForNodeWasEnabled = function()
{
this.panels.elements.searchingForNodeWasEnabled();
}

WebInspector.searchingForNodeWasDisabled = function()
{
this.panels.elements.searchingForNodeWasDisabled();
}

WebInspector.attachDebuggerWhenShown = function()
{
this.panels.scripts.attachDebuggerWhenShown();
}

WebInspector.debuggerWasEnabled = function()
{
this.panels.scripts.debuggerWasEnabled();
}

WebInspector.debuggerWasDisabled = function()
{
this.panels.scripts.debuggerWasDisabled();
}

WebInspector.profilerWasEnabled = function()
{
this.panels.profiles.profilerWasEnabled();
}

WebInspector.profilerWasDisabled = function()
{
this.panels.profiles.profilerWasDisabled();
}

WebInspector.parsedScriptSource = function(sourceID, sourceURL, source, startingLine, scriptWorldType)
{
this.panels.scripts.addScript(sourceID, sourceURL, source, startingLine, undefined, undefined, scriptWorldType);
}

WebInspector.restoredBreakpoint = function(sourceID, sourceURL, line, enabled, condition)
{
this.breakpointManager.restoredBreakpoint(sourceID, sourceURL, line, enabled, condition);
}

WebInspector.failedToParseScriptSource = function(sourceURL, source, startingLine, errorLine, errorMessage)
{
this.panels.scripts.addScript(null, sourceURL, source, startingLine, errorLine, errorMessage);
}

WebInspector.pausedScript = function(details)
{
this.panels.scripts.debuggerPaused(details.callFrames);
this.breakpointManager.debuggerPaused(details);
InspectorFrontendHost.bringToFront();
}

WebInspector.resumedScript = function()
{
this.breakpointManager.debuggerResumed();
this.panels.scripts.debuggerResumed();
}

WebInspector.reset = function()
{
this.breakpointManager.reset();

for (var panelName in this.panels) {
var panel = this.panels[panelName];
if ("reset" in panel)
panel.reset();
}

this.resources = {};
this.highlightDOMNode(0);

this.console.clearMessages();
this.extensionServer.notifyInspectorReset();

this.breakpointManager.restoreBreakpoints();
}

WebInspector.resetProfilesPanel = function()
{
if (WebInspector.panels.profiles)
WebInspector.panels.profiles.resetProfiles();
}

WebInspector.bringToFront = function()
{
InspectorFrontendHost.bringToFront();
}

WebInspector.inspectedURLChanged = function(url)
{
InspectorFrontendHost.inspectedURLChanged(url);
this.settings.inspectedURLChanged(url);
this.extensionServer.notifyInspectedURLChanged();
if (!this._breakpointsRestored) {
this.breakpointManager.restoreBreakpoints();
this._breakpointsRestored = true;
}
}

WebInspector.didCommitLoad = function()
{

WebInspector.setDocument(null);
}

WebInspector.updateConsoleMessageExpiredCount = function(count)
{
var message = String.sprintf(WebInspector.UIString("%d console messages are not shown."), count);
WebInspector.console.addMessage(WebInspector.ConsoleMessage.createTextMessage(message, WebInspector.ConsoleMessage.MessageLevel.Warning));
}

WebInspector.addConsoleMessage = function(payload)
{
var consoleMessage = new WebInspector.ConsoleMessage(
payload.source,
payload.type,
payload.level,
payload.line,
payload.url,
payload.groupLevel,
payload.repeatCount,
payload.message,
payload.parameters,
payload.stackTrace);
this.console.addMessage(consoleMessage);
}

WebInspector.updateConsoleMessageRepeatCount = function(count)
{
this.console.updateMessageRepeatCount(count);
}

WebInspector.log = function(message, messageLevel)
{

var self = this;


function isLogAvailable()
{
return WebInspector.ConsoleMessage && WebInspector.RemoteObject && self.console;
}


function flushQueue()
{
var queued = WebInspector.log.queued;
if (!queued)
return;

for (var i = 0; i < queued.length; ++i)
logMessage(queued[i]);

delete WebInspector.log.queued;
}



function flushQueueIfAvailable()
{
if (!isLogAvailable())
return;

clearInterval(WebInspector.log.interval);
delete WebInspector.log.interval;

flushQueue();
}


function logMessage(message)
{
var repeatCount = 1;
if (message == WebInspector.log.lastMessage)
repeatCount = WebInspector.log.repeatCount + 1;

WebInspector.log.lastMessage = message;
WebInspector.log.repeatCount = repeatCount;


message = new WebInspector.RemoteObject.fromPrimitiveValue(message);


var msg = new WebInspector.ConsoleMessage(
WebInspector.ConsoleMessage.MessageSource.Other,
WebInspector.ConsoleMessage.MessageType.Log,
messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug,
-1,
null,
null,
repeatCount,
null,
[message],
null);

self.console.addMessage(msg);
}


if (!isLogAvailable()) {
if (!WebInspector.log.queued)
WebInspector.log.queued = [];

WebInspector.log.queued.push(message);

if (!WebInspector.log.interval)
WebInspector.log.interval = setInterval(flushQueueIfAvailable, 1000);

return;
}


flushQueue();


logMessage(message);
}

WebInspector.addProfileHeader = function(profile)
{
this.panels.profiles.addProfileHeader(profile);
}

WebInspector.setRecordingProfile = function(isProfiling)
{
this.panels.profiles.getProfileType(WebInspector.CPUProfileType.TypeId).setRecordingProfile(isProfiling);
if (this.panels.profiles.hasTemporaryProfile(WebInspector.CPUProfileType.TypeId) !== isProfiling) {
if (!this._temporaryRecordingProfile) {
this._temporaryRecordingProfile = {
typeId: WebInspector.CPUProfileType.TypeId,
title: WebInspector.UIString("Recording…"),
uid: -1,
isTemporary: true
};
}
if (isProfiling)
this.panels.profiles.addProfileHeader(this._temporaryRecordingProfile);
else
this.panels.profiles.removeProfileHeader(this._temporaryRecordingProfile);
}
this.panels.profiles.updateProfileTypeButtons();
}

WebInspector.drawLoadingPieChart = function(canvas, percent) {
var g = canvas.getContext("2d");
var darkColor = "rgb(122, 168, 218)";
var lightColor = "rgb(228, 241, 251)";
var cx = 8;
var cy = 8;
var r = 7;

g.beginPath();
g.arc(cx, cy, r, 0, Math.PI * 2, false);
g.closePath();

g.lineWidth = 1;
g.strokeStyle = darkColor;
g.fillStyle = lightColor;
g.fill();
g.stroke();

var startangle = -Math.PI / 2;
var endangle = startangle + (percent * Math.PI * 2);

g.beginPath();
g.moveTo(cx, cy);
g.arc(cx, cy, r, startangle, endangle, false);
g.closePath();

g.fillStyle = darkColor;
g.fill();
}

WebInspector.updateFocusedNode = function(nodeId)
{
this._updateFocusedNode(nodeId);
this.highlightDOMNodeForTwoSeconds(nodeId);
}

WebInspector.displayNameForURL = function(url)
{
if (!url)
return "";

var resource = this.resourceForURL(url);
if (resource)
return resource.displayName;

if (!WebInspector.mainResource)
return url.trimURL("");

var lastPathComponent = WebInspector.mainResource.lastPathComponent;
var index = WebInspector.mainResource.url.indexOf(lastPathComponent);
if (index !== -1 && index + lastPathComponent.length === WebInspector.mainResource.url.length) {
var baseURL = WebInspector.mainResource.url.substring(0, index);
if (url.indexOf(baseURL) === 0)
return url.substring(index);
}

return url.trimURL(WebInspector.mainResource.domain);
}

WebInspector._choosePanelToShowSourceLine = function(url, line, preferredPanel)
{
preferredPanel = preferredPanel || "resources";

var panel = this.panels[preferredPanel];
if (panel && panel.canShowSourceLine(url, line))
return panel;
panel = this.panels.resources;
return panel.canShowSourceLine(url, line) ? panel : null;
}

WebInspector.canShowSourceLine = function(url, line, preferredPanel)
{
return !!this._choosePanelToShowSourceLine(url, line, preferredPanel);
}

WebInspector.showSourceLine = function(url, line, preferredPanel)
{
this.currentPanel = this._choosePanelToShowSourceLine(url, line, preferredPanel);
if (!this.currentPanel)
return false;
this.currentPanel.showSourceLine(url, line);
return true;
}

WebInspector.linkifyStringAsFragment = function(string)
{
var container = document.createDocumentFragment();
var linkStringRegEx = /(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\/\/|www\.)[\w$\-_+*'=\|\/\\(){}[\]%@&#~,:;.!?]{2,}[\w$\-_+*=\|\/\\({%@&#~]/;
    var lineColumnRegEx = /:(\d+)(:(\d+))?$/;

    while (string) {
        var linkString = linkStringRegEx.exec(string);
        if (!linkString)
            break;

        linkString = linkString[0];
        var title = linkString;
        var linkIndex = string.indexOf(linkString);
        var nonLink = string.substring(0, linkIndex);
        container.appendChild(document.createTextNode(nonLink));

        var profileStringMatches = WebInspector.ProfileType.URLRegExp.exec(title);
        if (profileStringMatches)
            title = WebInspector.panels.profiles.displayTitleForProfileLink(profileStringMatches[2], profileStringMatches[1]);

        var realURL = (linkString.indexOf("www.") === 0 ? "http://" + linkString : linkString);
        var lineColumnMatch = lineColumnRegEx.exec(realURL);
        if (lineColumnMatch)
            realURL = realURL.substring(0, realURL.length - lineColumnMatch[0].length);

        var hasResourceWithURL = !!WebInspector.resourceForURL(realURL);
        var urlNode = WebInspector.linkifyURLAsNode(realURL, title, null, hasResourceWithURL);
        container.appendChild(urlNode);
        if (lineColumnMatch) {
            urlNode.setAttribute("line_number", lineColumnMatch[1]);
            urlNode.setAttribute("preferred_panel", "scripts");
        }
        string = string.substring(linkIndex + linkString.length, string.length);
    }

    if (string)
        container.appendChild(document.createTextNode(string));

    return container;
}

WebInspector.showProfileForURL = function(url)
{
    WebInspector.showPanel("profiles");
    WebInspector.panels.profiles.showProfileForURL(url);
}

WebInspector.linkifyURLAsNode = function(url, linkText, classes, isExternal, tooltipText)
{
    if (!linkText)
        linkText = url;
    classes = (classes ? classes + " " : "");
    classes += isExternal ? "webkit-html-external-link" : "webkit-html-resource-link";

    var a = document.createElement("a");
    a.href = url;
    a.className = classes;
    if (typeof tooltipText === "undefined")
        a.title = url;
    else if (typeof tooltipText !== "string" || tooltipText.length)
        a.title = tooltipText;
    a.textContent = linkText;

    return a;
}

WebInspector.linkifyURL = function(url, linkText, classes, isExternal, tooltipText)
{
    // Use the DOM version of this function so as to avoid needing to escape attributes.
    // FIXME:  Get rid of linkifyURL entirely.
    return WebInspector.linkifyURLAsNode(url, linkText, classes, isExternal, tooltipText).outerHTML;
}

WebInspector.linkifyResourceAsNode = function(url, preferredPanel, lineNumber, classes, tooltipText)
{
    var linkText = WebInspector.displayNameForURL(url);
    if (lineNumber)
        linkText += ":" + lineNumber;
    var node = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText);
    node.setAttribute("line_number", lineNumber);
    node.setAttribute("preferred_panel", preferredPanel);
    return node;
}

WebInspector.resourceURLForRelatedNode = function(node, url)
{
    if (!url || url.indexOf("://") > 0)
        return url;

    for (var frameOwnerCandidate = node; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
        if (frameOwnerCandidate.documentURL) {
            var result = WebInspector.completeURL(frameOwnerCandidate.documentURL, url);
            if (result)
                return result;
            break;
        }
    }

    // documentURL not found or has bad value
    var resourceURL = url;
    function callback(resource)
    {
        if (resource.path === url) {
            resourceURL = resource.url;
            return true;
        }
    }
    WebInspector.forAllResources(callback);
    return resourceURL;
}

WebInspector.completeURL = function(baseURL, href)
{
    var parsedURL = baseURL.asParsedURL();
    if (parsedURL) {
        var path = href;
        if (path.charAt(0) !== "/") {
            var basePath = parsedURL.path;
            path = basePath.substring(0, basePath.lastIndexOf("/")) + "/" + path;
        } else if (path.length > 1 && path.charAt(1) === "/") {
            // href starts with "//" which is a full URL with the protocol dropped (use the baseURL protocol).
            return parsedURL.scheme + ":" + path;
        }
        return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + path;
    }
    return null;
}

WebInspector.addMainEventListeners = function(doc)
{
    doc.defaultView.addEventListener("focus", this.windowFocused.bind(this), false);
    doc.defaultView.addEventListener("blur", this.windowBlurred.bind(this), false);
    doc.addEventListener("click", this.documentClick.bind(this), true);
}

WebInspector._searchFieldManualFocus = function(event)
{
    this.currentFocusElement = event.target;
    this._previousFocusElement = event.target;
}

WebInspector._searchKeyDown = function(event)
{
    // Escape Key will clear the field and clear the search results
    if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
        // If focus belongs here and text is empty - nothing to do, return unhandled.
        if (event.target.value === "" && this.currentFocusElement === this.previousFocusElement)
            return;
        event.preventDefault();
        event.stopPropagation();
        // When search was selected manually and is currently blank, we'd like Esc stay unhandled

event.target.value = "";

this.performSearch(event);
this.currentFocusElement = this.previousFocusElement;
if (this.currentFocusElement === event.target)
this.currentFocusElement.select();
return false;
}

if (!isEnterKey(event))
return false;


event.target.select();




this.performSearch(event);



event.preventDefault();
}

WebInspector.performSearch = function(event)
{
var forceSearch = event.keyIdentifier === "Enter";
this.doPerformSearch(event.target.value, forceSearch, event.shiftKey, false);
}

WebInspector.doPerformSearch = function(query, forceSearch, isBackwardSearch, repeatSearch)
{
var isShortSearch = (query.length < 3);


if (isShortSearch && this.shortSearchWasForcedByKeyEvent && this.currentQuery !== query)
delete this.shortSearchWasForcedByKeyEvent;


if (isShortSearch && forceSearch)
this.shortSearchWasForcedByKeyEvent = true;

if (!query || !query.length || (!forceSearch && isShortSearch)) {

if (this.shortSearchWasForcedByKeyEvent) {
delete this.shortSearchWasForcedByKeyEvent;
return;
}

delete this.currentQuery;

for (var panelName in this.panels) {
var panel = this.panels[panelName];
var hadCurrentQuery = !!panel.currentQuery;
delete panel.currentQuery;
if (hadCurrentQuery && panel.searchCanceled)
panel.searchCanceled();
}

this.updateSearchMatchesCount();

return;
}

if (!repeatSearch && query === this.currentPanel.currentQuery && this.currentPanel.currentQuery === this.currentQuery) {


if (forceSearch) {
if (!isBackwardSearch && this.currentPanel.jumpToNextSearchResult)
this.currentPanel.jumpToNextSearchResult();
else if (isBackwardSearch && this.currentPanel.jumpToPreviousSearchResult)
this.currentPanel.jumpToPreviousSearchResult();
}
return;
}

this.currentQuery = query;

this.updateSearchMatchesCount();

if (!this.currentPanel.performSearch)
return;

this.currentPanel.currentQuery = query;
this.currentPanel.performSearch(query);
}

WebInspector.addNodesToSearchResult = function(nodeIds)
{
WebInspector.panels.elements.addNodesToSearchResult(nodeIds);
}

WebInspector.updateSearchMatchesCount = function(matches, panel)
{
if (!panel)
panel = this.currentPanel;

panel.currentSearchMatches = matches;

if (panel !== this.currentPanel)
return;

if (!this.currentPanel.currentQuery) {
document.getElementById("search-results-matches").addStyleClass("hidden");
return;
}

if (matches) {
if (matches === 1)
var matchesString = WebInspector.UIString("1 match");
else
var matchesString = WebInspector.UIString("%d matches", matches);
} else
var matchesString = WebInspector.UIString("Not Found");

var matchesToolbarElement = document.getElementById("search-results-matches");
matchesToolbarElement.removeStyleClass("hidden");
matchesToolbarElement.textContent = matchesString;
}

WebInspector.UIString = function(string)
{
if (window.localizedStrings && string in window.localizedStrings)
string = window.localizedStrings[string];
else {
if (!(string in WebInspector.missingLocalizedStrings)) {
if (!WebInspector.InspectorBackendStub)
console.error("Localized string \"" + string + "\" not found.");
WebInspector.missingLocalizedStrings[string] = true;
}

if (Preferences.showMissingLocalizedStrings)
string += " (not localized)";
}

return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
}

WebInspector.formatLocalized = function(format, substitutions, formatters, initialValue, append)
{
return String.format(WebInspector.UIString(format), substitutions, formatters, initialValue, append);
}

WebInspector.isMac = function()
{
if (!("_isMac" in this))
this._isMac = WebInspector.platform === "mac";

return this._isMac;
}

WebInspector.isBeingEdited = function(element)
{
return element.__editing;
}

WebInspector.isEditingAnyField = function()
{
return this.__editing;
}

WebInspector.startEditing = function(element, committedCallback, cancelledCallback, context, multiline)
{
if (element.__editing)
return;
element.__editing = true;
WebInspector.__editing = true;

var oldText = getContent(element);
var moveDirection = "";

element.addStyleClass("editing");

var oldTabIndex = element.tabIndex;
if (element.tabIndex < 0)
element.tabIndex = 0;

function blurEventListener() {
editingCommitted.call(element);
}

function getContent(element) {
if (element.tagName === "INPUT" && element.type === "text")
return element.value;
else
return element.textContent;
}

function cleanUpAfterEditing() {
delete this.__editing;
delete WebInspector.__editing;

this.removeStyleClass("editing");
this.tabIndex = oldTabIndex;
this.scrollTop = 0;
this.scrollLeft = 0;

element.removeEventListener("blur", blurEventListener, false);
element.removeEventListener("keydown", keyDownEventListener, true);

if (element === WebInspector.currentFocusElement || element.isAncestor(WebInspector.currentFocusElement))
WebInspector.currentFocusElement = WebInspector.previousFocusElement;
}

function editingCancelled() {
if (this.tagName === "INPUT" && this.type === "text")
this.value = oldText;
else
this.textContent = oldText;

cleanUpAfterEditing.call(this);

if (cancelledCallback)
cancelledCallback(this, context);
}

function editingCommitted() {
cleanUpAfterEditing.call(this);

if (committedCallback)
committedCallback(this, getContent(this), oldText, context, moveDirection);
}

function keyDownEventListener(event) {
var isMetaOrCtrl = WebInspector.isMac() ?
event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
if (isEnterKey(event) && (!multiline || isMetaOrCtrl)) {
editingCommitted.call(element);
event.preventDefault();
event.stopPropagation();
} else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
editingCancelled.call(element);
event.preventDefault();
event.stopPropagation();
} else if (event.keyIdentifier === "U+0009") 
moveDirection = (event.shiftKey ? "backward" : "forward");
}

element.addEventListener("blur", blurEventListener, false);
element.addEventListener("keydown", keyDownEventListener, true);

WebInspector.currentFocusElement = element;
return {
cancel: editingCancelled.bind(element),
commit: editingCommitted.bind(element)
};
}

WebInspector._toolbarItemClicked = function(event)
{
var toolbarItem = event.currentTarget;
this.currentPanel = toolbarItem.panel;
}






WebInspector.MIMETypes = {
"text/html":                   {0: true},
"text/xml":                    {0: true},
"text/plain":                  {0: true},
"application/xhtml+xml":       {0: true},
"text/css":                    {1: true},
"text/xsl":                    {1: true},
"image/jpeg":                  {2: true},
"image/png":                   {2: true},
"image/gif":                   {2: true},
"image/bmp":                   {2: true},
"image/vnd.microsoft.icon":    {2: true},
"image/x-icon":                {2: true},
"image/x-xbitmap":             {2: true},
"font/ttf":                    {3: true},
"font/opentype":               {3: true},
"application/x-font-type1":    {3: true},
"application/x-font-ttf":      {3: true},
"application/x-truetype-font": {3: true},
"text/javascript":             {4: true},
"text/ecmascript":             {4: true},
"application/javascript":      {4: true},
"application/ecmascript":      {4: true},
"application/x-javascript":    {4: true},
"text/javascript1.1":          {4: true},
"text/javascript1.2":          {4: true},
"text/javascript1.3":          {4: true},
"text/jscript":                {4: true},
"text/livescript":             {4: true},
}

WebInspector.PanelHistory = function()
{
this._history = [];
this._historyIterator = -1;
}

WebInspector.PanelHistory.prototype = {
canGoBack: function()
{
return this._historyIterator > 0;
},

goBack: function()
{
this._inHistory = true;
WebInspector.currentPanel = WebInspector.panels[this._history[--this._historyIterator]];
delete this._inHistory;
},

canGoForward: function()
{
return this._historyIterator < this._history.length - 1;
},

goForward: function()
{
this._inHistory = true;
WebInspector.currentPanel = WebInspector.panels[this._history[++this._historyIterator]];
delete this._inHistory;
},

setPanel: function(panelName)
{
if (this._inHistory)
return;

this._history.splice(this._historyIterator + 1, this._history.length - this._historyIterator - 1);
if (!this._history.length || this._history[this._history.length - 1] !== panelName)
this._history.push(panelName);
this._historyIterator = this._history.length - 1;
}
}








WebInspector.InspectorBackendStub = function()
{
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "populateScriptObjects", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "getInspectorState", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "setSearchingForNode", "arguments": {"enabled": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "setMonitoringXHREnabled", "arguments": {"enable": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "reloadPage", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "startTimelineProfiler", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "stopTimelineProfiler", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Resource", "command": "cachedResources", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Resource", "command": "resourceContent", "arguments": {"frameId": "number","url": "string","base64Encode": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "Backend", "command": "enableDebugger", "arguments": {"always": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "disableDebugger", "arguments": {"always": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "setBreakpoint", "arguments": {"sourceID": "string","lineNumber": "number","enabled": "boolean","condition": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "removeBreakpoint", "arguments": {"sourceID": "string","lineNumber": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "activateBreakpoints", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "deactivateBreakpoints", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "pause", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "resume", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "stepOverStatement", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "stepIntoStatement", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "stepOutOfFunction", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "setPauseOnExceptionsState", "arguments": {"pauseOnExceptionsState": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "editScriptSource", "arguments": {"sourceID": "string","newContent": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Debug", "command": "getScriptSource", "arguments": {"sourceID": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "setNativeBreakpoint", "arguments": {"breakpoint": "object"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "removeNativeBreakpoint", "arguments": {"breakpointId": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "enableProfiler", "arguments": {"always": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "disableProfiler", "arguments": {"always": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "startProfiling", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "stopProfiling", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Profiler", "command": "getProfileHeaders", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Profiler", "command": "getProfile", "arguments": {"type": "string","uid": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "Profiler", "command": "removeProfile", "arguments": {"type": "string","uid": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "Profiler", "command": "clearProfiles", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Profiler", "command": "takeHeapSnapshot", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Backend", "command": "setInjectedScriptSource", "arguments": {"scriptSource": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Backend", "command": "dispatchOnInjectedScript", "arguments": {"injectedScriptId": "number","methodName": "string","arguments": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "addScriptToEvaluateOnLoad", "arguments": {"scriptSource": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "removeAllScriptsToEvaluateOnLoad", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "getChildNodes", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "setAttribute", "arguments": {"elementId": "number","name": "string","value": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "removeAttribute", "arguments": {"elementId": "number","name": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "setTextNodeValue", "arguments": {"nodeId": "number","value": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "getEventListenersForNode", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "copyNode", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "removeNode", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "changeTagName", "arguments": {"nodeId": "number","newTagName": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "getOuterHTML", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "setOuterHTML", "arguments": {"nodeId": "number","outerHTML": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "addInspectedNode", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "performSearch", "arguments": {"query": "string","runSynchronously": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "searchCanceled", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "pushNodeByPathToFrontend", "arguments": {"path": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "setConsoleMessagesEnabled", "arguments": {"enabled": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "clearConsoleMessages", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "highlightDOMNode", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "hideDOMNodeHighlight", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "openInInspectedWindow", "arguments": {"url": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "highlightFrame", "arguments": {"frameId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "hideFrameHighlight", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "getStyles", "arguments": {"nodeId": "number","authOnly": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "getAllStyles", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "getInlineStyle", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "getComputedStyle", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "getStyleSheet", "arguments": {"styleSheetId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "getStyleSourceData", "arguments": {"styleSheetId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "applyStyleText", "arguments": {"styleId": "number","styleText": "string","propertyName": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "setStyleText", "arguments": {"styleId": "number","styleText": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "setStyleProperty", "arguments": {"styleId": "number","name": "string","value": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "toggleStyleEnabled", "arguments": {"styleId": "number","propertyName": "string","disabled": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "setRuleSelector", "arguments": {"ruleId": "number","selector": "string","selectedNodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "DOM", "command": "addRule", "arguments": {"selector": "string","selectedNodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "getStylesForNode2", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "getComputedStyleForNode2", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "getInlineStyleForNode2", "arguments": {"nodeId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "getAllStyles2", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "getStyleSheet2", "arguments": {"styleSheetId": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "getStyleSheetText2", "arguments": {"styleSheetId": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "setStyleSheetText2", "arguments": {"styleSheetId": "string","text": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "setPropertyText2", "arguments": {"styleId": "object","propertyIndex": "number","text": "string","overwrite": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "toggleProperty2", "arguments": {"styleId": "object","propertyIndex": "number","disable": "boolean"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "setRuleSelector2", "arguments": {"ruleId": "object","selector": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "addRule2", "arguments": {"contextNodeId": "number","selector": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "getSupportedCSSProperties", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "CSS", "command": "querySelectorAll", "arguments": {"documentId": "number","selector": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "getCookies", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "deleteCookie", "arguments": {"cookieName": "string","domain": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "ApplicationCache", "command": "getApplicationCaches", "arguments": {}}');
this._registerDelegate('{"seq": 0, "domain": "FileSystem", "command": "getFileSystemPathAsync", "arguments": {"type": "number","origin": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "FileSystem", "command": "revealFolderInOS", "arguments": {"path": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Backend", "command": "releaseWrapperObjectGroup", "arguments": {"injectedScriptId": "number","objectGroup": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "didEvaluateForTestInFrontend", "arguments": {"testCallId": "number","jsonResult": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Backend", "command": "getDatabaseTableNames", "arguments": {"databaseId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "Backend", "command": "executeSQL", "arguments": {"databaseId": "number","query": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "getDOMStorageEntries", "arguments": {"storageId": "number"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "setDOMStorageItem", "arguments": {"storageId": "number","key": "string","value": "string"}}');
this._registerDelegate('{"seq": 0, "domain": "Controller", "command": "removeDOMStorageItem", "arguments": {"storageId": "number","key": "string"}}');
}

WebInspector.InspectorBackendStub.prototype = {
_registerDelegate: function(commandInfo)
{
var commandObject = JSON.parse(commandInfo);
this[commandObject.command] = this.sendMessageToBackend.bind(this, commandInfo);
},

sendMessageToBackend: function()
{
var args = Array.prototype.slice.call(arguments);
var request = JSON.parse(args.shift());

for (var key in request.arguments) {
if (args.length === 0) {
console.error("Protocol Error: Invalid number of arguments for 'InspectorBackend.%s' call. It should have the next arguments '%s'.", request.command, JSON.stringify(request.arguments));
return;
}
var value = args.shift();
if (typeof value !== request.arguments[key]) {
console.error("Protocol Error: Invalid type of argument '%s' for 'InspectorBackend.%s' call. It should be '%s' but it is '%s'.", key, request.command, request.arguments[key], typeof value);
return;
}
request.arguments[key] = value;
}

if (args.length === 1) {
if (typeof args[0] !== "function" && typeof args[0] !== "undefined") {
console.error("Protocol Error: Optional callback argument for 'InspectorBackend.%s' call should be a function but its type is '%s'.", request.command, typeof args[0]);
return;
}
request.seq = WebInspector.Callback.wrap(args[0]);
}

if (window.dumpInspectorProtocolMessages)
console.log("frontend: " + JSON.stringify(request));

var message = JSON.stringify(request);
InspectorFrontendHost.sendMessageToBackend(message);
}
}

InspectorBackend = new WebInspector.InspectorBackendStub();




if (!window.InspectorFrontendHost) {

WebInspector.InspectorFrontendHostStub = function()
{
this._attachedWindowHeight = 0;
}

WebInspector._platformFlavor = WebInspector.PlatformFlavor.MacLeopard;

WebInspector.InspectorFrontendHostStub.prototype = {
platform: function()
{
var match = navigator.userAgent.match(/Windows NT/);
if (match)
return "windows";
match = navigator.userAgent.match(/Mac OS X/);
if (match)
return "mac";
return "linux";
},

port: function()
{
return "unknown";
},

bringToFront: function()
{
this._windowVisible = true;
},

closeWindow: function()
{
this._windowVisible = false;
},

disconnectFromBackend: function()
{
this._windowVisible = false;
},

attach: function()
{
},

detach: function()
{
},

search: function(sourceRow, query)
{
},

setAttachedWindowHeight: function(height)
{
},

moveWindowBy: function(x, y)
{
},

setExtensionAPI: function(script)
{
},

loaded: function()
{
},

localizedStringsURL: function()
{
return undefined;
},

hiddenPanels: function()
{
return "";
},

inspectedURLChanged: function(url)
{
},

copyText: function()
{
},

canAttachWindow: function()
{
return false;
},

sendMessageToBackend: function(message)
{
}
}

InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub();

}





if (!window.InspectorExtensionRegistry) {

WebInspector.InspectorExtensionRegistryStub = function()
{
}

WebInspector.InspectorExtensionRegistryStub.prototype = {
getExtensionsAsync: function()
{
}
};

InspectorExtensionRegistry = new WebInspector.InspectorExtensionRegistryStub();

}





WebInspector.Object = function() {
}

WebInspector.Object.prototype = {
addEventListener: function(eventType, listener, thisObject)
{
if (!("_listeners" in this))
this._listeners = {};
if (!(eventType in this._listeners))
this._listeners[eventType] = [];
this._listeners[eventType].push({ thisObject: thisObject, listener: listener });
},

removeEventListener: function(eventType, listener, thisObject)
{
if (!("_listeners" in this) || !(eventType in this._listeners))
return;
var listeners = this._listeners[eventType];
for (var i = 0; i < listeners.length; ++i) {
if (listener && listeners[i].listener === listener && listeners[i].thisObject === thisObject)
listeners.splice(i, 1);
else if (!listener && thisObject && listeners[i].thisObject === thisObject)
listeners.splice(i, 1);
}

if (!listeners.length)
delete this._listeners[eventType];
},

removeAllListeners: function()
{
delete this._listeners;
},

dispatchEventToListeners: function(eventType, eventData)
{
if (!("_listeners" in this) || !(eventType in this._listeners))
return;

var stoppedPropagation = false;

function stopPropagation()
{
stoppedPropagation = true;
}

function preventDefault()
{
this.defaultPrevented = true;
}

var event = {target: this, type: eventType, data: eventData, defaultPrevented: false};
event.stopPropagation = stopPropagation;
event.preventDefault = preventDefault;

var listeners = this._listeners[eventType].slice(0);
for (var i = 0; i < listeners.length; ++i) {
listeners[i].listener.call(listeners[i].thisObject, event);
if (stoppedPropagation)
break;
}

return event.defaultPrevented;
}
}






var Preferences = {
canEditScriptSource: false,
maxInlineTextChildLength: 80,
minConsoleHeight: 75,
minSidebarWidth: 100,
minElementsSidebarWidth: 200,
minScriptsSidebarWidth: 200,
styleRulesExpandedState: {},
showMissingLocalizedStrings: false,
samplingCPUProfiler: false,
showColorNicknames: true,
debuggerAlwaysEnabled: false,
profilerAlwaysEnabled: false,
onlineDetectionEnabled: true,
nativeInstrumentationEnabled: false,
resourceExportEnabled: false,
fileSystemEnabled: false,
useDataURLForResourceImageIcons: true,
showTimingTab: false,
debugMode: false
}

WebInspector.Settings = function()
{
this.installApplicationSetting("colorFormat", "hex");
this.installApplicationSetting("consoleHistory", []);
this.installApplicationSetting("eventListenersFilter", "all");
this.installApplicationSetting("lastViewedScriptFile", "application");
this.installApplicationSetting("resourcesLargeRows", true);
this.installApplicationSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"});
this.installApplicationSetting("resourceViewTab", "content");
this.installApplicationSetting("showInheritedComputedStyleProperties", false);
this.installApplicationSetting("showUserAgentStyles", true);
this.installApplicationSetting("watchExpressions", []);
this.installApplicationSetting("lastActivePanel", "elements");

this.installProjectSetting("breakpoints", {});
this.installProjectSetting("nativeBreakpoints", []);
}

WebInspector.Settings.prototype = {
installApplicationSetting: function(key, defaultValue)
{
if (key in this)
return;

this.__defineGetter__(key, this._get.bind(this, key, defaultValue));
this.__defineSetter__(key, this._set.bind(this, key));
},

installProjectSetting: function(key, defaultValue)
{
this.__defineGetter__(key, this._getProjectSetting.bind(this, key, defaultValue));
this.__defineSetter__(key, this._setProjectSetting.bind(this, key));
},

inspectedURLChanged: function(url)
{
var fragmentIndex = url.indexOf("#");
if (fragmentIndex !== -1)
url = url.substring(0, fragmentIndex);
this._inspectedURL = url;
},

_get: function(key, defaultValue)
{
if (key in window.localStorage) {
try {
return JSON.parse(window.localStorage[key]);
} catch(e) {
window.localStorage.removeItem(key);
}
}
return defaultValue;
},

_set: function(key, value)
{
window.localStorage[key] = JSON.stringify(value);
},

_getProjectSetting: function(key, defaultValue)
{
return this._get(this._formatProjectKey(key), defaultValue);
},

_setProjectSetting: function(key, value)
{
return this._set(this._formatProjectKey(key), value);
},

_formatProjectKey: function(key)
{
return key + ":" + this._inspectedURL;
}
}

WebInspector.Settings.prototype.__proto__ = WebInspector.Object.prototype;





WebInspector.CSSStyleModel = function()
{
}

WebInspector.CSSStyleModel.parseRuleArrayPayload = function(ruleArray)
{
var result = [];
for (var i = 0; i < ruleArray.length; ++i)
result.push(WebInspector.CSSRule.parsePayload(ruleArray[i]));
return result;
}

WebInspector.CSSStyleModel.prototype = {
getStylesAsync: function(nodeId, userCallback)
{
function callback(userCallback, payload)
{
if (!payload) {
if (userCallback)
userCallback(null);
return;
}

var result = {};
if ("inlineStyle" in payload)
result.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(payload.inlineStyle);

result.computedStyle = WebInspector.CSSStyleDeclaration.parsePayload(payload.computedStyle);
result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleArrayPayload(payload.matchedCSSRules);

result.styleAttributes = {};
for (var name in payload.styleAttributes)
result.styleAttributes[name] = WebInspector.CSSStyleDeclaration.parsePayload(payload.styleAttributes[name]);

result.pseudoElements = [];
for (var i = 0; i < payload.pseudoElements.length; ++i) {
var entryPayload = payload.pseudoElements[i];
result.pseudoElements.push({ pseudoId: entryPayload.pseudoId, rules: WebInspector.CSSStyleModel.parseRuleArrayPayload(entryPayload.rules) });
}

result.inherited = [];
for (var i = 0; i < payload.inherited.length; ++i) {
var entryPayload = payload.inherited[i];
var entry = {};
if ("inlineStyle" in entryPayload)
entry.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(entryPayload.inlineStyle);
if ("matchedCSSRules" in entryPayload)
entry.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleArrayPayload(entryPayload.matchedCSSRules);
result.inherited.push(entry);
}

if (userCallback)
userCallback(result);
}

InspectorBackend.getStylesForNode2(nodeId, callback.bind(null, userCallback));
},

getComputedStyleAsync: function(nodeId, userCallback)
{
function callback(userCallback, stylePayload)
{
if (!stylePayload)
userCallback(null);
else
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(stylePayload));
}

InspectorBackend.getComputedStyleForNode2(nodeId, callback.bind(null, userCallback));
},

getInlineStyleAsync: function(nodeId, userCallback)
{
function callback(userCallback, stylePayload)
{
if (!stylePayload)
userCallback(null);
else
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(stylePayload));
}

InspectorBackend.getInlineStyleForNode2(nodeId, callback.bind(null, userCallback));
},

setRuleSelector: function(ruleId, nodeId, newSelector, successCallback, failureCallback)
{
function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
{
var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
var rule = WebInspector.CSSRule.parsePayload(rulePayload);
successCallback(rule, doesAffectSelectedNode);
this._styleSheetChanged(rule.id.styleSheetId, true);
}

function callback(nodeId, successCallback, failureCallback, newSelector, rulePayload)
{
if (!rulePayload)
failureCallback();
else
InspectorBackend.querySelectorAll(nodeId, newSelector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
}

InspectorBackend.setRuleSelector2(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback));
},

addRule: function(nodeId, selector, successCallback, failureCallback)
{
function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
{
var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
var rule = WebInspector.CSSRule.parsePayload(rulePayload);
successCallback(rule, doesAffectSelectedNode);
this._styleSheetChanged(rule.id.styleSheetId, true);
}

function callback(successCallback, failureCallback, selector, rulePayload)
{
if (!rulePayload) {

failureCallback();
} else
InspectorBackend.querySelectorAll(nodeId, selector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
}

InspectorBackend.addRule2(nodeId, selector, callback.bind(this, successCallback, failureCallback, selector));
},

_styleSheetChanged: function(styleSheetId, majorChange)
{
if (!majorChange || !styleSheetId)
return;

function callback(href, content)
{
var resource = WebInspector.resourceManager.resourceForURL(href);
if (resource && resource.type === WebInspector.Resource.Type.Stylesheet)
resource.setContent(content, this._onRevert.bind(this, styleSheetId));
}
InspectorBackend.getStyleSheetText2(styleSheetId, callback.bind(this));
},

_onRevert: function(styleSheetId, contentToRevertTo)
{
function callback(success)
{
this._styleSheetChanged(styleSheetId, true);
}
InspectorBackend.setStyleSheetText2(styleSheetId, contentToRevertTo, callback.bind(this));
}
}

WebInspector.CSSStyleDeclaration = function(payload)
{
this.id = payload.styleId;
this.properties = payload.properties;
this._shorthandValues = payload.shorthandValues;
this._livePropertyMap = {}; 
this._allProperties = []; 
this._longhandProperties = {}; 
this.__disabledProperties = {}; 
var payloadPropertyCount = payload.cssProperties.length;

var propertyIndex = 0;
for (var i = 0; i < payloadPropertyCount; ++i) {
var property = new WebInspector.CSSProperty.parsePayload(this, i, payload.cssProperties[i]);
this._allProperties.push(property);
if (property.disabled)
this.__disabledProperties[i] = property;
if (!property.active && !property.styleBased)
continue;
var name = property.name;
this[propertyIndex] = name;
this._livePropertyMap[name] = property;


if (property.shorthand) { 
var longhands = this._longhandProperties[property.shorthand];
if (!longhands) {
longhands = [];
this._longhandProperties[property.shorthand] = longhands;
}
longhands.push(property);
}
++propertyIndex;
}
this.length = propertyIndex;
if ("cssText" in payload)
this.cssText = payload.cssText;
}

WebInspector.CSSStyleDeclaration.parsePayload = function(payload)
{
return new WebInspector.CSSStyleDeclaration(payload);
}

WebInspector.CSSStyleDeclaration.prototype = {
get allProperties()
{
return this._allProperties;
},

getLiveProperty: function(name)
{
return this._livePropertyMap[name];
},

getPropertyValue: function(name)
{
var property = this._livePropertyMap[name];
return property ? property.value : "";
},

getPropertyPriority: function(name)
{
var property = this._livePropertyMap[name];
return property ? property.priority : "";
},

getPropertyShorthand: function(name)
{
var property = this._livePropertyMap[name];
return property ? property.shorthand : "";
},

isPropertyImplicit: function(name)
{
var property = this._livePropertyMap[name];
return property ? property.implicit : "";
},

styleTextWithShorthands: function()
{
var cssText = "";
var foundProperties = {};
for (var i = 0; i < this.length; ++i) {
var individualProperty = this[i];
var shorthandProperty = this.getPropertyShorthand(individualProperty);
var propertyName = (shorthandProperty || individualProperty);

if (propertyName in foundProperties)
continue;

if (shorthandProperty) {
var value = this.getShorthandValue(shorthandProperty);
var priority = this.getShorthandPriority(shorthandProperty);
} else {
var value = this.getPropertyValue(individualProperty);
var priority = this.getPropertyPriority(individualProperty);
}

foundProperties[propertyName] = true;

cssText += propertyName + ": " + value;
if (priority)
cssText += " !" + priority;
cssText += "; ";
}

return cssText;
},

getLonghandProperties: function(name)
{
return this._longhandProperties[name] || [];
},

getShorthandValue: function(shorthandProperty)
{
var property = this.getLiveProperty(shorthandProperty);
return property ? property.value : this._shorthandValues[shorthandProperty];
},

getShorthandPriority: function(shorthandProperty)
{
var priority = this.getPropertyPriority(shorthandProperty);
if (priority)
return priority;

var longhands = this._longhandProperties[shorthandProperty];
return longhands ? this.getPropertyPriority(longhands[0]) : null;
},

propertyAt: function(index)
{
return (index < this.allProperties.length) ? this.allProperties[index] : null;
},

pastLastSourcePropertyIndex: function()
{
for (var i = this.allProperties.length - 1; i >= 0; --i) {
var property = this.allProperties[i];
if (property.active || property.disabled)
return i + 1;
}
return 0;
},

newBlankProperty: function()
{
return new WebInspector.CSSProperty(this, this.pastLastSourcePropertyIndex(), "", "", "", "active", true, false, false, "");
},

insertPropertyAt: function(index, name, value, userCallback)
{
function callback(userCallback, payload)
{
if (!userCallback)
return;

if (!payload)
userCallback(null);
else {
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload));
WebInspector.cssModel._styleSheetChanged(this.id.styleSheetId, true);
}
}

InspectorBackend.setPropertyText2(this.id, index, name + ": " + value + ";", false, callback.bind(null, userCallback));
},

appendProperty: function(name, value, userCallback)
{
this.insertPropertyAt(this.allProperties.length, name, value, userCallback);
}
}

WebInspector.CSSRule = function(payload)
{
this.id = payload.ruleId;
this.selectorText = payload.selectorText;
this.sourceLine = payload.sourceLine;
this.sourceURL = payload.sourceURL;
this.origin = payload.origin;
this.style = WebInspector.CSSStyleDeclaration.parsePayload(payload.style);
this.style.parentRule = this;
this.selectorRange = payload.selectorRange;
}

WebInspector.CSSRule.parsePayload = function(payload)
{
return new WebInspector.CSSRule(payload);
}

WebInspector.CSSRule.prototype = {
get isUserAgent()
{
return this.origin === "user-agent";
},

get isUser()
{
return this.origin === "user";
},

get isViaInspector()
{
return this.origin === "inspector";
},

get isRegular()
{
return this.origin === "";
}
}

WebInspector.CSSProperty = function(ownerStyle, index, name, value, priority, status, parsedOk, implicit, shorthand, text)
{
this.ownerStyle = ownerStyle;
this.index = index;
this.name = name;
this.value = value;
this.priority = priority;
this.status = status;
this.parsedOk = parsedOk;
this.implicit = implicit;
this.shorthand = shorthand;
this.text = text;
}

WebInspector.CSSProperty.parsePayload = function(ownerStyle, index, payload)
{
var result = new WebInspector.CSSProperty(
ownerStyle, index, payload.name, payload.value, payload.priority, payload.status, payload.parsedOk, payload.implicit, payload.shorthandName, payload.text);
return result;
}

WebInspector.CSSProperty.prototype = {
get propertyText()
{
if (this.text !== undefined)
return this.text;

if (this.name === "")
return "";
return this.name + ": " + this.value + (this.priority ? " !" + this.priority : "") + ";";
},

get isLive()
{
return this.active || this.styleBased;
},

get active()
{
return this.status === "active";
},

get styleBased()
{
return this.status === "style";
},

get inactive()
{
return this.status === "inactive";
},

get disabled()
{
return this.status === "disabled";
},


setText: function(propertyText, majorChange, userCallback)
{
function callback(stylePayload)
{
if (stylePayload)
this.text = propertyText;

if (!userCallback)
return;
if (!stylePayload)
userCallback(null);
else {
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
userCallback(style);
WebInspector.cssModel._styleSheetChanged(style.id.styleSheetId, majorChange);
}
}

if (!this.ownerStyle)
throw "No ownerStyle for property";


InspectorBackend.setPropertyText2(this.ownerStyle.id, this.index, propertyText, this.index < this.ownerStyle.pastLastSourcePropertyIndex(), callback.bind(this));
},

setValue: function(newValue, userCallback)
{
var text = this.name + ": " + newValue + (this.priority ? " !" + this.priority : "") + ";"
this.setText(text, userCallback);
},

setDisabled: function(disabled, userCallback)
{
if (!this.ownerStyle && userCallback)
userCallback(null);
if (disabled === this.disabled && userCallback)
userCallback(this.ownerStyle);

function callback(stylePayload)
{
if (!userCallback)
return;
if (!stylePayload)
userCallback(null);
else {
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
userCallback(style);
WebInspector.cssModel._styleSheetChanged(this.ownerStyle.id.styleSheetId, false);
}
}

InspectorBackend.toggleProperty2(this.ownerStyle.id, this.index, disabled, callback.bind(this));
}
}

WebInspector.CSSStyleSheet = function(payload)
{
this.id = payload.styleSheetId;
this.sourceURL = payload.sourceURL;
this.title = payload.title;
this.disabled = payload.disabled;
this.rules = [];
this.styles = {};
for (var i = 0; i < payload.rules.length; ++i) {
var rule = WebInspector.CSSRule.parsePayload(payload.rules[i]);
this.rules.push(rule);
if (rule.style)
this.styles[rule.style.id] = rule.style;
}
if ("text" in payload)
this._text = payload.text;
}

WebInspector.CSSStyleSheet.createForId = function(styleSheetId, userCallback)
{
function callback(styleSheetPayload)
{
if (!styleSheetPayload)
userCallback(null);
else
userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload));
}
InspectorBackend.getStyleSheet2(styleSheetId, callback.bind(this));
}

WebInspector.CSSStyleSheet.prototype = {
getText: function()
{
return this._text;
},

setText: function(newText, userCallback)
{
function callback(styleSheetPayload)
{
if (!styleSheetPayload)
userCallback(null);
else {
userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload));
WebInspector.cssModel._styleSheetChanged(this.id, true);
}
}

InspectorBackend.setStyleSheetText2(this.id, newText, callback.bind(this));
}
}





WebInspector.Checkbox = function(label, className, tooltip)
{
this.element = document.createElement('label');
this._inputElement = document.createElement('input');
this._inputElement.type = "checkbox";

this.element.className = className;
this.element.appendChild(this._inputElement);
this.element.appendChild(document.createTextNode(label));
if (tooltip)
this.element.title = tooltip;
}

WebInspector.Checkbox.prototype = {
set checked(checked)
{
this._inputElement.checked = checked;
},

get checked()
{
return this._inputElement.checked;
},

addEventListener: function(listener)
{
function listenerWrapper(event)
{
if (listener)
listener(event);
event.stopPropagation();
return true;
}

this._inputElement.addEventListener("click", listenerWrapper, false);
this.element.addEventListener("click", listenerWrapper, false);
}
}





WebInspector.ContextMenu = function() {
this._items = [];
this._handlers = {};
}

WebInspector.ContextMenu.prototype = {
show: function(event)
{

while (this._items.length > 0 && !("id" in this._items[this._items.length - 1]))
this._items.splice(this._items.length - 1, 1);

if (this._items.length) {
WebInspector._contextMenu = this;
InspectorFrontendHost.showContextMenu(event, this._items);
}
},

appendItem: function(label, handler, disabled)
{
var id = this._items.length;
this._items.push({type: "item", id: id, label: label, enabled: !disabled});
this._handlers[id] = handler;
},

appendCheckboxItem: function(label, handler, checked, disabled)
{
var id = this._items.length;
this._items.push({type: "checkbox", id: id, label: label, checked: !!checked, enabled: !disabled});
this._handlers[id] = handler;
},

appendSeparator: function()
{

if (this._items.length === 0)
return;
if (!("id" in this._items[this._items.length - 1]))
return;
this._items.push({type: "separator"});
},

_itemSelected: function(id)
{
if (this._handlers[id])
this._handlers[id].call(this);
}
}

WebInspector.contextMenuItemSelected = function(id)
{
if (WebInspector._contextMenu)
WebInspector._contextMenu._itemSelected(id);
}

WebInspector.contextMenuCleared = function()
{


}





WebInspector.KeyboardShortcut = function()
{
};


WebInspector.KeyboardShortcut.Modifiers = {
None: 0,   
Shift: 1,
Ctrl: 2,
Alt: 4,
Meta: 8,   
get CtrlOrMeta()
{

return WebInspector.isMac() ? this.Meta : this.Ctrl;
}
};

WebInspector.KeyboardShortcut.Keys = {
Backspace: { code: 8, name: "\u21a4" },
Tab: { code: 9, name: { mac: "\u21e5", other: "<Tab>" } },
Enter: { code: 13, name: { mac: "\u21a9", other: "<Enter>" } },
Esc: { code: 27, name: { mac: "\u238b", other: "<Esc>" } },
Space: { code: 32, name: "<Space>" },
PageUp: { code: 33,  name: { mac: "\u21de", other: "<PageUp>" } },      
PageDown: { code: 34, name: { mac: "\u21df", other: "<PageDown>" } },   
End: { code: 35, name: { mac: "\u2197", other: "<End>" } },             
Home: { code: 36, name: { mac: "\u2196", other: "<Home>" } },           
Left: { code: 37, name: "\u2190" },           
Up: { code: 38, name: "\u2191" },             
Right: { code: 39, name: "\u2192" },          
Down: { code: 40, name: "\u2193" },           
Delete: { code: 46, name: "<Del>" },
Zero: { code: 48, name: "0" },
F1: { code: 112, name: "F1" },
F2: { code: 113, name: "F2" },
F3: { code: 114, name: "F3" },
F4: { code: 115, name: "F4" },
F5: { code: 116, name: "F5" },
F6: { code: 117, name: "F6" },
F7: { code: 118, name: "F7" },
F8: { code: 119, name: "F8" },
F9: { code: 120, name: "F9" },
F10: { code: 121, name: "F10" },
F11: { code: 122, name: "F11" },
F12: { code: 123, name: "F12" },
Semicolon: { code: 186, name: ";" },
Plus: { code: 187, name: "+" },
Comma: { code: 188, name: "," },
Minus: { code: 189, name: "-" },
Period: { code: 190, name: "." },
Slash: { code: 191, name: "/" },
Apostrophe: { code: 192, name: "`" },
SingleQuote: { code: 222, name: "\'" }
};


WebInspector.KeyboardShortcut.makeKey = function(keyCode, optModifiers)
{
if (typeof keyCode === "string")
keyCode = keyCode.charCodeAt(0) - 32;
var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
for (var i = 1; i < arguments.length; i++)
modifiers |= arguments[i];
return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
};

WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
{
var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
if (keyboardEvent.shiftKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
if (keyboardEvent.ctrlKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl;
if (keyboardEvent.altKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
if (keyboardEvent.metaKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyboardEvent.keyCode, modifiers);
};

WebInspector.KeyboardShortcut.makeDescriptor = function(key, optModifiers)
{
var modifiers = 0;
for (var i = 1; i < arguments.length; i++)
modifiers |= arguments[i];

return {
key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key : key.code, modifiers),
name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers)
};
}

WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers)
{
return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key);
}

WebInspector.KeyboardShortcut._keyName = function(key)
{
if (typeof key === "string")
return key.toUpperCase();
if (typeof key.name === "string")
return key.name;
return key.name[WebInspector.platform] || key.name.other;
}

WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
{
return (keyCode & 255) | (modifiers << 8);
};

WebInspector.KeyboardShortcut._modifiersToString = function(modifiers)
{
const cmdKey = "\u2318";
const optKey = "\u2325";
const shiftKey = "\u21e7";
const ctrlKey = "\u2303";

var isMac = WebInspector.isMac();
var res = "";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Ctrl)
res += isMac ? ctrlKey : "<Ctrl> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Alt)
res += isMac ? optKey : "<Alt> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Shift)
res += isMac ? shiftKey : "<Shift> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Meta)
res += isMac ? cmdKey : "<Win> + ";

return res;
};





WebInspector.TextPrompt = function(element, completions, stopCharacters)
{
this.element = element;
this.element.addStyleClass("text-prompt");
this.completions = completions;
this.completionStopCharacters = stopCharacters;
this.history = [];
this.historyOffset = 0;
this.element.addEventListener("keydown", this._onKeyDown.bind(this), true);
}

WebInspector.TextPrompt.prototype = {
get text()
{
return this.element.textContent;
},

set text(x)
{
if (!x) {

this.element.removeChildren();
this.element.appendChild(document.createElement("br"));
} else
this.element.textContent = x;

this.moveCaretToEndOfPrompt();
},

_onKeyDown: function(event)
{
function defaultAction()
{
this.clearAutoComplete();
this.autoCompleteSoon();
}

var handled = false;
switch (event.keyIdentifier) {
case "Up":
this._upKeyPressed(event);
break;
case "Down":
this._downKeyPressed(event);
break;
case "U+0009": 
this._tabKeyPressed(event);
break;
case "Right":
case "End":
if (!this.acceptAutoComplete())
this.autoCompleteSoon();
break;
case "Alt":
case "Meta":
case "Shift":
case "Control":
break;
case "U+0050": 
if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
handled = true;
this._moveBackInHistory();
break;
}
defaultAction.call(this);
break;
case "U+004E": 
if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
handled = true;
this._moveForwardInHistory();
break;
}
defaultAction.call(this);
break;
default:
defaultAction.call(this);
break;
}

if (handled) {
event.preventDefault();
event.stopPropagation();
}
},

acceptAutoComplete: function()
{
if (!this.autoCompleteElement || !this.autoCompleteElement.parentNode)
return false;

var text = this.autoCompleteElement.textContent;
var textNode = document.createTextNode(text);
this.autoCompleteElement.parentNode.replaceChild(textNode, this.autoCompleteElement);
delete this.autoCompleteElement;

var finalSelectionRange = document.createRange();
finalSelectionRange.setStart(textNode, text.length);
finalSelectionRange.setEnd(textNode, text.length);

var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(finalSelectionRange);

return true;
},

clearAutoComplete: function(includeTimeout)
{
if (includeTimeout && "_completeTimeout" in this) {
clearTimeout(this._completeTimeout);
delete this._completeTimeout;
}

if (!this.autoCompleteElement)
return;

if (this.autoCompleteElement.parentNode)
this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
delete this.autoCompleteElement;

if (!this._userEnteredRange || !this._userEnteredText)
return;

this._userEnteredRange.deleteContents();
this.element.pruneEmptyTextNodes();

var userTextNode = document.createTextNode(this._userEnteredText);
this._userEnteredRange.insertNode(userTextNode);

var selectionRange = document.createRange();
selectionRange.setStart(userTextNode, this._userEnteredText.length);
selectionRange.setEnd(userTextNode, this._userEnteredText.length);

var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(selectionRange);

delete this._userEnteredRange;
delete this._userEnteredText;
},

autoCompleteSoon: function()
{
if (!("_completeTimeout" in this))
this._completeTimeout = setTimeout(this.complete.bind(this, true), 250);
},

complete: function(auto, reverse)
{
this.clearAutoComplete(true);
var selection = window.getSelection();
if (!selection.rangeCount)
return;

var selectionRange = selection.getRangeAt(0);
if (!selectionRange.commonAncestorContainer.isDescendant(this.element))
return;
if (auto && !this.isCaretAtEndOfPrompt())
return;
var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this.completionStopCharacters, this.element, "backward");
this.completions(wordPrefixRange, auto, this._completionsReady.bind(this, selection, auto, wordPrefixRange, reverse));
},

_completionsReady: function(selection, auto, originalWordPrefixRange, reverse, completions)
{
if (!completions || !completions.length)
return;

var selectionRange = selection.getRangeAt(0);

var fullWordRange = document.createRange();
fullWordRange.setStart(originalWordPrefixRange.startContainer, originalWordPrefixRange.startOffset);
fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffset);

if (originalWordPrefixRange.toString() + selectionRange.toString() != fullWordRange.toString())
return;

var wordPrefixLength = originalWordPrefixRange.toString().length;

if (auto)
var completionText = completions[0];
else {
if (completions.length === 1) {
var completionText = completions[0];
wordPrefixLength = completionText.length;
} else {
var commonPrefix = completions[0];
for (var i = 0; i < completions.length; ++i) {
var completion = completions[i];
var lastIndex = Math.min(commonPrefix.length, completion.length);
for (var j = wordPrefixLength; j < lastIndex; ++j) {
if (commonPrefix[j] !== completion[j]) {
commonPrefix = commonPrefix.substr(0, j);
break;
}
}
}
wordPrefixLength = commonPrefix.length;

if (selection.isCollapsed)
var completionText = completions[0];
else {
var currentText = fullWordRange.toString();

var foundIndex = null;
for (var i = 0; i < completions.length; ++i) {
if (completions[i] === currentText)
foundIndex = i;
}

var nextIndex = foundIndex + (reverse ? -1 : 1);
if (foundIndex === null || nextIndex >= completions.length)
var completionText = completions[0];
else if (nextIndex < 0)
var completionText = completions[completions.length - 1];
else
var completionText = completions[nextIndex];
}
}
}

this._userEnteredRange = fullWordRange;
this._userEnteredText = fullWordRange.toString();

fullWordRange.deleteContents();
this.element.pruneEmptyTextNodes();

var finalSelectionRange = document.createRange();

if (auto) {
var prefixText = completionText.substring(0, wordPrefixLength);
var suffixText = completionText.substring(wordPrefixLength);

var prefixTextNode = document.createTextNode(prefixText);
fullWordRange.insertNode(prefixTextNode);

this.autoCompleteElement = document.createElement("span");
this.autoCompleteElement.className = "auto-complete-text";
this.autoCompleteElement.textContent = suffixText;

prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, prefixTextNode.nextSibling);

finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
} else {
var completionTextNode = document.createTextNode(completionText);
fullWordRange.insertNode(completionTextNode);

if (completions.length > 1)
finalSelectionRange.setStart(completionTextNode, wordPrefixLength);
else
finalSelectionRange.setStart(completionTextNode, completionText.length);

finalSelectionRange.setEnd(completionTextNode, completionText.length);
}

selection.removeAllRanges();
selection.addRange(finalSelectionRange);
},

isCaretInsidePrompt: function()
{
return this.element.isInsertionCaretInside();
},

isCaretAtEndOfPrompt: function()
{
var selection = window.getSelection();
if (!selection.rangeCount || !selection.isCollapsed)
return false;

var selectionRange = selection.getRangeAt(0);
var node = selectionRange.startContainer;
if (node !== this.element && !node.isDescendant(this.element))
return false;

if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < node.nodeValue.length)
return false;

var foundNextText = false;
while (node) {
if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) {
if (foundNextText)
return false;
foundNextText = true;
}

node = node.traverseNextNode(this.element);
}

return true;
},

isCaretOnFirstLine: function()
{
var selection = window.getSelection();
var focusNode = selection.focusNode;
if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this.element)
return true;

if (focusNode.textContent.substring(0, selection.focusOffset).indexOf("\n") !== -1)
return false;
focusNode = focusNode.previousSibling;

while (focusNode) {
if (focusNode.nodeType !== Node.TEXT_NODE)
return true;
if (focusNode.textContent.indexOf("\n") !== -1)
return false;
focusNode = focusNode.previousSibling;
}

return true;
},

isCaretOnLastLine: function()
{
var selection = window.getSelection();
var focusNode = selection.focusNode;
if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this.element)
return true;

if (focusNode.textContent.substring(selection.focusOffset).indexOf("\n") !== -1)
return false;
focusNode = focusNode.nextSibling;

while (focusNode) {
if (focusNode.nodeType !== Node.TEXT_NODE)
return true;
if (focusNode.textContent.indexOf("\n") !== -1)
return false;
focusNode = focusNode.nextSibling;
}

return true;
},

moveCaretToEndOfPrompt: function()
{
var selection = window.getSelection();
var selectionRange = document.createRange();

var offset = this.element.childNodes.length;
selectionRange.setStart(this.element, offset);
selectionRange.setEnd(this.element, offset);

selection.removeAllRanges();
selection.addRange(selectionRange);
},

_tabKeyPressed: function(event)
{
event.preventDefault();
event.stopPropagation();

this.complete(false, event.shiftKey);
},

_upKeyPressed: function(event)
{
if (!this.isCaretOnFirstLine())
return;

event.preventDefault();
event.stopPropagation();

this._moveBackInHistory();
},

_downKeyPressed: function(event)
{
if (!this.isCaretOnLastLine())
return;

event.preventDefault();
event.stopPropagation();

this._moveForwardInHistory();
},

_moveBackInHistory: function()
{
if (this.historyOffset == this.history.length)
return;

this.clearAutoComplete(true);

if (this.historyOffset === 0)
this.tempSavedCommand = this.text;

++this.historyOffset;
this.text = this.history[this.history.length - this.historyOffset];

this.element.scrollIntoViewIfNeeded();
var firstNewlineIndex = this.text.indexOf("\n");
if (firstNewlineIndex === -1)
this.moveCaretToEndOfPrompt();
else {
var selection = window.getSelection();
var selectionRange = document.createRange();

selectionRange.setStart(this.element.firstChild, firstNewlineIndex);
selectionRange.setEnd(this.element.firstChild, firstNewlineIndex);

selection.removeAllRanges();
selection.addRange(selectionRange);
}
},

_moveForwardInHistory: function()
{
if (this.historyOffset === 0)
return;

this.clearAutoComplete(true);

--this.historyOffset;

if (this.historyOffset === 0) {
this.text = this.tempSavedCommand;
delete this.tempSavedCommand;
return;
}

this.text = this.history[this.history.length - this.historyOffset];
this.element.scrollIntoViewIfNeeded();
}
}





WebInspector.Popover = function(contentElement)
{
this.element = document.createElement("div");
this.element.className = "popover";

this._popupArrowElement = document.createElement("div");
this._popupArrowElement.className = "arrow";
this.element.appendChild(this._popupArrowElement);

this.contentElement = contentElement;
this._contentDiv = document.createElement("div");
this._contentDiv.className = "content";
}

WebInspector.Popover.prototype = {
show: function(anchor, preferredWidth, preferredHeight)
{

if (WebInspector.Popover._popoverElement)
document.body.removeChild(WebInspector.Popover._popoverElement);
WebInspector.Popover._popoverElement = this.element;


this.contentElement.positionAt(0, 0);
document.body.appendChild(this.contentElement);
var preferredWidth = preferredWidth || this.contentElement.offsetWidth;
var preferredHeight = preferredHeight || this.contentElement.offsetHeight;

this._contentDiv.appendChild(this.contentElement);
this.element.appendChild(this._contentDiv);
document.body.appendChild(this.element);
this._positionElement(anchor, preferredWidth, preferredHeight);
},

hide: function()
{
if (WebInspector.Popover._popoverElement) {
delete WebInspector.Popover._popoverElement;
document.body.removeChild(this.element);
}
},

_positionElement: function(anchorElement, preferredWidth, preferredHeight)
{
const borderWidth = 25;
const scrollerWidth = 11;
const arrowHeight = 15;
const arrowOffset = 10;
const borderRadius = 10;


preferredWidth = Math.max(preferredWidth, 50);
const totalWidth = window.innerWidth;
const totalHeight = window.innerHeight;

var anchorBox = {x: anchorElement.totalOffsetLeft, y: anchorElement.totalOffsetTop, width: anchorElement.offsetWidth, height: anchorElement.offsetHeight};
while (anchorElement !== document.body) {
if (anchorElement.scrollLeft)
anchorBox.x -= anchorElement.scrollLeft;
if (anchorElement.scrollTop)
anchorBox.y -= anchorElement.scrollTop;
anchorElement = anchorElement.parentElement;
}

var newElementPosition = { x: 0, y: 0, width: preferredWidth + scrollerWidth, height: preferredHeight };

var verticalAlignment;
var roomAbove = anchorBox.y;
var roomBelow = totalHeight - anchorBox.y - anchorBox.height;

if (roomAbove > roomBelow) {

if (anchorBox.y > newElementPosition.height + arrowHeight + borderRadius)
newElementPosition.y = anchorBox.y - newElementPosition.height - arrowHeight;
else {
newElementPosition.y = borderRadius * 2;
newElementPosition.height = anchorBox.y - borderRadius * 2 - arrowHeight;
}
verticalAlignment = "bottom";
} else {

newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight;
if (newElementPosition.y + newElementPosition.height + arrowHeight - borderWidth >= totalHeight)
newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height - borderRadius * 2 - arrowHeight;

verticalAlignment = "top";
}

var horizontalAlignment;
if (anchorBox.x + newElementPosition.width < totalWidth) {
newElementPosition.x = Math.max(borderRadius, anchorBox.x - borderRadius - arrowOffset);
horizontalAlignment = "left";
} else if (newElementPosition.width + borderRadius * 2 < totalWidth) {
newElementPosition.x = totalWidth - newElementPosition.width - borderRadius;
horizontalAlignment = "right";

var arrowRightPosition = Math.max(0, totalWidth - anchorBox.x - anchorBox.width - borderRadius - arrowOffset);
arrowRightPosition += anchorBox.width / 2;
this._popupArrowElement.style.right = arrowRightPosition + "px";
} else {
newElementPosition.x = borderRadius;
newElementPosition.width = totalWidth - borderRadius * 2;
newElementPosition.height += scrollerWidth;
horizontalAlignment = "left";
if (verticalAlignment === "bottom")
newElementPosition.y -= scrollerWidth;

this._popupArrowElement.style.left = Math.max(0, anchorBox.x - borderRadius * 2 - arrowOffset) + "px";
this._popupArrowElement.style.left += anchorBox.width / 2;
}

this.element.className = "popover " + verticalAlignment + "-" + horizontalAlignment + "-arrow";
this.element.positionAt(newElementPosition.x - borderWidth, newElementPosition.y - borderWidth);
this.element.style.width = newElementPosition.width + borderWidth * 2 + "px";
this.element.style.height = newElementPosition.height + borderWidth * 2 + "px";
}
}

WebInspector.PopoverHelper = function(panelElement, getAnchor, showPopup, showOnClick, onHide)
{
this._panelElement = panelElement;
this._getAnchor = getAnchor;
this._showPopup = showPopup;
this._showOnClick = showOnClick;
this._onHide = onHide;
panelElement.addEventListener("mousedown", this._mouseDown.bind(this), false);
panelElement.addEventListener("mousemove", this._mouseMove.bind(this), false);
this.setTimeout(1000);
}

WebInspector.PopoverHelper.prototype = {
setTimeout: function(timeout)
{
this._timeout = timeout;
},

_mouseDown: function(event)
{
this._killHidePopupTimer();
this._handleMouseAction(event, true);
},

_mouseMove: function(event)
{

if (this._hoverElement === event.target || (this._hoverElement && this._hoverElement.isAncestor(event.target)))
return;


if (this._popup && !this._hidePopupTimer) {
var self = this;
function doHide()
{
self._hidePopup();
delete self._hidePopupTimer;
}
this._hidePopupTimer = setTimeout(doHide, this._timeout / 2);
}

this._handleMouseAction(event);
},

_handleMouseAction: function(event, isMouseDown)
{
this._resetHoverTimer();

this._hoverElement = this._getAnchor(event.target);
if (!this._hoverElement)
return;

const toolTipDelay = isMouseDown ? 0 : (this._popup ? this._timeout * 0.6 : this._timeout);
this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
},

_resetHoverTimer: function()
{
if (this._hoverTimer) {
clearTimeout(this._hoverTimer);
delete this._hoverTimer;
}
},

hidePopup: function()
{
this._resetHoverTimer();
this._hidePopup();
},

_hidePopup: function()
{
if (!this._popup)
return;

if (this._onHide)
this._onHide();

this._popup.hide();
delete this._popup;
},

_mouseHover: function(element)
{
delete this._hoverTimer;

this._popup = this._showPopup(element);
if (this._popup)
this._popup.contentElement.addEventListener("mousemove", this._killHidePopupTimer.bind(this), true);
},

_killHidePopupTimer: function()
{
if (this._hidePopupTimer) {
clearTimeout(this._hidePopupTimer);
delete this._hidePopupTimer;



this._resetHoverTimer();
}
}
}





WebInspector.TabbedPane = function(element)
{
this.element = element || document.createElement("div");
this.element.addStyleClass("tabbed-pane");
this._tabsElement = this.element.createChild("div", "tabbed-pane-header");
this._contentElement = this.element.createChild("div", "tabbed-pane-content");
this._tabs = {};
}

WebInspector.TabbedPane.prototype = {
appendTab: function(id, tabTitle, view)
{
var tabElement = document.createElement("li");
tabElement.textContent = tabTitle;
tabElement.addEventListener("click", this.selectTab.bind(this, id, true), false);

this._tabsElement.appendChild(tabElement);
this._contentElement.appendChild(view.element);

this._tabs[id] = { tabElement: tabElement, view: view }
},

selectTab: function(id, userGesture)
{
if (!(id in this._tabs))
return false;

if (this._currentTab) {
this._hideTab(this._currentTab)
delete this._currentTab;
}

var tab = this._tabs[id];
this._showTab(tab);
this._currentTab = tab;
if (userGesture) {
var event = {tabId: id};
this.dispatchEventToListeners("tab-selected", event);
}
return true;
},

_showTab: function(tab)
{
tab.tabElement.addStyleClass("selected");
tab.view.show(this._contentElement);
},

_hideTab: function(tab)
{
tab.tabElement.removeStyleClass("selected");
tab.view.visible = false;
}
}

WebInspector.TabbedPane.prototype.__proto__ = WebInspector.Object.prototype;





WebInspector.Placard = function(title, subtitle)
{
this.element = document.createElement("div");
this.element.className = "placard";
this.element.placard = this;

this.titleElement = document.createElement("div");
this.titleElement.className = "title";

this.subtitleElement = document.createElement("div");
this.subtitleElement.className = "subtitle";

this.element.appendChild(this.subtitleElement);
this.element.appendChild(this.titleElement);

this.title = title;
this.subtitle = subtitle;
this.selected = false;
}

WebInspector.Placard.prototype = {
get title()
{
return this._title;
},

set title(x)
{
if (this._title === x)
return;
this._title = x;
this.titleElement.textContent = x;
},

get subtitle()
{
return this._subtitle;
},

set subtitle(x)
{
if (this._subtitle === x)
return;
this._subtitle = x;
this.subtitleElement.innerHTML = x;
},

get selected()
{
return this._selected;
},

set selected(x)
{
if (x)
this.select();
else
this.deselect();
},

select: function()
{
if (this._selected)
return;
this._selected = true;
this.element.addStyleClass("selected");
},

deselect: function()
{
if (!this._selected)
return;
this._selected = false;
this.element.removeStyleClass("selected");
},

toggleSelected: function()
{
this.selected = !this.selected;
}
}





WebInspector.View = function(element)
{
this.element = element || document.createElement("div");
this._visible = false;
}

WebInspector.View.prototype = {
get visible()
{
return this._visible;
},

set visible(x)
{
if (this._visible === x)
return;

if (x)
this.show();
else
this.hide();
},

show: function(parentElement)
{
this._visible = true;
if (parentElement && parentElement !== this.element.parentNode) {
this.detach();
parentElement.appendChild(this.element);
}
if (!this.element.parentNode && this.attach)
this.attach();
this.element.addStyleClass("visible");
},

hide: function()
{
this.element.removeStyleClass("visible");
this._visible = false;
},

detach: function()
{
if (this.element.parentNode)
this.element.parentNode.removeChild(this.element);
}
}

WebInspector.View.prototype.__proto__ = WebInspector.Object.prototype;





WebInspector.Callback = function()
{
this._lastCallbackId = 1;
this._callbacks = {};
}

WebInspector.Callback.prototype = {
wrap: function(callback)
{
var callbackId = this._lastCallbackId++;
this._callbacks[callbackId] = callback || function() {};
return callbackId;
},

processResponse: function(callbackId, args)
{
var callback = this._callbacks[callbackId];
callback.apply(null, args);
delete this._callbacks[callbackId];
},

removeResponseCallbackEntry: function(callbackId)
{
delete this._callbacks[callbackId];
}
}

WebInspector.Callback._INSTANCE = new WebInspector.Callback();
WebInspector.Callback.wrap = WebInspector.Callback._INSTANCE.wrap.bind(WebInspector.Callback._INSTANCE);
WebInspector.processResponse = WebInspector.Callback._INSTANCE.processResponse.bind(WebInspector.Callback._INSTANCE);
WebInspector.removeResponseCallbackEntry = WebInspector.Callback._INSTANCE.removeResponseCallbackEntry.bind(WebInspector.Callback._INSTANCE);





WebInspector.Drawer = function()
{
WebInspector.View.call(this, document.getElementById("drawer"));

this._savedHeight = 200; 
this.state = WebInspector.Drawer.State.Hidden;
this.fullPanel = false;

this.mainElement = document.getElementById("main");
this.toolbarElement = document.getElementById("toolbar");
this.mainStatusBar = document.getElementById("main-status-bar");
this.mainStatusBar.addEventListener("mousedown", this._startStatusBarDragging.bind(this), true);
this.viewStatusBar = document.getElementById("other-drawer-status-bar-items");
this._counters = document.getElementById("counters");
this._drawerStatusBar = document.getElementById("drawer-status-bar");
}

WebInspector.Drawer.prototype = {
get visibleView()
{
return this._visibleView;
},

set visibleView(x)
{
if (this._visibleView === x) {
if (this.visible && this.fullPanel)
return;
this.visible = !this.visible;
return;
}

var firstTime = !this._visibleView;
if (this._visibleView)
this._visibleView.hide();

this._visibleView = x;

if (x && !firstTime) {
this._safelyRemoveChildren();
this.viewStatusBar.removeChildren(); 
x.attach(this.element, this.viewStatusBar);
x.show();
this.visible = true;
}
},

get savedHeight()
{
var height = this._savedHeight || this.element.offsetHeight;
return Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this.mainElement.totalOffsetTop - Preferences.minConsoleHeight);
},

showView: function(view)
{
if (!this.visible || this.visibleView !== view)
this.visibleView = view;
},

show: function()
{
if (this._animating || this.visible)
return;

if (this.visibleView)
this.visibleView.show();

WebInspector.View.prototype.show.call(this);

this._animating = true;

document.body.addStyleClass("drawer-visible");

var anchoredItems = document.getElementById("anchored-status-bar-items");
var height = (this.fullPanel ? window.innerHeight - this.toolbarElement.offsetHeight : this.savedHeight);
var animations = [
{element: this.element, end: {height: height}},
{element: document.getElementById("main"), end: {bottom: height}},
{element: document.getElementById("main-status-bar"), start: {"padding-left": anchoredItems.offsetWidth - 1}, end: {"padding-left": 0}},
{element: document.getElementById("other-drawer-status-bar-items"), start: {opacity: 0}, end: {opacity: 1}}
];

var drawerStatusBar = document.getElementById("drawer-status-bar");
drawerStatusBar.insertBefore(anchoredItems, drawerStatusBar.firstChild);

if (this._currentPanelCounters) {
var oldRight = this._drawerStatusBar.clientWidth - (this._counters.offsetLeft + this._currentPanelCounters.offsetWidth);
var newRight = WebInspector.Panel.counterRightMargin;
var rightPadding = (oldRight - newRight);
animations.push({element: this._currentPanelCounters, start: {"padding-right": rightPadding}, end: {"padding-right": 0}});
this._currentPanelCounters.parentNode.removeChild(this._currentPanelCounters);
this.mainStatusBar.appendChild(this._currentPanelCounters);
}

function animationFinished()
{
if ("updateStatusBarItems" in WebInspector.currentPanel)
WebInspector.currentPanel.updateStatusBarItems();
if (this.visibleView.afterShow)
this.visibleView.afterShow();
delete this._animating;
delete this._currentAnimationInterval;
this.state = (this.fullPanel ? WebInspector.Drawer.State.Full : WebInspector.Drawer.State.Variable);
if (this._currentPanelCounters)
this._currentPanelCounters.removeAttribute("style");
}

this._currentAnimationInterval = WebInspector.animateStyle(animations, this._animationDuration(), animationFinished.bind(this));
},

hide: function()
{
if (this._animating || !this.visible)
return;

WebInspector.View.prototype.hide.call(this);

if (this.visibleView)
this.visibleView.hide();

this._animating = true;

if (!this.fullPanel)
this._savedHeight = this.element.offsetHeight;

if (this.element === WebInspector.currentFocusElement || this.element.isAncestor(WebInspector.currentFocusElement))
WebInspector.currentFocusElement = WebInspector.previousFocusElement;

var anchoredItems = document.getElementById("anchored-status-bar-items");



this.mainStatusBar.style.setProperty("padding-left", (anchoredItems.offsetWidth - 1) + "px");
document.body.removeStyleClass("drawer-visible");
if ("updateStatusBarItems" in WebInspector.currentPanel)
WebInspector.currentPanel.updateStatusBarItems();
document.body.addStyleClass("drawer-visible");

var animations = [
{element: document.getElementById("main"), end: {bottom: 0}},
{element: document.getElementById("main-status-bar"), start: {"padding-left": 0}, end: {"padding-left": anchoredItems.offsetWidth - 1}},
{element: document.getElementById("other-drawer-status-bar-items"), start: {opacity: 1}, end: {opacity: 0}}
];

if (this._currentPanelCounters) {
var newRight = this._drawerStatusBar.clientWidth - this._counters.offsetLeft;
var oldRight = this.mainStatusBar.clientWidth - (this._currentPanelCounters.offsetLeft + this._currentPanelCounters.offsetWidth);
var rightPadding = (newRight - oldRight);
animations.push({element: this._currentPanelCounters, start: {"padding-right": 0}, end: {"padding-right": rightPadding}});
}

function animationFinished()
{
WebInspector.currentPanel.resize();
var mainStatusBar = document.getElementById("main-status-bar");
mainStatusBar.insertBefore(anchoredItems, mainStatusBar.firstChild);
mainStatusBar.style.removeProperty("padding-left");

if (this._currentPanelCounters) {
this._currentPanelCounters.setAttribute("style", null);
this._currentPanelCounters.parentNode.removeChild(this._currentPanelCounters);
this._counters.insertBefore(this._currentPanelCounters, this._counters.firstChild);
}

document.body.removeStyleClass("drawer-visible");
delete this._animating;
delete this._currentAnimationInterval;
this.state = WebInspector.Drawer.State.Hidden;
}

this._currentAnimationInterval = WebInspector.animateStyle(animations, this._animationDuration(), animationFinished.bind(this));
},

resize: function()
{
if (this.state === WebInspector.Drawer.State.Hidden)
return;

var height;
var mainElement = document.getElementById("main");
if (this.state === WebInspector.Drawer.State.Variable) {
height = parseInt(this.element.style.height);
height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - mainElement.totalOffsetTop - Preferences.minConsoleHeight);
} else
height = window.innerHeight - this.toolbarElement.offsetHeight;

mainElement.style.bottom = height + "px";
this.element.style.height = height + "px";
},

enterPanelMode: function()
{
this._cancelAnimationIfNeeded();
this.fullPanel = true;

if (this.visible) {
this._savedHeight = this.element.offsetHeight;
var height = window.innerHeight - this.toolbarElement.offsetHeight;
this._animateDrawerHeight(height, WebInspector.Drawer.State.Full);
}
},

exitPanelMode: function()
{
this._cancelAnimationIfNeeded();
this.fullPanel = false;

if (this.visible) {


this.state = WebInspector.Drawer.State.Variable;
var height = this.savedHeight;
this._animateDrawerHeight(height, WebInspector.Drawer.State.Variable);
}
},

immediatelyExitPanelMode: function()
{
this.visible = false;
this.fullPanel = false;
},

set currentPanelCounters(x)
{
if (!x) {
if (this._currentPanelCounters)
this._currentPanelCounters.parentElement.removeChild(this._currentPanelCounters);
delete this._currentPanelCounters;
return;
}

this._currentPanelCounters = x;
if (this.visible)
this.mainStatusBar.appendChild(x);
else
this._counters.insertBefore(x, this._counters.firstChild);
},

_cancelAnimationIfNeeded: function()
{
if (this._animating) {
clearInterval(this._currentAnimationInterval);
delete this._animating;
delete this._currentAnimationInterval;
}
},

_animateDrawerHeight: function(height, finalState)
{
this._animating = true;
var animations = [
{element: this.element, end: {height: height}},
{element: document.getElementById("main"), end: {bottom: height}}
];

function animationFinished()
{
delete this._animating;
delete this._currentAnimationInterval;
this.state = finalState;
}

this._currentAnimationInterval = WebInspector.animateStyle(animations, this._animationDuration(), animationFinished.bind(this));
},

_animationDuration: function()
{

if (this.fullPanel && (this.state === WebInspector.Drawer.State.Hidden || this.state === WebInspector.Drawer.State.Full))
return 0;

return (window.event && window.event.shiftKey ? 2000 : 250);
},

_safelyRemoveChildren: function()
{
var child = this.element.firstChild;
while (child) {
if (child.id !== "drawer-status-bar") {
var moveTo = child.nextSibling;
this.element.removeChild(child);
child = moveTo;
} else
child = child.nextSibling;
}
},

_startStatusBarDragging: function(event)
{
if (!this.visible || event.target !== this.mainStatusBar)
return;

WebInspector.elementDragStart(this.mainStatusBar, this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), event, "row-resize");

this._statusBarDragOffset = event.pageY - this.element.totalOffsetTop;

event.stopPropagation();
},

_statusBarDragging: function(event)
{
var mainElement = document.getElementById("main");
var height = window.innerHeight - event.pageY + this._statusBarDragOffset;
height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - mainElement.totalOffsetTop - Preferences.minConsoleHeight);

mainElement.style.bottom = height + "px";
this.element.style.height = height + "px";

event.preventDefault();
event.stopPropagation();
},

_endStatusBarDragging: function(event)
{
WebInspector.elementDragEnd(event);

this._savedHeight = this.element.offsetHeight;
delete this._statusBarDragOffset;

event.stopPropagation();
}
}

WebInspector.Drawer.prototype.__proto__ = WebInspector.View.prototype;

WebInspector.Drawer.State = {
Hidden: 0,
Variable: 1,
Full: 2
};





WebInspector.ChangesView = function(drawer)
{
WebInspector.View.call(this);
this.element.innerHTML = "<div style=\"bottom:25%;color:rgb(192,192,192);font-size:12px;height:65px;left:0px;margin:auto;position:absolute;right:0px;text-align:center;top:0px;\"><h1>Not Implemented Yet</h1></div>";

this.drawer = drawer;

this.clearButton = document.createElement("button");
this.clearButton.id = "clear-changes-status-bar-item";
this.clearButton.title = WebInspector.UIString("Clear changes log.");
this.clearButton.className = "status-bar-item clear-status-bar-item";
this.clearButton.addEventListener("click", this._clearButtonClicked.bind(this), false);

this.toggleChangesButton = document.getElementById("changes-status-bar-item");
this.toggleChangesButton.title = WebInspector.UIString("Show changes view.");
this.toggleChangesButton.addEventListener("click", this._toggleChangesButtonClicked.bind(this), false);
var anchoredStatusBar = document.getElementById("anchored-status-bar-items");
anchoredStatusBar.appendChild(this.toggleChangesButton);
}

WebInspector.ChangesView.prototype = {
_clearButtonClicked: function()
{

},

_toggleChangesButtonClicked: function()
{
this.drawer.visibleView = this;
},

attach: function(mainElement, statusBarElement)
{
mainElement.appendChild(this.element);
statusBarElement.appendChild(this.clearButton);
},

show: function()
{
this.toggleChangesButton.addStyleClass("toggled-on");
this.toggleChangesButton.title = WebInspector.UIString("Hide changes view.");
},

hide: function()
{
this.toggleChangesButton.removeStyleClass("toggled-on");
this.toggleChangesButton.title = WebInspector.UIString("Show changes view.");
}
}

WebInspector.ChangesView.prototype.__proto__ = WebInspector.View.prototype;





const ExpressionStopCharacters = " =:[({;,!+-*/&|^<>";

WebInspector.ConsoleView = function(drawer)
{
WebInspector.View.call(this, document.getElementById("console-view"));

this.messages = [];
this.drawer = drawer;

this.clearButton = document.getElementById("clear-console-status-bar-item");
this.clearButton.title = WebInspector.UIString("Clear console log.");
this.clearButton.addEventListener("click", this._clearButtonClicked.bind(this), false);

this.messagesElement = document.getElementById("console-messages");
this.messagesElement.addEventListener("selectstart", this._messagesSelectStart.bind(this), false);
this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);

this.promptElement = document.getElementById("console-prompt");
this.promptElement.className = "source-code";
this.promptElement.addEventListener("keydown", this._promptKeyDown.bind(this), true);
this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), ExpressionStopCharacters + ".");
this.prompt.history = WebInspector.settings.consoleHistory;

this.topGroup = new WebInspector.ConsoleGroup(null, 0);
this.messagesElement.insertBefore(this.topGroup.element, this.promptElement);
this.groupLevel = 0;
this.currentGroup = this.topGroup;

this.toggleConsoleButton = document.getElementById("console-status-bar-item");
this.toggleConsoleButton.title = WebInspector.UIString("Show console.");
this.toggleConsoleButton.addEventListener("click", this._toggleConsoleButtonClicked.bind(this), false);


this.filterBarElement = document.getElementById("console-filter");

function createDividerElement() {
var dividerElement = document.createElement("div");
dividerElement.addStyleClass("scope-bar-divider");
this.filterBarElement.appendChild(dividerElement);
}

var updateFilterHandler = this._updateFilter.bind(this);
function createFilterElement(category) {
var categoryElement = document.createElement("li");
categoryElement.category = category;
categoryElement.addStyleClass(categoryElement.category);            
categoryElement.addEventListener("click", updateFilterHandler, false);

var label = category.toString();
categoryElement.appendChild(document.createTextNode(label));

this.filterBarElement.appendChild(categoryElement);
return categoryElement;
}

this.allElement = createFilterElement.call(this, WebInspector.UIString("All"));
createDividerElement.call(this);
this.errorElement = createFilterElement.call(this, WebInspector.UIString("Errors"));
this.warningElement = createFilterElement.call(this, WebInspector.UIString("Warnings"));
this.logElement = createFilterElement.call(this, WebInspector.UIString("Logs"));

this.filter(this.allElement, false);
this._registerShortcuts();

this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);

this._customFormatters = {
"object": this._formatobject,
"array":  this._formatarray,
"node":   this._formatnode,
"string": this._formatstring
};
}

WebInspector.ConsoleView.prototype = {
_updateFilter: function(e)
{
var isMac = WebInspector.isMac();
var selectMultiple = false;
if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
selectMultiple = true;
if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
selectMultiple = true;

this.filter(e.target, selectMultiple);
},

filter: function(target, selectMultiple)
{
function unselectAll()
{
this.allElement.removeStyleClass("selected");
this.errorElement.removeStyleClass("selected");
this.warningElement.removeStyleClass("selected");
this.logElement.removeStyleClass("selected");

this.messagesElement.removeStyleClass("filter-all");
this.messagesElement.removeStyleClass("filter-errors");
this.messagesElement.removeStyleClass("filter-warnings");
this.messagesElement.removeStyleClass("filter-logs");
}

var targetFilterClass = "filter-" + target.category.toLowerCase();

if (target.category == "All") {
if (target.hasStyleClass("selected")) {

return;
}

unselectAll.call(this);
} else {

if (this.allElement.hasStyleClass("selected")) {
this.allElement.removeStyleClass("selected");
this.messagesElement.removeStyleClass("filter-all");
}
}

if (!selectMultiple) {


unselectAll.call(this);

target.addStyleClass("selected");
this.messagesElement.addStyleClass(targetFilterClass);

return;
}

if (target.hasStyleClass("selected")) {


target.removeStyleClass("selected");
this.messagesElement.removeStyleClass(targetFilterClass);
} else {


target.addStyleClass("selected");
this.messagesElement.addStyleClass(targetFilterClass);
}
},

_toggleConsoleButtonClicked: function()
{
this.drawer.visibleView = this;
},

attach: function(mainElement, statusBarElement)
{
mainElement.appendChild(this.element);
statusBarElement.appendChild(this.clearButton);
statusBarElement.appendChild(this.filterBarElement);
},

show: function()
{
this.toggleConsoleButton.addStyleClass("toggled-on");
this.toggleConsoleButton.title = WebInspector.UIString("Hide console.");
if (!this.prompt.isCaretInsidePrompt())
this.prompt.moveCaretToEndOfPrompt();
},

afterShow: function()
{
WebInspector.currentFocusElement = this.promptElement;  
},

hide: function()
{
this.toggleConsoleButton.removeStyleClass("toggled-on");
this.toggleConsoleButton.title = WebInspector.UIString("Show console.");
},

_scheduleScrollIntoView: function()
{
if (this._scrollIntoViewTimer)
return;

function scrollIntoView()
{
this.promptElement.scrollIntoView(false);
delete this._scrollIntoViewTimer;
}
this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20);
},

addMessage: function(msg)
{
if (msg instanceof WebInspector.ConsoleMessage && !(msg instanceof WebInspector.ConsoleCommandResult)) {
this._incrementErrorWarningCount(msg);
WebInspector.resourceManager.addConsoleMessage(msg);
this.commandSincePreviousMessage = false;
this.previousMessage = msg;
} else if (msg instanceof WebInspector.ConsoleCommand) {
if (this.previousMessage) {
this.commandSincePreviousMessage = true;
}
}

this.messages.push(msg);

if (msg.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
if (this.groupLevel < 1)
return;

this.groupLevel--;

this.currentGroup = this.currentGroup.parentGroup;
} else {
if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
this.groupLevel++;

var group = new WebInspector.ConsoleGroup(this.currentGroup, this.groupLevel);
this.currentGroup.messagesElement.appendChild(group.element);
this.currentGroup = group;
}

this.currentGroup.addMessage(msg);
}

this._scheduleScrollIntoView();
},

updateMessageRepeatCount: function(count)
{
var msg = this.previousMessage;
var prevRepeatCount = msg.totalRepeatCount;

if (!this.commandSincePreviousMessage) {
msg.repeatDelta = count - prevRepeatCount;
msg.repeatCount = msg.repeatCount + msg.repeatDelta;
msg.totalRepeatCount = count;
msg._updateRepeatCount();
this._incrementErrorWarningCount(msg);
} else {
var msgCopy = new WebInspector.ConsoleMessage(msg.source, msg.type, msg.level, msg.line, msg.url, msg.groupLevel, count - prevRepeatCount, msg._messageText, msg._parameters, msg._stackTrace);
msgCopy.totalRepeatCount = count;
msgCopy._formatMessage();
this.addMessage(msgCopy);
}
},

_incrementErrorWarningCount: function(msg)
{
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
WebInspector.warnings += msg.repeatDelta;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
WebInspector.errors += msg.repeatDelta;
break;
}
},

requestClearMessages: function()
{
InspectorBackend.clearConsoleMessages();
},

clearMessages: function()
{
WebInspector.resourceManager.clearConsoleMessages();

this.messages = [];

this.groupLevel = 0;
this.currentGroup = this.topGroup;
this.topGroup.messagesElement.removeChildren();

WebInspector.errors = 0;
WebInspector.warnings = 0;

delete this.commandSincePreviousMessage;
delete this.previousMessage;
},

completions: function(wordRange, bestMatchOnly, completionsReadyCallback)
{

var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, ExpressionStopCharacters, this.promptElement, "backward");
var expressionString = expressionRange.toString();
var lastIndex = expressionString.length - 1;

var dotNotation = (expressionString[lastIndex] === ".");
var bracketNotation = (expressionString[lastIndex] === "[");

if (dotNotation || bracketNotation)
expressionString = expressionString.substr(0, lastIndex);

var prefix = wordRange.toString();
if (!expressionString && !prefix)
return;

var reportCompletions = this._reportCompletions.bind(this, bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix);


var includeInspectorCommandLineAPI = (!dotNotation && !bracketNotation);
var callFrameId = WebInspector.panels.scripts.selectedCallFrameId();
var injectedScriptAccess;
if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) {
var selectedCallFrame = WebInspector.panels.scripts.sidebarPanes.callstack.selectedCallFrame;
injectedScriptAccess = InjectedScriptAccess.get(selectedCallFrame.worldId);
} else
injectedScriptAccess = InjectedScriptAccess.getDefault();
injectedScriptAccess.getCompletions(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions);
},

_reportCompletions: function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result, isException) {
if (isException)
return;

if (bracketNotation) {
if (prefix.length && prefix[0] === "'")
var quoteUsed = "'";
else
var quoteUsed = "\"";
}

var results = [];
var properties = Object.keys(result).sort();

for (var i = 0; i < properties.length; ++i) {
var property = properties[i];

if (dotNotation && !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(property))
continue;

if (bracketNotation) {
if (!/^[0-9]+$/.test(property))
property = quoteUsed + property.escapeCharacters(quoteUsed + "\\") + quoteUsed;
property += "]";
}

if (property.length < prefix.length)
continue;
if (property.indexOf(prefix) !== 0)
continue;

results.push(property);
if (bestMatchOnly)
break;
}
completionsReadyCallback(results);
},

_clearButtonClicked: function()
{
this.requestClearMessages();
},

_handleContextMenuEvent: function(event)
{
if (!window.getSelection().isCollapsed) {


return;
}

var contextMenu = new WebInspector.ContextMenu();

function monitoringXHRWasChanged(newState)
{
WebInspector.monitoringXHREnabled = newState;
}
var itemAction = InspectorBackend.setMonitoringXHREnabled.bind(InspectorBackend, !WebInspector.monitoringXHREnabled, monitoringXHRWasChanged);
contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), itemAction, WebInspector.monitoringXHREnabled);
contextMenu.appendItem(WebInspector.UIString("Clear Console"), this.requestClearMessages.bind(this));
contextMenu.show(event);
},

_messagesSelectStart: function(event)
{
if (this._selectionTimeout)
clearTimeout(this._selectionTimeout);

this.prompt.clearAutoComplete();

function moveBackIfOutside()
{
delete this._selectionTimeout;
if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
this.prompt.moveCaretToEndOfPrompt();
this.prompt.autoCompleteSoon();
}

this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
},

_messagesClicked: function(event)
{
var link = event.target.enclosingNodeOrSelfWithNodeName("a");
if (!link || !link.representedNode)
return;

WebInspector.updateFocusedNode(link.representedNode.id);
event.stopPropagation();
event.preventDefault();
},

_registerShortcuts: function()
{
this._shortcuts = {};

var shortcut = WebInspector.KeyboardShortcut;
var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta);

this._shortcuts[shortcutK.key] = this.requestClearMessages.bind(this);
this._shortcuts[shortcutK.key].isMacOnly = true;

var clearConsoleHandler = this.requestClearMessages.bind(this);
var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
this._shortcuts[shortcutL.key] = clearConsoleHandler;

var section = WebInspector.shortcutsHelp.section(WebInspector.UIString("Console"));
var keys = WebInspector.isMac() ? [ shortcutK.name, shortcutL.name ] : [ shortcutL.name ];
section.addAlternateKeys(keys, WebInspector.UIString("Clear Console"));

keys = [
shortcut.shortcutToString(shortcut.Keys.Tab),
shortcut.shortcutToString(shortcut.Keys.Tab, shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous suggestion"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion"));
keys = [
shortcut.shortcutToString(shortcut.Keys.Down),
shortcut.shortcutToString(shortcut.Keys.Up)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line"));
keys = [
shortcut.shortcutToString("N", shortcut.Modifiers.Alt),
shortcut.shortcutToString("P", shortcut.Modifiers.Alt)
];
if (WebInspector.isMac())
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Enter), WebInspector.UIString("Execute command"));
},

_promptKeyDown: function(event)
{
if (isEnterKey(event)) {
this._enterKeyPressed(event);
return;
}

var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcut];
if (handler) {
if (!this._shortcuts[shortcut].isMacOnly || WebInspector.isMac()) {
handler();
event.preventDefault();
return;
}
}
},

evalInInspectedWindow: function(expression, objectGroup, callback)
{
if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) {
WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, objectGroup, callback);
return;
}
this.doEvalInWindow(expression, objectGroup, callback);
},

doEvalInWindow: function(expression, objectGroup, callback)
{
if (!expression) {

expression = "this";
}

function evalCallback(result)
{
callback(WebInspector.RemoteObject.fromPayload(result));
};
InjectedScriptAccess.getDefault().evaluate(expression, objectGroup, evalCallback);
},

_enterKeyPressed: function(event)
{
if (event.altKey || event.ctrlKey || event.shiftKey)
return;

event.preventDefault();
event.stopPropagation();

this.prompt.clearAutoComplete(true);

var str = this.prompt.text;
if (!str.length)
return;

var commandMessage = new WebInspector.ConsoleCommand(str);
this.addMessage(commandMessage);

var self = this;
function printResult(result)
{
self.prompt.history.push(str);
self.prompt.historyOffset = 0;
self.prompt.text = "";

WebInspector.settings.consoleHistory = self.prompt.history.slice(-30);

self.addMessage(new WebInspector.ConsoleCommandResult(result, commandMessage));
}
this.evalInInspectedWindow(str, "console", printResult);
},

_format: function(output, forceObjectFormat)
{
var isProxy = (output != null && typeof output === "object");
var type = (forceObjectFormat ? "object" : WebInspector.RemoteObject.type(output));

var formatter = this._customFormatters[type];
if (!formatter || !isProxy) {
formatter = this._formatvalue;
output = output.description;
}

var span = document.createElement("span");
span.className = "console-formatted-" + type + " source-code";
formatter.call(this, output, span);
return span;
},

_formatvalue: function(val, elem)
{
elem.appendChild(document.createTextNode(val));
},

_formatobject: function(obj, elem)
{
elem.appendChild(new WebInspector.ObjectPropertiesSection(obj, obj.description, null, true).element);
},

_formatnode: function(object, elem)
{
function printNode(nodeId)
{
if (!nodeId)
return;
var treeOutline = new WebInspector.ElementsTreeOutline();
treeOutline.showInElementsPanelEnabled = true;
treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
treeOutline.element.addStyleClass("outline-disclosure");
if (!treeOutline.children[0].hasChildren)
treeOutline.element.addStyleClass("single-node");
elem.appendChild(treeOutline.element);
}

object.pushNodeToFrontend(printNode);
},

_formatarray: function(arr, elem)
{
arr.getOwnProperties(false, this._printArray.bind(this, elem));
},

_formatstring: function(output, elem)
{
var span = document.createElement("span");
span.className = "console-formatted-string source-code";
span.appendChild(WebInspector.linkifyStringAsFragment(output.description));


elem.removeStyleClass("console-formatted-string");
elem.appendChild(document.createTextNode("\""));
elem.appendChild(span);
elem.appendChild(document.createTextNode("\""));
},

_printArray: function(elem, properties)
{
if (!properties)
return;

var elements = [];
for (var i = 0; i < properties.length; ++i) {
var name = properties[i].name;
if (name == parseInt(name))
elements[name] = this._formatAsArrayEntry(properties[i].value);
}

elem.appendChild(document.createTextNode("["));
for (var i = 0; i < elements.length; ++i) {
var element = elements[i];
if (element)
elem.appendChild(element);
else
elem.appendChild(document.createTextNode("undefined"))
if (i < elements.length - 1)
elem.appendChild(document.createTextNode(", "));
}
elem.appendChild(document.createTextNode("]"));
},

_formatAsArrayEntry: function(output)
{

return this._format(output, WebInspector.RemoteObject.type(output) === "array");
}
}

WebInspector.ConsoleView.prototype.__proto__ = WebInspector.View.prototype;

WebInspector.ConsoleMessage = function(source, type, level, line, url, groupLevel, repeatCount, message, parameters, stackTrace)
{
this.source = source;
this.type = type;
this.level = level;
this.line = line;
this.url = url;
this.groupLevel = groupLevel;
this.repeatCount = repeatCount;
this.repeatDelta = repeatCount;
this.totalRepeatCount = repeatCount;
this._messageText = message;
this._parameters = parameters;
this._stackTrace = stackTrace;
this._formatMessage();
}

WebInspector.ConsoleMessage.createTextMessage = function(text, level)
{
level = level || WebInspector.ConsoleMessage.MessageLevel.Log;
return new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Log, level, 0, null, null, 1, null, [text], null);
}

WebInspector.ConsoleMessage.prototype = {
_formatMessage: function()
{
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Assert:
case WebInspector.ConsoleMessage.MessageType.Trace:
case WebInspector.ConsoleMessage.MessageType.UncaughtException:
var ol = document.createElement("ol");
ol.className = "outline-disclosure";
var treeOutline = new TreeOutline(ol);
var messageText;
if (this.type === WebInspector.ConsoleMessage.MessageType.Assert)
messageText = this._format(this._parameters);
else if (this.type === WebInspector.ConsoleMessage.MessageType.Trace)
messageText = document.createTextNode("console.trace()");
else
messageText = document.createTextNode(this._messageText);

var content = document.createElement("div");
this._addMessageHeader(content, messageText);
var root = new TreeElement(content, null, true);
content.treeElementForTest = root;
treeOutline.appendChild(root);
if (this.type === WebInspector.ConsoleMessage.MessageType.Trace)
root.expand();

this._populateStackTraceTreeElement(root);
this.formattedMessage = ol;
break;
case WebInspector.ConsoleMessage.MessageType.Object:
var obj = this._parameters ? this._parameters[0] : undefined;
this.formattedMessage = this._format(["%O", obj]);
break;
default:
var args = this._parameters || [this._messageText];
this.formattedMessage = this._format(args);
break;
}


this.message = this.formattedMessage.textContent;
},

isErrorOrWarning: function()
{
return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
},

_format: function(parameters)
{

var formattedResult = document.createElement("span");
if (!parameters.length)
return formattedResult;



for (var i = 0; i < parameters.length; ++i) {
if (typeof parameters[i] === "object")
parameters[i] = WebInspector.RemoteObject.fromPayload(parameters[i]);
else
parameters[i] = WebInspector.RemoteObject.fromPrimitiveValue(parameters[i]);
}


var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && this.type !== WebInspector.ConsoleMessage.MessageType.Result;


if (shouldFormatMessage) {

var result = this._formatWithSubstitutionString(parameters, formattedResult);
parameters = result.unusedSubstitutions;
if (parameters.length)
formattedResult.appendChild(document.createTextNode(" "));
}


for (var i = 0; i < parameters.length; ++i) {

if (shouldFormatMessage && parameters[i].type === "string")
formattedResult.appendChild(document.createTextNode(parameters[i].description));
else
formattedResult.appendChild(WebInspector.console._format(parameters[i]));
if (i < parameters.length - 1)
formattedResult.appendChild(document.createTextNode(" "));
}
return formattedResult;
},

_formatWithSubstitutionString: function(parameters, formattedResult)
{
var formatters = {}
for (var i in String.standardFormatters)
formatters[i] = String.standardFormatters[i];

function consoleFormatWrapper(force)
{
return function(obj) {
return WebInspector.console._format(obj, force);
};
}


formatters.o = consoleFormatWrapper();

formatters.i = formatters.d;

formatters.O = consoleFormatWrapper(true);

function append(a, b)
{
if (!(b instanceof Node))
a.appendChild(WebInspector.linkifyStringAsFragment(b.toString()));
else
a.appendChild(b);
return a;
}


return String.format(parameters[0].description, parameters.slice(1), formatters, formattedResult, append);
},

toMessageElement: function()
{
if (this._element)
return this._element;

var element = document.createElement("div");
element.message = this;
element.className = "console-message";

this._element = element;

switch (this.source) {
case WebInspector.ConsoleMessage.MessageSource.HTML:
element.addStyleClass("console-html-source");
break;
case WebInspector.ConsoleMessage.MessageSource.WML:
element.addStyleClass("console-wml-source");
break;
case WebInspector.ConsoleMessage.MessageSource.XML:
element.addStyleClass("console-xml-source");
break;
case WebInspector.ConsoleMessage.MessageSource.JS:
element.addStyleClass("console-js-source");
break;
case WebInspector.ConsoleMessage.MessageSource.CSS:
element.addStyleClass("console-css-source");
break;
case WebInspector.ConsoleMessage.MessageSource.Other:
element.addStyleClass("console-other-source");
break;
}

switch (this.level) {
case WebInspector.ConsoleMessage.MessageLevel.Tip:
element.addStyleClass("console-tip-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Log:
element.addStyleClass("console-log-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
element.addStyleClass("console-debug-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
element.addStyleClass("console-warning-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
element.addStyleClass("console-error-level");
break;
}

if (this.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
element.addStyleClass("console-group-title");

if (this.elementsTreeOutline) {
element.addStyleClass("outline-disclosure");
element.appendChild(this.elementsTreeOutline.element);
return element;
}

if (this.type === WebInspector.ConsoleMessage.MessageType.Trace ||
this.type === WebInspector.ConsoleMessage.MessageType.Assert ||
this.type === WebInspector.ConsoleMessage.MessageType.UncaughtException)
element.appendChild(this.formattedMessage);
else
this._addMessageHeader(element, this.formattedMessage);

if (this.repeatCount > 1)
this._updateRepeatCount();

return element;
},

_populateStackTraceTreeElement: function(parentTreeElement)
{
for (var i = 0; i < this._stackTrace.length; i++) {
var frame = this._stackTrace[i];

var content = document.createElement("div");
var messageTextElement = document.createElement("span");
messageTextElement.className = "console-message-text source-code";
var functionName = frame.functionName || WebInspector.UIString("(anonymous function)");
messageTextElement.appendChild(document.createTextNode(functionName));
content.appendChild(messageTextElement);

var urlElement = WebInspector.linkifyResourceAsNode(frame.sourceURL, "scripts", frame.lineNumber, "console-message-url"); 
content.appendChild(urlElement);

var treeElement = new TreeElement(content);
parentTreeElement.appendChild(treeElement);
}
},

_addMessageHeader: function(parentElement, formattedMessage)
{
if (this.url && this.url !== "undefined") {
var urlElement = WebInspector.linkifyResourceAsNode(this.url, "scripts", this.line, "console-message-url"); 
parentElement.appendChild(urlElement);
}

var messageTextElement = document.createElement("span");
messageTextElement.className = "console-message-text source-code";
if (this.type === WebInspector.ConsoleMessage.MessageType.Assert)
messageTextElement.appendChild(document.createTextNode(WebInspector.UIString("Assertion failed: ")));
messageTextElement.appendChild(formattedMessage);
parentElement.appendChild(messageTextElement);
},

_updateRepeatCount: function() {
if (!this.repeatCountElement) {
this.repeatCountElement = document.createElement("span");
this.repeatCountElement.className = "bubble";

this._element.insertBefore(this.repeatCountElement, this._element.firstChild);
this._element.addStyleClass("repeated-message");
}
this.repeatCountElement.textContent = this.repeatCount;
},

toString: function()
{
var sourceString;
switch (this.source) {
case WebInspector.ConsoleMessage.MessageSource.HTML:
sourceString = "HTML";
break;
case WebInspector.ConsoleMessage.MessageSource.WML:
sourceString = "WML";
break;
case WebInspector.ConsoleMessage.MessageSource.XML:
sourceString = "XML";
break;
case WebInspector.ConsoleMessage.MessageSource.JS:
sourceString = "JS";
break;
case WebInspector.ConsoleMessage.MessageSource.CSS:
sourceString = "CSS";
break;
case WebInspector.ConsoleMessage.MessageSource.Other:
sourceString = "Other";
break;
}

var typeString;
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Log:
case WebInspector.ConsoleMessage.MessageType.UncaughtException:
typeString = "Log";
break;
case WebInspector.ConsoleMessage.MessageType.Object:
typeString = "Object";
break;
case WebInspector.ConsoleMessage.MessageType.Trace:
typeString = "Trace";
break;
case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
case WebInspector.ConsoleMessage.MessageType.StartGroup:
typeString = "Start Group";
break;
case WebInspector.ConsoleMessage.MessageType.EndGroup:
typeString = "End Group";
break;
case WebInspector.ConsoleMessage.MessageType.Assert:
typeString = "Assert";
break;
case WebInspector.ConsoleMessage.MessageType.Result:
typeString = "Result";
break;
}

var levelString;
switch (this.level) {
case WebInspector.ConsoleMessage.MessageLevel.Tip:
levelString = "Tip";
break;
case WebInspector.ConsoleMessage.MessageLevel.Log:
levelString = "Log";
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
levelString = "Warning";
break;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
levelString = "Debug";
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
levelString = "Error";
break;
}

return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line;
},

isEqual: function(msg, disreguardGroup)
{
if (!msg)
return false;

var ret = (this.source == msg.source)
&& (this.type == msg.type)
&& (this.level == msg.level)
&& (this.line == msg.line)
&& (this.url == msg.url)
&& (this.message == msg.message);

return (disreguardGroup ? ret : (ret && (this.groupLevel == msg.groupLevel)));
}
}


WebInspector.ConsoleMessage.MessageSource = {
HTML: 0,
WML: 1,
XML: 2,
JS: 3,
CSS: 4,
Other: 5
}

WebInspector.ConsoleMessage.MessageType = {
Log: 0,
Object: 1,
Trace: 2,
StartGroup: 3,
StartGroupCollapsed: 4,
EndGroup: 5,
Assert: 6,
UncaughtException: 7,
Result: 8
}

WebInspector.ConsoleMessage.MessageLevel = {
Tip: 0,
Log: 1,
Warning: 2,
Error: 3,
Debug: 4
}

WebInspector.ConsoleCommand = function(command)
{
this.command = command;
}

WebInspector.ConsoleCommand.prototype = {
toMessageElement: function()
{
var element = document.createElement("div");
element.command = this;
element.className = "console-user-command";

var commandTextElement = document.createElement("span");
commandTextElement.className = "console-message-text source-code";
commandTextElement.textContent = this.command;
element.appendChild(commandTextElement);

return element;
}
}

WebInspector.ConsoleCommandResult = function(result, originatingCommand)
{
var level = (result.isError() ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
this.originatingCommand = originatingCommand;
WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Result, level, -1, null, null, 1, null, [result]);
}

WebInspector.ConsoleCommandResult.prototype = {
toMessageElement: function()
{
var element = WebInspector.ConsoleMessage.prototype.toMessageElement.call(this);
element.addStyleClass("console-user-command-result");
return element;
}
}

WebInspector.ConsoleCommandResult.prototype.__proto__ = WebInspector.ConsoleMessage.prototype;

WebInspector.ConsoleGroup = function(parentGroup, level)
{
this.parentGroup = parentGroup;
this.level = level;

var element = document.createElement("div");
element.className = "console-group";
element.group = this;
this.element = element;

var messagesElement = document.createElement("div");
messagesElement.className = "console-group-messages";
element.appendChild(messagesElement);
this.messagesElement = messagesElement;
}

WebInspector.ConsoleGroup.prototype = {
addMessage: function(msg)
{
var element = msg.toMessageElement();

if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
this.messagesElement.parentNode.insertBefore(element, this.messagesElement);
element.addEventListener("click", this._titleClicked.bind(this), false);
var groupElement = element.enclosingNodeOrSelfWithClass("console-group");
if (groupElement && msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
groupElement.addStyleClass("collapsed");
} else
this.messagesElement.appendChild(element);

if (element.previousSibling && msg.originatingCommand && element.previousSibling.command === msg.originatingCommand)
element.previousSibling.addStyleClass("console-adjacent-user-command-result");
},

_titleClicked: function(event)
{
var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title");
if (groupTitleElement) {
var groupElement = groupTitleElement.enclosingNodeOrSelfWithClass("console-group");
if (groupElement)
if (groupElement.hasStyleClass("collapsed"))
groupElement.removeStyleClass("collapsed");
else
groupElement.addStyleClass("collapsed");
groupTitleElement.scrollIntoViewIfNeeded(true);
}

event.stopPropagation();
event.preventDefault();
}
}






WebInspector.Panel = function(name)
{
WebInspector.View.call(this);

this.element.addStyleClass("panel");
this.element.addStyleClass(name);
this._panelName = name;

WebInspector.settings.installApplicationSetting(this._sidebarWidthSettingName(), undefined);
}


WebInspector.Panel.counterRightMargin = 25;

WebInspector.Panel.prototype = {
get toolbarItem()
{
if (this._toolbarItem)
return this._toolbarItem;







this._toolbarItem = document.createElement("button");
this._toolbarItem.className = "toolbar-item toggleable";
this._toolbarItem.panel = this;

this._toolbarItem.addStyleClass(this._panelName);

var iconElement = document.createElement("div");
iconElement.className = "toolbar-icon";
this._toolbarItem.appendChild(iconElement);

if ("toolbarItemLabel" in this) {
var labelElement = document.createElement("div");
labelElement.className = "toolbar-label";
labelElement.textContent = this.toolbarItemLabel;
this._toolbarItem.appendChild(labelElement);
}

return this._toolbarItem;
},

get name()
{
return this._panelName;
},

show: function()
{
WebInspector.View.prototype.show.call(this);

var statusBarItems = this.statusBarItems;
if (statusBarItems) {
this._statusBarItemContainer = document.createElement("div");
for (var i = 0; i < statusBarItems.length; ++i)
this._statusBarItemContainer.appendChild(statusBarItems[i]);
document.getElementById("main-status-bar").appendChild(this._statusBarItemContainer);
}

if ("_toolbarItem" in this)
this._toolbarItem.addStyleClass("toggled-on");

WebInspector.currentFocusElement = this.defaultFocusedElement;

this.restoreSidebarWidth();
this._restoreScrollPositions();
},

hide: function()
{
this._storeScrollPositions();
WebInspector.View.prototype.hide.call(this);

if (this._statusBarItemContainer && this._statusBarItemContainer.parentNode)
this._statusBarItemContainer.parentNode.removeChild(this._statusBarItemContainer);
delete this._statusBarItemContainer;
if ("_toolbarItem" in this)
this._toolbarItem.removeStyleClass("toggled-on");
},

get defaultFocusedElement()
{
return this.sidebarTreeElement || this.element;
},

attach: function()
{
if (!this.element.parentNode)
document.getElementById("main-panels").appendChild(this.element);
},

searchCanceled: function()
{
if (this._searchResults) {
for (var i = 0; i < this._searchResults.length; ++i) {
var view = this._searchResults[i];
if (view.searchCanceled)
view.searchCanceled();
delete view.currentQuery;
}
}

WebInspector.updateSearchMatchesCount(0, this);

if (this._currentSearchChunkIntervalIdentifier) {
clearInterval(this._currentSearchChunkIntervalIdentifier);
delete this._currentSearchChunkIntervalIdentifier;
}

this._totalSearchMatches = 0;
this._currentSearchResultIndex = 0;
this._searchResults = [];
},

performSearch: function(query)
{

this.searchCanceled(true);

var searchableViews = this.searchableViews;
if (!searchableViews || !searchableViews.length)
return;

var parentElement = this.viewsContainerElement;
var visibleView = this.visibleView;
var sortFuction = this.searchResultsSortFunction;

var matchesCountUpdateTimeout = null;

function updateMatchesCount()
{
WebInspector.updateSearchMatchesCount(this._totalSearchMatches, this);
matchesCountUpdateTimeout = null;
}

function updateMatchesCountSoon()
{
if (matchesCountUpdateTimeout)
return;

matchesCountUpdateTimeout = setTimeout(updateMatchesCount.bind(this), 500);
}

function finishedCallback(view, searchMatches)
{
if (!searchMatches)
return;

this._totalSearchMatches += searchMatches;
this._searchResults.push(view);

if (sortFuction)
this._searchResults.sort(sortFuction);

if (this.searchMatchFound)
this.searchMatchFound(view, searchMatches);

updateMatchesCountSoon.call(this);

if (view === visibleView)
view.jumpToFirstSearchResult();
}

var i = 0;
var panel = this;
var boundFinishedCallback = finishedCallback.bind(this);
var chunkIntervalIdentifier = null;




function processChunk()
{
var view = searchableViews[i];

if (++i >= searchableViews.length) {
if (panel._currentSearchChunkIntervalIdentifier === chunkIntervalIdentifier)
delete panel._currentSearchChunkIntervalIdentifier;
clearInterval(chunkIntervalIdentifier);
}

if (!view)
return;

if (view.element.parentNode !== parentElement && view.element.parentNode && parentElement)
view.detach();

view.currentQuery = query;
view.performSearch(query, boundFinishedCallback);
}

processChunk();

chunkIntervalIdentifier = setInterval(processChunk, 25);
this._currentSearchChunkIntervalIdentifier = chunkIntervalIdentifier;
},

jumpToNextSearchResult: function()
{
if (!this.showView || !this._searchResults || !this._searchResults.length)
return;

var showFirstResult = false;

this._currentSearchResultIndex = this._searchResults.indexOf(this.visibleView);
if (this._currentSearchResultIndex === -1) {
this._currentSearchResultIndex = 0;
showFirstResult = true;
}

var currentView = this._searchResults[this._currentSearchResultIndex];

if (currentView.showingLastSearchResult()) {
if (++this._currentSearchResultIndex >= this._searchResults.length)
this._currentSearchResultIndex = 0;
currentView = this._searchResults[this._currentSearchResultIndex];
showFirstResult = true;
}

if (currentView !== this.visibleView) {
this.showView(currentView);
WebInspector.focusSearchField();
}

if (showFirstResult)
currentView.jumpToFirstSearchResult();
else
currentView.jumpToNextSearchResult();
},

jumpToPreviousSearchResult: function()
{
if (!this.showView || !this._searchResults || !this._searchResults.length)
return;

var showLastResult = false;

this._currentSearchResultIndex = this._searchResults.indexOf(this.visibleView);
if (this._currentSearchResultIndex === -1) {
this._currentSearchResultIndex = 0;
showLastResult = true;
}

var currentView = this._searchResults[this._currentSearchResultIndex];

if (currentView.showingFirstSearchResult()) {
if (--this._currentSearchResultIndex < 0)
this._currentSearchResultIndex = (this._searchResults.length - 1);
currentView = this._searchResults[this._currentSearchResultIndex];
showLastResult = true;
}

if (currentView !== this.visibleView) {
this.showView(currentView);
WebInspector.focusSearchField();
}

if (showLastResult)
currentView.jumpToLastSearchResult();
else
currentView.jumpToPreviousSearchResult();
},

createSidebar: function(parentElement, resizerParentElement)
{
if (this.sidebarElement)
return;

if (!parentElement)
parentElement = this.element;

if (!resizerParentElement)
resizerParentElement = parentElement;

this.sidebarElement = document.createElement("div");
this.sidebarElement.className = "sidebar";
parentElement.appendChild(this.sidebarElement);

this.sidebarResizeElement = document.createElement("div");
this.sidebarResizeElement.className = "sidebar-resizer-vertical";
this.sidebarResizeElement.addEventListener("mousedown", this._startSidebarDragging.bind(this), false);
resizerParentElement.appendChild(this.sidebarResizeElement);

this.sidebarTreeElement = document.createElement("ol");
this.sidebarTreeElement.className = "sidebar-tree";
this.sidebarElement.appendChild(this.sidebarTreeElement);

this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
this.sidebarTree.panel = this;
},

_sidebarWidthSettingName: function()
{
return this._panelName + "SidebarWidth";
},

_startSidebarDragging: function(event)
{
WebInspector.elementDragStart(this.sidebarResizeElement, this._sidebarDragging.bind(this), this._endSidebarDragging.bind(this), event, "col-resize");
},

_sidebarDragging: function(event)
{
this.updateSidebarWidth(event.pageX);

event.preventDefault();
},

_endSidebarDragging: function(event)
{
WebInspector.elementDragEnd(event);
this.saveSidebarWidth();
},

updateSidebarWidth: function(width)
{
if (!this.sidebarElement)
return;

if (this.sidebarElement.offsetWidth <= 0) {


return;
}

if (!("_currentSidebarWidth" in this))
this._currentSidebarWidth = this.sidebarElement.offsetWidth;

if (typeof width === "undefined")
width = this._currentSidebarWidth;

width = Number.constrain(width, Preferences.minSidebarWidth, window.innerWidth / 2);

this._currentSidebarWidth = width;
this.setSidebarWidth(width);

this.updateMainViewWidth(width);
},

setSidebarWidth: function(width)
{
this.sidebarElement.style.width = width + "px";
this.sidebarResizeElement.style.left = (width - 3) + "px";
},

restoreSidebarWidth: function()
{
var sidebarWidth = WebInspector.settings[this._sidebarWidthSettingName()];
this.updateSidebarWidth(sidebarWidth);
},

saveSidebarWidth: function()
{
if (!this.sidebarElement)
return;
WebInspector.settings[this._sidebarWidthSettingName()] = this.sidebarElement.offsetWidth;
},

updateMainViewWidth: function(width)
{

},

resize: function()
{
var visibleView = this.visibleView;
if (visibleView && "resize" in visibleView)
visibleView.resize();
},

canShowSourceLine: function(url, line)
{
return false;
},

showSourceLine: function(url, line)
{
return false;
},

elementsToRestoreScrollPositionsFor: function()
{
return [];
},

_storeScrollPositions: function()
{
var elements = this.elementsToRestoreScrollPositionsFor();
for (var i = 0; i < elements.length; ++i) {
var container = elements[i];
container._scrollTop = container.scrollTop;
}
},

_restoreScrollPositions: function()
{
var elements = this.elementsToRestoreScrollPositionsFor();
for (var i = 0; i < elements.length; ++i) {
var container = elements[i];
if (container._scrollTop)
container.scrollTop = container._scrollTop;
}
}
}

WebInspector.Panel.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.TimelineGrid = function()
{
this.element = document.createElement("div");

this._itemsGraphsElement = document.createElement("div");
this._itemsGraphsElement.id = "resources-graphs";
this.element.appendChild(this._itemsGraphsElement);

this._dividersElement = document.createElement("div");
this._dividersElement.className = "resources-dividers";
this.element.appendChild(this._dividersElement);

this._eventDividersElement = document.createElement("div");
this._eventDividersElement.className = "resources-event-dividers";
this.element.appendChild(this._eventDividersElement);

this._dividersLabelBarElement = document.createElement("div");
this._dividersLabelBarElement.className = "resources-dividers-label-bar";
this.element.appendChild(this._dividersLabelBarElement);
}

WebInspector.TimelineGrid.prototype = {
get itemsGraphsElement()
{
return this._itemsGraphsElement;
},


updateDividers: function(force, calculator, paddingLeft)
{
var dividerCount = Math.round(this._dividersElement.offsetWidth / 64);
var slice = calculator.boundarySpan / dividerCount;
if (!force && this._currentDividerSlice === slice)
return false;

if (typeof paddingLeft !== "number")
paddingLeft = 0;
this._currentDividerSlice = slice;


var divider = this._dividersElement.firstChild;
var dividerLabelBar = this._dividersLabelBarElement.firstChild;

var dividersLabelBarElementClientWidth = this._dividersLabelBarElement.clientWidth;
var clientWidth = dividersLabelBarElementClientWidth - paddingLeft;
for (var i = paddingLeft ? 0 : 1; i <= dividerCount; ++i) {
if (!divider) {
divider = document.createElement("div");
divider.className = "resources-divider";
this._dividersElement.appendChild(divider);

dividerLabelBar = document.createElement("div");
dividerLabelBar.className = "resources-divider";
var label = document.createElement("div");
label.className = "resources-divider-label";
dividerLabelBar._labelElement = label;
dividerLabelBar.appendChild(label);
this._dividersLabelBarElement.appendChild(dividerLabelBar);
dividersLabelBarElementClientWidth = this._dividersLabelBarElement.clientWidth;
}

if (i === (paddingLeft ? 0 : 1)) {
divider.addStyleClass("first");
dividerLabelBar.addStyleClass("first");
} else {
divider.removeStyleClass("first");
dividerLabelBar.removeStyleClass("first");
}

if (i === dividerCount) {
divider.addStyleClass("last");
dividerLabelBar.addStyleClass("last");
} else {
divider.removeStyleClass("last");
dividerLabelBar.removeStyleClass("last");
}

var left = paddingLeft + clientWidth * (i / dividerCount);
var percentLeft = 100 * left / dividersLabelBarElementClientWidth;
this._setDividerAndBarLeft(divider, dividerLabelBar, percentLeft);

if (!isNaN(slice))
dividerLabelBar._labelElement.textContent = calculator.formatValue(slice * i);
else
dividerLabelBar._labelElement.textContent = "";

divider = divider.nextSibling;
dividerLabelBar = dividerLabelBar.nextSibling;
}


while (divider) {
var nextDivider = divider.nextSibling;
this._dividersElement.removeChild(divider);
divider = nextDivider;
}
while (dividerLabelBar) {
var nextDivider = dividerLabelBar.nextSibling;
this._dividersLabelBarElement.removeChild(dividerLabelBar);
dividerLabelBar = nextDivider;
}
return true;
},

_setDividerAndBarLeft: function(divider, dividerLabelBar, percentLeft)
{
var percentStyleLeft = parseFloat(divider.style.left);
if (!isNaN(percentStyleLeft) && Math.abs(percentStyleLeft - percentLeft) < 0.1)
return;
divider.style.left = percentLeft + "%";
dividerLabelBar.style.left = percentLeft + "%";
},

addEventDivider: function(divider)
{
this._eventDividersElement.appendChild(divider);
},

addEventDividers: function(dividers)
{
this.element.removeChild(this._eventDividersElement);
for (var i = 0; i < dividers.length; ++i)
if (dividers[i])
this._eventDividersElement.appendChild(dividers[i]);
this.element.appendChild(this._eventDividersElement);
},

removeEventDividers: function()
{
this._eventDividersElement.removeChildren();
},

hideEventDividers: function()
{
this._eventDividersElement.addStyleClass("hidden");
},

showEventDividers: function()
{
this._eventDividersElement.removeStyleClass("hidden");
},

setScrollAndDividerTop: function(scrollTop, dividersTop)
{
this._dividersElement.style.top = scrollTop + "px";
this._eventDividersElement.style.top = scrollTop + "px";
this._dividersLabelBarElement.style.top = dividersTop + "px";
}
}




WebInspector.Resource = function(identifier, url)
{
this.identifier = identifier;
this.url = url;
this._startTime = -1;
this._endTime = -1;
this._requestMethod = "";
this._category = WebInspector.resourceCategories.other;
this._pendingContentCallbacks = [];
}


WebInspector.Resource.Type = {
Document:   0,
Stylesheet: 1,
Image:      2,
Font:       3,
Script:     4,
XHR:        5,
Media:      6,
WebSocket:  7,
Other:      8,

isTextType: function(type)
{
return (type === this.Document) || (type === this.Stylesheet) || (type === this.Script) || (type === this.XHR);
},

toUIString: function(type)
{
return WebInspector.UIString(WebInspector.Resource.Type.toString(type));
},



toString: function(type)
{
switch (type) {
case this.Document:
return "document";
case this.Stylesheet:
return "stylesheet";
case this.Image:
return "image";
case this.Font:
return "font";
case this.Script:
return "script";
case this.XHR:
return "xhr";
case this.Media:
return "media";
case this.WebSocket:
return "websocket";
case this.Other:
default:
return "other";
}
}
}

WebInspector.Resource.prototype = {
get url()
{
return this._url;
},

set url(x)
{
if (this._url === x)
return;

this._url = x;
delete this._parsedQueryParameters;

var parsedURL = x.asParsedURL();
this.domain = parsedURL ? parsedURL.host : "";
this.path = parsedURL ? parsedURL.path : "";
this.lastPathComponent = "";
if (parsedURL && parsedURL.path) {

var path = parsedURL.path;
var indexOfQuery = path.indexOf("?");
if (indexOfQuery !== -1)
path = path.substring(0, indexOfQuery);


var lastSlashIndex = path.lastIndexOf("/");
if (lastSlashIndex !== -1)
this.lastPathComponent = path.substring(lastSlashIndex + 1);
}
this.lastPathComponentLowerCase = this.lastPathComponent.toLowerCase();
},

get documentURL()
{
return this._documentURL;
},

set documentURL(x)
{
this._documentURL = x;
},

get displayName()
{
if (this._displayName)
return this._displayName;
this._displayName = this.lastPathComponent;
if (!this._displayName)
this._displayName = this.displayDomain;
if (!this._displayName && this.url)
this._displayName = this.url.trimURL(WebInspector.mainResource ? WebInspector.mainResource.domain : "");
if (this._displayName === "/")
this._displayName = this.url;
return this._displayName;
},

get displayDomain()
{

if (this.domain && (!WebInspector.mainResource || (WebInspector.mainResource && this.domain !== WebInspector.mainResource.domain)))
return this.domain;
return "";
},

get startTime()
{
return this._startTime || -1;
},

set startTime(x)
{
this._startTime = x;
},

get responseReceivedTime()
{
return this._responseReceivedTime || -1;
},

set responseReceivedTime(x)
{
this._responseReceivedTime = x;
},

get endTime()
{
return this._endTime || -1;
},

set endTime(x)
{
if (this.timing && this.timing.requestTime) {

this._endTime = Math.max(x, this.responseReceivedTime);
} else {

this._endTime = x;
if (this._responseReceivedTime > x)
this._responseReceivedTime = x;
}
},

get duration()
{
if (this._endTime === -1 || this._startTime === -1)
return -1;
return this._endTime - this._startTime;
},

get latency()
{
if (this._responseReceivedTime === -1 || this._startTime === -1)
return -1;
return this._responseReceivedTime - this._startTime;
},

get receiveDuration()
{
if (this._endTime === -1 || this._responseReceivedTime === -1)
return -1;
return this._endTime - this._responseReceivedTime;
},

get resourceSize()
{
return this._resourceSize || 0;
},

set resourceSize(x)
{
this._resourceSize = x;
},

get transferSize()
{

return this.cached ? 0 : Number(this.responseHeaders["Content-Length"] || this.resourceSize || 0);
},

get expectedContentLength()
{
return this._expectedContentLength || 0;
},

set expectedContentLength(x)
{
this._expectedContentLength = x;
},

get finished()
{
return this._finished;
},

set finished(x)
{
if (this._finished === x)
return;

this._finished = x;

if (x) {
this._checkWarnings();
this.dispatchEventToListeners("finished");
if (this._pendingContentCallbacks.length)
this._innerRequestContent();
}
},

get failed()
{
return this._failed;
},

set failed(x)
{
this._failed = x;
},

get category()
{
return this._category;
},

set category(x)
{
this._category = x;
},

get cached()
{
return this._cached;
},

set cached(x)
{
this._cached = x;
if (x)
delete this._timing;
},


get timing()
{
return this._timing;
},

set timing(x)
{
if (x && !this._cached) {


this._startTime = x.requestTime;
this._responseReceivedTime = x.requestTime + x.receiveHeadersEnd / 1000.0;

this._timing = x;
this.dispatchEventToListeners("timing changed");
}
},

get mimeType()
{
return this._mimeType;
},

set mimeType(x)
{
this._mimeType = x;
},

get type()
{
return this._type;
},

set type(x)
{
if (this._type === x)
return;

this._type = x;

switch (x) {
case WebInspector.Resource.Type.Document:
this.category = WebInspector.resourceCategories.documents;
break;
case WebInspector.Resource.Type.Stylesheet:
this.category = WebInspector.resourceCategories.stylesheets;
break;
case WebInspector.Resource.Type.Script:
this.category = WebInspector.resourceCategories.scripts;
break;
case WebInspector.Resource.Type.Image:
this.category = WebInspector.resourceCategories.images;
break;
case WebInspector.Resource.Type.Font:
this.category = WebInspector.resourceCategories.fonts;
break;
case WebInspector.Resource.Type.XHR:
this.category = WebInspector.resourceCategories.xhr;
break;
case WebInspector.Resource.Type.WebSocket:
this.category = WebInspector.resourceCategories.websockets;
break;
case WebInspector.Resource.Type.Other:
default:
this.category = WebInspector.resourceCategories.other;
break;
}
},

get requestHeaders()
{
return this._requestHeaders || {};
},

set requestHeaders(x)
{
this._requestHeaders = x;
delete this._sortedRequestHeaders;
delete this._requestCookies;

this.dispatchEventToListeners("requestHeaders changed");
},

get sortedRequestHeaders()
{
if (this._sortedRequestHeaders !== undefined)
return this._sortedRequestHeaders;

this._sortedRequestHeaders = [];
for (var key in this.requestHeaders)
this._sortedRequestHeaders.push({header: key, value: this.requestHeaders[key]});
this._sortedRequestHeaders.sort(function(a,b) { return a.header.localeCompare(b.header) });

return this._sortedRequestHeaders;
},

requestHeaderValue: function(headerName)
{
return this._headerValue(this.requestHeaders, headerName);
},

get requestCookies()
{
if (!this._requestCookies)
this._requestCookies = WebInspector.CookieParser.parseCookie(this.requestHeaderValue("Cookie"));
return this._requestCookies;
},

get requestFormData()
{
return this._requestFormData;
},

set requestFormData(x)
{
this._requestFormData = x;
delete this._parsedFormParameters;
},

get responseHeaders()
{
return this._responseHeaders || {};
},

set responseHeaders(x)
{
this._responseHeaders = x;
delete this._sortedResponseHeaders;
delete this._responseCookies;

this.dispatchEventToListeners("responseHeaders changed");
},

get sortedResponseHeaders()
{
if (this._sortedResponseHeaders !== undefined)
return this._sortedResponseHeaders;

this._sortedResponseHeaders = [];
for (var key in this.responseHeaders)
this._sortedResponseHeaders.push({header: key, value: this.responseHeaders[key]});
this._sortedResponseHeaders.sort(function(a,b) { return a.header.localeCompare(b.header) });

return this._sortedResponseHeaders;
},

responseHeaderValue: function(headerName)
{
return this._headerValue(this.responseHeaders, headerName);
},

get responseCookies()
{
if (!this._responseCookies)
this._responseCookies = WebInspector.CookieParser.parseSetCookie(this.responseHeaderValue("Set-Cookie"));
return this._responseCookies;
},

get queryParameters()
{
if (this._parsedQueryParameters)
return this._parsedQueryParameters;
var queryString = this.url.split("?", 2)[1];
if (!queryString)
return;
this._parsedQueryParameters = this._parseParameters(queryString);
return this._parsedQueryParameters;
},

get formParameters()
{
if (this._parsedFormParameters)
return this._parsedFormParameters;
if (!this.requestFormData)
return;
var requestContentType = this.requestHeaderValue("Content-Type");
if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
return;
this._parsedFormParameters = this._parseParameters(this.requestFormData);
return this._parsedFormParameters;
},

_parseParameters: function(queryString)
{
function parseNameValue(pair)
{
var parameter = {};
var splitPair = pair.split("=", 2);

parameter.name = splitPair[0];
if (splitPair.length === 1)
parameter.value = "";
else
parameter.value = splitPair[1];
return parameter;
}
return queryString.split("&").map(parseNameValue);
},

_headerValue: function(headers, headerName)
{
headerName = headerName.toLowerCase();
for (var header in headers) {
if (header.toLowerCase() === headerName)
return headers[header];
}
},

get scripts()
{
if (!("_scripts" in this))
this._scripts = [];
return this._scripts;
},

addScript: function(script)
{
if (!script)
return;
this.scripts.unshift(script);
script.resource = this;
},

removeAllScripts: function()
{
if (!this._scripts)
return;

for (var i = 0; i < this._scripts.length; ++i) {
if (this._scripts[i].resource === this)
delete this._scripts[i].resource;
}

delete this._scripts;
},

removeScript: function(script)
{
if (!script)
return;

if (script.resource === this)
delete script.resource;

if (!this._scripts)
return;

this._scripts.remove(script);
},

get errors()
{
return this._errors || 0;
},

set errors(x)
{
this._errors = x;
this.dispatchEventToListeners("errors-warnings-updated");
},

get warnings()
{
return this._warnings || 0;
},

set warnings(x)
{
this._warnings = x;
this.dispatchEventToListeners("errors-warnings-updated");
},

clearErrorsAndWarnings: function()
{
this._warnings = 0;
this._errors = 0;
this.dispatchEventToListeners("errors-warnings-updated");
},

_mimeTypeIsConsistentWithType: function()
{



if (this.statusCode >= 400)
return true;

if (typeof this.type === "undefined"
|| this.type === WebInspector.Resource.Type.Other
|| this.type === WebInspector.Resource.Type.XHR
|| this.type === WebInspector.Resource.Type.WebSocket)
return true;

if (!this.mimeType)
return true; 

if (this.mimeType in WebInspector.MIMETypes)
return this.type in WebInspector.MIMETypes[this.mimeType];

return false;
},

_checkWarnings: function()
{
for (var warning in WebInspector.Warnings)
this._checkWarning(WebInspector.Warnings[warning]);
},

_checkWarning: function(warning)
{
var msg;
switch (warning.id) {
case WebInspector.Warnings.IncorrectMIMEType.id:
if (!this._mimeTypeIsConsistentWithType())
msg = new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.Other,
WebInspector.ConsoleMessage.MessageType.Log,
WebInspector.ConsoleMessage.MessageLevel.Warning,
-1,
this.url,
null,
1,
String.sprintf(WebInspector.Warnings.IncorrectMIMEType.message, WebInspector.Resource.Type.toUIString(this.type), this.mimeType),
null,
null);
break;
}

if (msg)
WebInspector.console.addMessage(msg);
},

get content()
{
return this._content;
},

get contentTimestamp()
{
return this._contentTimestamp;
},

setInitialContent: function(content)
{
this._content = content;
},

isLocallyModified: function()
{
return !!this._baseRevision;
},

setContent: function(newContent, onRevert)
{
var revisionResource = new WebInspector.Resource(null, this.url);
revisionResource.type = this.type;
revisionResource.loader = this.loader;
revisionResource.timestamp = this.timestamp;
revisionResource._content = this._content;
revisionResource._actualResource = this;
revisionResource._fireOnRevert = onRevert;

if (this.finished)
revisionResource.finished = true;
else {
function finished()
{
this.removeEventListener("finished", finished);
revisionResource.finished = true;
}
this.addEventListener("finished", finished.bind(this));
}

if (!this._baseRevision)
this._baseRevision = revisionResource;
else
revisionResource._baseRevision = this._baseRevision;

var data = { revision: revisionResource };
this._content = newContent;
this.timestamp = new Date();
this.dispatchEventToListeners("content-changed", data);
},

revertToThis: function()
{
if (!this._actualResource || !this._fireOnRevert)
return;

function callback(content)
{
if (content)
this._fireOnRevert(content);
}
this.requestContent(callback.bind(this));
},

get baseRevision()
{
return this._baseRevision;
},

requestContent: function(callback)
{
if (this._content) {
callback(this._content, this._contentEncoded);
return;
}
this._pendingContentCallbacks.push(callback);
if (this.finished)
this._innerRequestContent();
},

get contentURL()
{
const maxDataUrlSize = 1024 * 1024;

if (!this._content || this._content.length > maxDataUrlSize)
return this.url;

return "data:" + this.mimeType + (this._contentEncoded ? ";base64," : ",") + this._content;
},

_innerRequestContent: function()
{
if (this._contentRequested)
return;
this._contentRequested = true;
this._contentEncoded = !WebInspector.Resource.Type.isTextType(this.type);

function onResourceContent(data)
{
this._content = data;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._content, this._contentEncoded);
this._pendingContentCallbacks.length = 0;
delete this._contentRequested;
}
WebInspector.ResourceManager.requestContent(this, this._contentEncoded, onResourceContent.bind(this));
}
}

WebInspector.Resource.prototype.__proto__ = WebInspector.Object.prototype;





WebInspector.ResourceManager = function()
{
this._registerNotifyHandlers(
"identifierForInitialRequest",
"willSendRequest",
"markResourceAsCached",
"didReceiveResponse",
"didReceiveContentLength",
"didFinishLoading",
"didFailLoading",
"didLoadResourceFromMemoryCache",
"setInitialContent",
"didCommitLoadForFrame",
"frameDetachedFromParent",
"didCreateWebSocket",
"willSendWebSocketHandshakeRequest",
"didReceiveWebSocketHandshakeResponse",
"didCloseWebSocket");

this._resourcesById = {};
this._resourcesByURL = {};
this._resourceTreeModel = new WebInspector.ResourceTreeModel();
InspectorBackend.cachedResources(this._processCachedResources.bind(this));
}

WebInspector.ResourceManager.prototype = {
_registerNotifyHandlers: function()
{
for (var i = 0; i < arguments.length; ++i)
WebInspector[arguments[i]] = this[arguments[i]].bind(this);
},

identifierForInitialRequest: function(identifier, url, loader)
{
var resource = this._createResource(identifier, url, loader);


this._bindResourceURL(resource);

WebInspector.panels.network.refreshResource(resource);
WebInspector.panels.audits.resourceStarted(resource);
},

_createResource: function(identifier, url, loader)
{
var resource = new WebInspector.Resource(identifier, url);
resource.loader = loader;
if (loader)
resource.documentURL = loader.url;

this._resourcesById[identifier] = resource;
return resource;
},

willSendRequest: function(identifier, time, request, redirectResponse)
{
var resource = this._resourcesById[identifier];
if (!resource)
return;



var isRedirect = !redirectResponse.isNull && request.url.length;
if (isRedirect) {
resource.endTime = time;
this.didReceiveResponse(identifier, time, "Other", redirectResponse);
resource = this._appendRedirect(resource.identifier, request.url);
}

this._updateResourceWithRequest(resource, request);
resource.startTime = time;

if (isRedirect) {
WebInspector.panels.network.refreshResource(resource);
WebInspector.panels.audits.resourceStarted(resource);
} else 
WebInspector.panels.network.refreshResource(resource);
},

_updateResourceWithRequest: function(resource, request)
{
resource.requestMethod = request.httpMethod;
resource.requestHeaders = request.httpHeaderFields;
resource.requestFormData = request.requestFormData;
},

_appendRedirect: function(identifier, redirectURL)
{
var originalResource = this._resourcesById[identifier];
originalResource.identifier = null;

var newResource = this._createResource(identifier, redirectURL, originalResource.loader);
newResource.redirects = originalResource.redirects || [];
delete originalResource.redirects;
newResource.redirects.push(originalResource);
return newResource;
},

markResourceAsCached: function(identifier)
{
var resource = this._resourcesById[identifier];
if (!resource)
return;

resource.cached = true;
WebInspector.panels.network.refreshResource(resource);
},

didReceiveResponse: function(identifier, time, resourceType, response)
{
var resource = this._resourcesById[identifier];
if (!resource)
return;

resource.responseReceivedTime = time;
resource.type = WebInspector.Resource.Type[resourceType];

this._updateResourceWithResponse(resource, response);

WebInspector.panels.network.refreshResource(resource);
this._resourceTreeModel.addResourceToFrame(resource.loader.frameId, resource);
},

_updateResourceWithResponse: function(resource, response)
{
if (resource.isNull)
return;

resource.mimeType = response.mimeType;
resource.expectedContentLength = response.expectedContentLength;
resource.textEncodingName = response.textEncodingName;
resource.suggestedFilename = response.suggestedFilename;
resource.statusCode = response.httpStatusCode;
resource.statusText = response.httpStatusText;

resource.responseHeaders = response.httpHeaderFields;
resource.connectionReused = response.connectionReused;
resource.connectionID = response.connectionID;

if (response.wasCached)
resource.cached = true;
else
resource.timing = response.timing;

if (response.loadInfo) {
if (response.loadInfo.httpStatusCode)
resource.statusCode = response.loadInfo.httpStatusCode;
if (response.loadInfo.httpStatusText)
resource.statusText = response.loadInfo.httpStatusText;
resource.requestHeaders = response.loadInfo.requestHeaders;
resource.responseHeaders = response.loadInfo.responseHeaders;
}
},

didReceiveContentLength: function(identifier, time, lengthReceived)
{
var resource = this._resourcesById[identifier];
if (!resource)
return;

resource.resourceSize += lengthReceived;
resource.endTime = time;

WebInspector.panels.network.refreshResource(resource);
},

didFinishLoading: function(identifier, finishTime)
{
var resource = this._resourcesById[identifier];
if (!resource)
return;

resource.endTime = finishTime;
resource.finished = true;

WebInspector.panels.network.refreshResource(resource);
WebInspector.panels.audits.resourceFinished(resource);
WebInspector.extensionServer.notifyResourceFinished(resource);
delete this._resourcesById[identifier];
},

didFailLoading: function(identifier, time, localizedDescription)
{
var resource = this._resourcesById[identifier];
if (!resource)
return;

resource.failed = true;
resource.localizedFailDescription = localizedDescription;
resource.finished = true;
resource.endTime = time;

WebInspector.panels.network.refreshResource(resource);
WebInspector.panels.audits.resourceFinished(resource);
WebInspector.extensionServer.notifyResourceFinished(resource);
delete this._resourcesById[identifier];
},

didLoadResourceFromMemoryCache: function(time, cachedResource)
{
var resource = this._createResource(null, cachedResource.url, cachedResource.loader);
this._updateResourceWithCachedResource(resource, cachedResource);
resource.cached = true;
resource.requestMethod = "GET";
resource.startTime = resource.responseReceivedTime = resource.endTime = time;
resource.finished = true;

WebInspector.panels.network.refreshResource(resource);
WebInspector.panels.audits.resourceStarted(resource);
WebInspector.panels.audits.resourceFinished(resource);
this._resourceTreeModel.addResourceToFrame(resource.loader.frameId, resource);
},

_updateResourceWithCachedResource: function(resource, cachedResource)
{
resource.type = WebInspector.Resource.Type[cachedResource.type];
resource.resourceSize = cachedResource.encodedSize;
this._updateResourceWithResponse(resource, cachedResource.response);
},

setInitialContent: function(identifier, sourceString, type)
{
var resource = WebInspector.panels.network.resources[identifier];
if (!resource)
return;

resource.type = WebInspector.Resource.Type[type];
resource.setInitialContent(sourceString);
WebInspector.panels.resources.refreshResource(resource);
WebInspector.panels.network.refreshResource(resource);
},

didCommitLoadForFrame: function(frame, loader)
{
this._resourceTreeModel.didCommitLoadForFrame(frame, loader);
if (!frame.parentId) {
var mainResource = this.resourceForURL(frame.url);
if (mainResource) {
WebInspector.mainResource = mainResource;
mainResource.isMainResource = true;
WebInspector.panels.network.refreshResource(mainResource); 
}
}
},

frameDetachedFromParent: function(frameId)
{
this._resourceTreeModel.frameDetachedFromParent(frameId);
},

didCreateWebSocket: function(identifier, requestURL)
{
var resource = this._createResource(identifier, requestURL);
resource.type = WebInspector.Resource.Type.WebSocket;
WebInspector.panels.network.refreshResource(resource);
},

willSendWebSocketHandshakeRequest: function(identifier, time, request)
{
var resource = this._resourcesById[identifier];
if (!resource)
return;

resource.requestMethod = "GET";
resource.requestHeaders = request.webSocketHeaderFields;
resource.webSocketRequestKey3 = request.webSocketRequestKey3;
resource.startTime = time;

WebInspector.panels.network.refreshResource(resource);
},

didReceiveWebSocketHandshakeResponse: function(identifier, time, response)
{
var resource = this._resourcesById[identifier];
if (!resource)
return;

resource.statusCode = response.statusCode;
resource.statusText = response.statusText;
resource.responseHeaders = response.webSocketHeaderFields;
resource.webSocketChallengeResponse = response.webSocketChallengeResponse;
resource.responseReceivedTime = time;

WebInspector.panels.network.refreshResource(resource);
},

didCloseWebSocket: function(identifier, time)
{
var resource = this._resourcesById[identifier];
if (!resource)
return;
resource.endTime = time;

WebInspector.panels.network.refreshResource(resource);
},

_processCachedResources: function(mainFramePayload)
{
var mainResource = this._addFramesRecursively(mainFramePayload);
WebInspector.mainResource = mainResource;
mainResource.isMainResource = true;
},

_addFramesRecursively: function(framePayload)
{
var frameResource = this._createResource(null, framePayload.resource.url, framePayload.resource.loader);
this._updateResourceWithRequest(frameResource, framePayload.resource.request);
this._updateResourceWithResponse(frameResource, framePayload.resource.response);
frameResource.type = WebInspector.Resource.Type["Document"];
frameResource.finished = true;
this._bindResourceURL(frameResource);

this._resourceTreeModel.addOrUpdateFrame(framePayload);
this._resourceTreeModel.addResourceToFrame(framePayload.id, frameResource);

for (var i = 0; framePayload.children && i < framePayload.children.length; ++i)
this._addFramesRecursively(framePayload.children[i]);

if (!framePayload.subresources)
return;

for (var i = 0; i < framePayload.subresources.length; ++i) {
var cachedResource = framePayload.subresources[i];
var resource = this._createResource(null, cachedResource.url, cachedResource.loader);
this._updateResourceWithCachedResource(resource, cachedResource);
resource.finished = true;
this._bindResourceURL(resource);
this._resourceTreeModel.addResourceToFrame(framePayload.id, resource);
}
return frameResource;
},

resourceForURL: function(url)
{

var entry = this._resourcesByURL[url];
if (entry instanceof Array)
return entry[0];
return entry;
},

addConsoleMessage: function(msg)
{
var resource = this.resourceForURL(msg.url);
if (!resource)
return;

switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
resource.warnings += msg.repeatDelta;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
resource.errors += msg.repeatDelta;
break;
}

var view = WebInspector.ResourceManager.resourceViewForResource(resource);
if (view.addMessage)
view.addMessage(msg);
},

clearConsoleMessages: function()
{
function callback(resource)
{
resource.clearErrorsAndWarnings();
}
this._resourceTreeModel.forAllResources(callback);
},

forAllResources: function(callback)
{
this._resourceTreeModel.forAllResources(callback);
},

_bindResourceURL: function(resource)
{
var resourceForURL = this._resourcesByURL[resource.url];
if (!resourceForURL)
this._resourcesByURL[resource.url] = resource;
else if (resourceForURL instanceof Array)
resourceForURL.push(resource);
else
this._resourcesByURL[resource.url] = [resourceForURL, resource];
},

_unbindResourceURL: function(resource)
{
var resourceForURL = this._resourcesByURL[resource.url];
if (!resourceForURL)
return;

if (resourceForURL instanceof Array) {
resourceForURL.remove(resource, true);
if (resourceForURL.length === 1)
this._resourcesByURL[resource.url] = resourceForURL[0];
return;
}

delete this._resourcesByURL[resource.url];
}
}

WebInspector.ResourceManager.createResourceView = function(resource)
{
switch (resource.category) {
case WebInspector.resourceCategories.documents:
case WebInspector.resourceCategories.stylesheets:
case WebInspector.resourceCategories.scripts:
case WebInspector.resourceCategories.xhr:
return new WebInspector.SourceView(resource);
case WebInspector.resourceCategories.images:
return new WebInspector.ImageView(resource);
case WebInspector.resourceCategories.fonts:
return new WebInspector.FontView(resource);
default:
return new WebInspector.ResourceView(resource);
}
}

WebInspector.ResourceManager.resourceViewTypeMatchesResource = function(resource)
{
var resourceView = resource._resourcesView;
switch (resource.category) {
case WebInspector.resourceCategories.documents:
case WebInspector.resourceCategories.stylesheets:
case WebInspector.resourceCategories.scripts:
case WebInspector.resourceCategories.xhr:
return resourceView.__proto__ === WebInspector.SourceView.prototype;
case WebInspector.resourceCategories.images:
return resourceView.__proto__ === WebInspector.ImageView.prototype;
case WebInspector.resourceCategories.fonts:
return resourceView.__proto__ === WebInspector.FontView.prototype;
default:
return resourceView.__proto__ === WebInspector.ResourceView.prototype;
}
}

WebInspector.ResourceManager.resourceViewForResource = function(resource)
{
if (!resource)
return null;
if (!resource._resourcesView)
resource._resourcesView = WebInspector.ResourceManager.createResourceView(resource);
return resource._resourcesView;
}

WebInspector.ResourceManager.recreateResourceView = function(resource)
{
var newView = WebInspector.ResourceManager.createResourceView(resource);

var oldView = resource._resourcesView;
var oldViewParentNode = oldView.visible ? oldView.element.parentNode : null;
var scrollTop = oldView.scrollTop;

resource._resourcesView.detach();
delete resource._resourcesView;

resource._resourcesView = newView;

if (oldViewParentNode)
newView.show(oldViewParentNode);
if (scrollTop)
newView.scrollTop = scrollTop;

WebInspector.panels.scripts.viewRecreated(oldView, newView);
return newView;
}

WebInspector.ResourceManager.existingResourceViewForResource = function(resource)
{
if (!resource)
return null;
return resource._resourcesView;
}

WebInspector.ResourceManager.requestContent = function(resource, base64Encode, callback)
{
InspectorBackend.resourceContent(resource.loader.frameId, resource.url, base64Encode, callback);
}

WebInspector.ResourceTreeModel = function()
{
this._resourcesByFrameId = {};
this._subframes = {};
}

WebInspector.ResourceTreeModel.prototype = {
addOrUpdateFrame: function(frame)
{
var tmpResource = new WebInspector.Resource(null, frame.url);
WebInspector.panels.resources.addOrUpdateFrame(frame.parentId, frame.id, frame.name, tmpResource.displayName);
var subframes = this._subframes[frame.parentId];
if (!subframes) {
subframes = {};
this._subframes[frame.parentId || 0] = subframes;
}
subframes[frame.id] = true;
},

didCommitLoadForFrame: function(frame, loader)
{

this._clearChildFramesAndResources(frame.parentId ? frame.id : 0, loader.loaderId);

this.addOrUpdateFrame(frame);

var resourcesForFrame = this._resourcesByFrameId[frame.id];
for (var i = 0; resourcesForFrame && i < resourcesForFrame.length; ++i)
WebInspector.panels.resources.addResourceToFrame(frame.id, resourcesForFrame[i]);
},

frameDetachedFromParent: function(frameId)
{
this._clearChildFramesAndResources(frameId, 0);
WebInspector.panels.resources.removeFrame(frameId);
},

_clearChildFramesAndResources: function(frameId, loaderId)
{
WebInspector.panels.resources.removeResourcesFromFrame(frameId);

this._clearResources(frameId, loaderId);
var subframes = this._subframes[frameId];
if (!subframes)
return;

for (var childFrameId in subframes) {
WebInspector.panels.resources.removeFrame(childFrameId);
this._clearChildFramesAndResources(childFrameId, loaderId);
}
delete this._subframes[frameId];
},

addResourceToFrame: function(frameId, resource)
{
var resourcesForFrame = this._resourcesByFrameId[frameId];
if (!resourcesForFrame) {
resourcesForFrame = [];
this._resourcesByFrameId[frameId] = resourcesForFrame;
}
resourcesForFrame.push(resource);

WebInspector.panels.resources.addResourceToFrame(frameId, resource);
},

_clearResources: function(frameId, loaderToPreserveId)
{
var resourcesForFrame = this._resourcesByFrameId[frameId];
if (!resourcesForFrame)
return;

var preservedResourcesForFrame = [];
for (var i = 0; i < resourcesForFrame.length; ++i) {
var resource = resourcesForFrame[i];
if (resource.loader.loaderId === loaderToPreserveId) {
preservedResourcesForFrame.push(resource);
continue;
}
WebInspector.resourceManager._unbindResourceURL(resource);
}

delete this._resourcesByFrameId[frameId];
if (preservedResourcesForFrame.length)
this._resourcesByFrameId[frameId] = preservedResourcesForFrame;
},

forAllResources: function(callback)
{
this._callForFrameResources(0, callback);
},

_callForFrameResources: function(frameId, callback)
{
var resources = this._resourcesByFrameId[frameId];
for (var i = 0; resources && i < resources.length; ++i) {
if (callback(resources[i]))
return true;
}

var frames = this._subframes[frameId];
if (frames) {
for (var id in frames) {
if (this._callForFrameResources(id, callback))
return true;
}
}
return false;
}
}





WebInspector.ResourceCategory = function(name, title, color)
{
this.name = name;
this.title = title;
this.color = color;
}

WebInspector.ResourceCategory.prototype = {
toString: function()
{
return this.title;
}
}





WebInspector.Database = function(id, domain, name, version)
{
this._id = id;
this._domain = domain;
this._name = name;
this._version = version;
}

WebInspector.Database.successCallbacks = {};
WebInspector.Database.errorCallbacks = {};

WebInspector.Database.prototype = {
get id()
{
return this._id;
},

get name()
{
return this._name;
},

set name(x)
{
this._name = x;
},

get version()
{
return this._version;
},

set version(x)
{
this._version = x;
},

get domain()
{
return this._domain;
},

set domain(x)
{
this._domain = x;
},

get displayDomain()
{
return WebInspector.Resource.prototype.__lookupGetter__("displayDomain").call(this);
},

getTableNames: function(callback)
{
function sortingCallback(names)
{
callback(names.sort());
}
InspectorBackend.getDatabaseTableNames(this._id, sortingCallback);
},

executeSql: function(query, onSuccess, onError)
{
function callback(success, transactionId)
{
if (!success) {
onError(WebInspector.UIString("Database not found."));
return;
}
WebInspector.Database.successCallbacks[transactionId] = onSuccess;
WebInspector.Database.errorCallbacks[transactionId] = onError;
}
InspectorBackend.executeSQL(this._id, query, callback);
}
}

WebInspector.sqlTransactionSucceeded = function(transactionId, columnNames, values)
{
var callback = WebInspector.Database.successCallbacks[transactionId];
if (!callback)
return;
delete WebInspector.Database.successCallbacks[transactionId];
callback(columnNames, values);
}

WebInspector.sqlTransactionFailed = function(transactionId, errorObj)
{
var callback = WebInspector.Database.errorCallbacks[transactionId];
if (!callback)
return;
delete WebInspector.Database.errorCallbacks[transactionId];
callback(errorObj);
}





WebInspector.DOMStorage = function(id, domain, isLocalStorage)
{
this._id = id;
this._domain = domain;
this._isLocalStorage = isLocalStorage;
}

WebInspector.DOMStorage.prototype = {
get id()
{
return this._id;
},

get domStorage()
{
return this._domStorage;
},

get domain()
{
return this._domain;
},

get isLocalStorage()
{
return this._isLocalStorage;
},

getEntries: function(callback)
{
InspectorBackend.getDOMStorageEntries(this._id, callback);
},

setItem: function(key, value, callback)
{
InspectorBackend.setDOMStorageItem(this._id, key, value, callback);
},

removeItem: function(key, callback)
{
InspectorBackend.removeDOMStorageItem(this._id, key, callback);
}
}






WebInspector.DOMStorageItemsView = function(domStorage)
{
WebInspector.View.call(this);

this.domStorage = domStorage;

this.element.addStyleClass("storage-view");
this.element.addStyleClass("table");

this.deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item");
this.deleteButton.visible = false;
this.deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);

this.refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
this.refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
}

WebInspector.DOMStorageItemsView.prototype = {
get statusBarItems()
{
return [this.refreshButton.element, this.deleteButton.element];
},

show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);
this.update();
},

hide: function()
{
WebInspector.View.prototype.hide.call(this);
this.deleteButton.visible = false;
},

update: function()
{
this.element.removeChildren();
var callback = this._showDOMStorageEntries.bind(this);
this.domStorage.getEntries(callback);
},

_showDOMStorageEntries: function(entries)
{
this._dataGrid = this._dataGridForDOMStorageEntries(entries);
this.element.appendChild(this._dataGrid.element);
this._dataGrid.autoSizeColumns(10);
this.deleteButton.visible = true;
},

resize: function()
{
if (this._dataGrid)
this._dataGrid.updateWidths();
},

_dataGridForDOMStorageEntries: function(entries)
{
var columns = {};
columns[0] = {};
columns[1] = {};
columns[0].title = WebInspector.UIString("Key");
columns[1].title = WebInspector.UIString("Value");

var nodes = [];

var keys = [];
var length = entries.length;
for (var i = 0; i < entries.length; i++) {
var data = {};

var key = entries[i][0];
data[0] = key;
var value = entries[i][1];
data[1] = value;
var node = new WebInspector.DataGridNode(data, false);
node.selectable = true;
nodes.push(node);
keys.push(key);
}

var dataGrid = new WebInspector.DataGrid(columns, this._editingCallback.bind(this), this._deleteCallback.bind(this));
var length = nodes.length;
for (var i = 0; i < length; ++i)
dataGrid.appendChild(nodes[i]);
dataGrid.addCreationNode(false);
if (length > 0)
nodes[0].selected = true;
return dataGrid;
},

_deleteButtonClicked: function(event)
{
if (!this._dataGrid || !this._dataGrid.selectedNode)
return;

this._deleteCallback(this._dataGrid.selectedNode);
},

_refreshButtonClicked: function(event)
{
this.update();
},

_editingCallback: function(editingNode, columnIdentifier, oldText, newText)
{
var domStorage = this.domStorage;
if (columnIdentifier === 0) {
if (oldText)
domStorage.removeItem(oldText);

domStorage.setItem(newText, editingNode.data[1]);
} else {
domStorage.setItem(editingNode.data[0], newText);
}

this.update();
},

_deleteCallback: function(node)
{
if (!node || node.isCreationNode)
return;

if (this.domStorage)
this.domStorage.removeItem(node.data[0]);

this.update();
}
}

WebInspector.DOMStorageItemsView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.DataGrid = function(columns, editCallback, deleteCallback)
{
this.element = document.createElement("div");
this.element.className = "data-grid";
this.element.tabIndex = 0;
this.element.addEventListener("keydown", this._keyDown.bind(this), false);

this._headerTable = document.createElement("table");
this._headerTable.className = "header";
this._headerTableHeaders = {};

this._dataTable = document.createElement("table");
this._dataTable.className = "data";

this._dataTable.addEventListener("mousedown", this._mouseDownInDataTable.bind(this), true);
this._dataTable.addEventListener("click", this._clickInDataTable.bind(this), true);

this._dataTable.addEventListener("contextmenu", this._contextMenuInDataTable.bind(this), true);



if (editCallback) {
this._dataTable.addEventListener("dblclick", this._ondblclick.bind(this), false);
this._editCallback = editCallback;
}
if (deleteCallback)
this._deleteCallback = deleteCallback;

this.aligned = {};

this._scrollContainer = document.createElement("div");
this._scrollContainer.className = "data-container";
this._scrollContainer.appendChild(this._dataTable);

this.element.appendChild(this._headerTable);
this.element.appendChild(this._scrollContainer);

var headerRow = document.createElement("tr");
var columnGroup = document.createElement("colgroup");
this._columnCount = 0;

for (var columnIdentifier in columns) {
var column = columns[columnIdentifier];
if (column.disclosure)
this.disclosureColumnIdentifier = columnIdentifier;

var col = document.createElement("col");
if (column.width)
col.style.width = column.width;
column.element = col;
columnGroup.appendChild(col);

var cell = document.createElement("th");
cell.className = columnIdentifier + "-column";
cell.columnIdentifier = columnIdentifier;
this._headerTableHeaders[columnIdentifier] = cell;

var div = document.createElement("div");
if (column.titleDOMFragment)
div.appendChild(column.titleDOMFragment);
else
div.textContent = column.title;
cell.appendChild(div);

if (column.sort) {
cell.addStyleClass("sort-" + column.sort);
this._sortColumnCell = cell;
}

if (column.sortable) {
cell.addEventListener("click", this._clickInHeaderCell.bind(this), false);
cell.addStyleClass("sortable");
}

if (column.aligned)
this.aligned[columnIdentifier] = column.aligned;

headerRow.appendChild(cell);

++this._columnCount;
}

columnGroup.span = this._columnCount;

var cell = document.createElement("th");
cell.className = "corner";
headerRow.appendChild(cell);

this._headerTableColumnGroup = columnGroup;
this._headerTable.appendChild(this._headerTableColumnGroup);
this.headerTableBody.appendChild(headerRow);

var fillerRow = document.createElement("tr");
fillerRow.className = "filler";

for (var columnIdentifier in columns) {
var column = columns[columnIdentifier];
var cell = document.createElement("td");
cell.className = columnIdentifier + "-column";
fillerRow.appendChild(cell);
}

this._dataTableColumnGroup = columnGroup.cloneNode(true);
this._dataTable.appendChild(this._dataTableColumnGroup);
this.dataTableBody.appendChild(fillerRow);

this.columns = columns || {};
this._columnsArray = [];
for (var columnIdentifier in columns) {
columns[columnIdentifier].ordinal = this._columnsArray.length;
this._columnsArray.push(columns[columnIdentifier]);
}

for (var i = 0; i < this._columnsArray.length; ++i)
this._columnsArray[i].bodyElement = this._dataTableColumnGroup.children[i];

this.children = [];
this.selectedNode = null;
this.expandNodesWhenArrowing = false;
this.root = true;
this.hasChildren = false;
this.expanded = true;
this.revealed = true;
this.selected = false;
this.dataGrid = this;
this.indentWidth = 15;
this.resizers = [];
this._columnWidthsInitialized = false;
}

WebInspector.DataGrid.prototype = {
_ondblclick: function(event)
{
if (this._editing || this._editingNode)
return;

this._startEditing(event.target);
},

_startEditingColumnOfDataGridNode: function(node, column)
{
this._editing = true;
this._editingNode = node;
this._editingNode.select();

var element = this._editingNode._element.children[column];
WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},

_startEditing: function(target)
{
var element = target.enclosingNodeOrSelfWithNodeName("td");
if (!element)
return;

this._editingNode = this.dataGridNodeFromNode(target);
if (!this._editingNode) {
if (!this.creationNode)
return;
this._editingNode = this.creationNode;
}


if (this._editingNode.isCreationNode)
return this._startEditingColumnOfDataGridNode(this._editingNode, 0);

this._editing = true;
WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},

_editingCommitted: function(element, newText, oldText, context, moveDirection)
{




var columnIdentifier = parseInt(element.className.match(/\b(\d+)-column\b/)[1]);

var textBeforeEditing = this._editingNode.data[columnIdentifier];
var currentEditingNode = this._editingNode;

function moveToNextIfNeeded(wasChange) {
if (!moveDirection)
return;

if (moveDirection === "forward") {
if (currentEditingNode.isCreationNode && columnIdentifier === 0 && !wasChange)
return;

if (columnIdentifier === 0)
return this._startEditingColumnOfDataGridNode(currentEditingNode, 1);

var nextDataGridNode = currentEditingNode.traverseNextNode(true, null, true);
if (nextDataGridNode)
return this._startEditingColumnOfDataGridNode(nextDataGridNode, 0);
if (currentEditingNode.isCreationNode && wasChange) {
addCreationNode(false);
return this._startEditingColumnOfDataGridNode(this.creationNode, 0);
}
return;
}

if (moveDirection === "backward") {
if (columnIdentifier === 1)
return this._startEditingColumnOfDataGridNode(currentEditingNode, 0);
var nextDataGridNode = currentEditingNode.traversePreviousNode(true, null, true);

if (nextDataGridNode)
return this._startEditingColumnOfDataGridNode(nextDataGridNode, 1);
return;
}
}

if (textBeforeEditing == newText) {
this._editingCancelled(element);
moveToNextIfNeeded.call(this, false);
return;
}


this._editingNode.data[columnIdentifier] = newText;



this._editCallback(this._editingNode, columnIdentifier, textBeforeEditing, newText);

if (this._editingNode.isCreationNode)
this.addCreationNode(false);

this._editingCancelled(element);
moveToNextIfNeeded.call(this, true);
},

_editingCancelled: function(element, context)
{
delete this._editing;
this._editingNode = null;
},

get sortColumnIdentifier()
{
if (!this._sortColumnCell)
return null;
return this._sortColumnCell.columnIdentifier;
},

get sortOrder()
{
if (!this._sortColumnCell || this._sortColumnCell.hasStyleClass("sort-ascending"))
return "ascending";
if (this._sortColumnCell.hasStyleClass("sort-descending"))
return "descending";
return null;
},

get headerTableBody()
{
if ("_headerTableBody" in this)
return this._headerTableBody;

this._headerTableBody = this._headerTable.getElementsByTagName("tbody")[0];
if (!this._headerTableBody) {
this._headerTableBody = this.element.ownerDocument.createElement("tbody");
this._headerTable.insertBefore(this._headerTableBody, this._headerTable.tFoot);
}

return this._headerTableBody;
},

get dataTableBody()
{
if ("_dataTableBody" in this)
return this._dataTableBody;

this._dataTableBody = this._dataTable.getElementsByTagName("tbody")[0];
if (!this._dataTableBody) {
this._dataTableBody = this.element.ownerDocument.createElement("tbody");
this._dataTable.insertBefore(this._dataTableBody, this._dataTable.tFoot);
}

return this._dataTableBody;
},

autoSizeColumns: function(minPercent, maxPercent, maxDescentLevel)
{
if (minPercent)
minPercent = Math.min(minPercent, Math.floor(100 / this._columnCount));
var widths = {};
var columns = this.columns;
for (var columnIdentifier in columns)
widths[columnIdentifier] = (columns[columnIdentifier].title || "").length;

var children = maxDescentLevel ? this._enumerateChildren(this, [], maxDescentLevel + 1) : this.children;
for (var i = 0; i < children.length; ++i) {
var node = children[i];
for (var columnIdentifier in columns) {
var text = node.data[columnIdentifier] || "";
if (text.length > widths[columnIdentifier])
widths[columnIdentifier] = text.length;
}
}

var totalColumnWidths = 0;
for (var columnIdentifier in columns)
totalColumnWidths += widths[columnIdentifier];

var recoupPercent = 0;
for (var columnIdentifier in columns) {
var width = Math.round(100 * widths[columnIdentifier] / totalColumnWidths);
if (minPercent && width < minPercent) {
recoupPercent += (minPercent - width);
width = minPercent;
} else if (maxPercent && width > maxPercent) {
recoupPercent -= (width - maxPercent);
width = maxPercent;
}
widths[columnIdentifier] = width;
}

while (minPercent && recoupPercent > 0) {
for (var columnIdentifier in columns) {
if (widths[columnIdentifier] > minPercent) {
--widths[columnIdentifier];
--recoupPercent;
if (!recoupPercent)
break;
}
}
}

while (maxPercent && recoupPercent < 0) {
for (var columnIdentifier in columns) {
if (widths[columnIdentifier] < maxPercent) {
++widths[columnIdentifier];
++recoupPercent;
if (!recoupPercent)
break;
}
}
}

for (var columnIdentifier in columns)
columns[columnIdentifier].element.style.width = widths[columnIdentifier] + "%";
this._columnWidthsInitialized = false;
this.updateWidths();
},

_enumerateChildren: function(rootNode, result, maxLevel)
{
if (!rootNode.root)
result.push(rootNode);
if (!maxLevel)
return;
for (var i = 0; i < rootNode.children.length; ++i)
this._enumerateChildren(rootNode.children[i], result, maxLevel - 1);
return result;
},











updateWidths: function()
{
var headerTableColumns = this._headerTableColumnGroup.children;

var tableWidth = this._dataTable.offsetWidth;
var numColumns = headerTableColumns.length;


if (!this._columnWidthsInitialized && this.element.offsetWidth) {




for (var i = 0; i < numColumns; i++) {
var columnWidth = this.headerTableBody.rows[0].cells[i].offsetWidth;
var percentWidth = ((columnWidth / tableWidth) * 100) + "%";
this._headerTableColumnGroup.children[i].style.width = percentWidth;
this._dataTableColumnGroup.children[i].style.width = percentWidth;
}
this._columnWidthsInitialized = true;
}
this._positionResizers();
this.dispatchEventToListeners("width changed");
},

columnWidthsMap: function()
{
var result = {};
for (var i = 0; i < this._columnsArray.length; ++i) {
var width = this._headerTableColumnGroup.children[i].style.width;
result[this._columnsArray[i].columnIdentifier] = parseFloat(width);
}
return result;
},

applyColumnWidthsMap: function(columnWidthsMap)
{
for (var columnIdentifier in this.columns) {
var column = this.columns[columnIdentifier];
var width = (columnWidthsMap[columnIdentifier] || 0) + "%";
this._headerTableColumnGroup.children[column.ordinal].style.width = width;
this._dataTableColumnGroup.children[column.ordinal].style.width = width;
}


delete this._columnWidthsInitialized;
this.updateWidths();
},

isColumnVisible: function(columnIdentifier)
{
var column = this.columns[columnIdentifier];
var columnElement = column.element;
return !columnElement.hidden;
},

showColumn: function(columnIdentifier)
{
var column = this.columns[columnIdentifier];
var columnElement = column.element;
if (!columnElement.hidden)
return;

columnElement.hidden = false;
columnElement.removeStyleClass("hidden");

var columnBodyElement = column.bodyElement;
columnBodyElement.hidden = false;
columnBodyElement.removeStyleClass("hidden");
},

hideColumn: function(columnIdentifier)
{
var column = this.columns[columnIdentifier];
var columnElement = column.element;
if (columnElement.hidden)
return;

var oldWidth = parseFloat(columnElement.style.width);

columnElement.hidden = true;
columnElement.addStyleClass("hidden");
columnElement.style.width = 0;

var columnBodyElement = column.bodyElement;
columnBodyElement.hidden = true;
columnBodyElement.addStyleClass("hidden");
columnBodyElement.style.width = 0;

this._columnWidthsInitialized = false;
},

isScrolledToLastRow: function()
{
return this._scrollContainer.scrollTop === this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight;
},

scrollToLastRow: function()
{
this._scrollContainer.scrollTop = this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight;
},

_positionResizers: function()
{
var headerTableColumns = this._headerTableColumnGroup.children;
var numColumns = headerTableColumns.length;
var left = 0;
var previousResizer = null;


for (var i = 0; i < numColumns - 1; i++) {
var resizer = this.resizers[i];

if (!resizer) {


resizer = document.createElement("div");
resizer.addStyleClass("data-grid-resizer");

resizer.addEventListener("mousedown", this._startResizerDragging.bind(this), false);
this.element.appendChild(resizer);
this.resizers[i] = resizer;
}




left += this.headerTableBody.rows[0].cells[i].offsetWidth;

var columnIsVisible = !this._headerTableColumnGroup.children[i].hidden;
if (columnIsVisible) {
resizer.style.removeProperty("display");
resizer.style.left = left + "px";
resizer.leftNeighboringColumnID = i;
if (previousResizer)
previousResizer.rightNeighboringColumnID = i;
previousResizer = resizer;
} else {
resizer.style.setProperty("display", "none");
resizer.leftNeighboringColumnID = 0;
resizer.rightNeighboringColumnID = 0;
}
}
if (previousResizer)
previousResizer.rightNeighboringColumnID = numColumns - 1;
},

addCreationNode: function(hasChildren)
{
if (this.creationNode)
this.creationNode.makeNormal();

var emptyData = {};
for (var column in this.columns)
emptyData[column] = '';
this.creationNode = new WebInspector.CreationDataGridNode(emptyData, hasChildren);
this.appendChild(this.creationNode);
},

appendChild: function(child)
{
this.insertChild(child, this.children.length);
},

insertChild: function(child, index)
{
if (!child)
throw("insertChild: Node can't be undefined or null.");
if (child.parent === this)
throw("insertChild: Node is already a child of this node.");

if (child.parent)
child.parent.removeChild(child);

this.children.splice(index, 0, child);
this.hasChildren = true;

child.parent = this;
child.dataGrid = this.dataGrid;
child._recalculateSiblings(index);

delete child._depth;
delete child._revealed;
delete child._attached;
child._shouldRefreshChildren = true;

var current = child.children[0];
while (current) {
current.dataGrid = this.dataGrid;
delete current._depth;
delete current._revealed;
delete current._attached;
current._shouldRefreshChildren = true;
current = current.traverseNextNode(false, child, true);
}

if (this.expanded)
child._attach();
},

removeChild: function(child)
{
if (!child)
throw("removeChild: Node can't be undefined or null.");
if (child.parent !== this)
throw("removeChild: Node is not a child of this node.");

child.deselect();
child._detach();

this.children.remove(child, true);

if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
if (child.nextSibling)
child.nextSibling.previousSibling = child.previousSibling;

child.dataGrid = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;

if (this.children.length <= 0)
this.hasChildren = false;
},

removeChildren: function()
{
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
child.deselect();
child._detach();

child.dataGrid = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}

this.children = [];
this.hasChildren = false;
},

removeChildrenRecursive: function()
{
var childrenToRemove = this.children;

var child = this.children[0];
while (child) {
if (child.children.length)
childrenToRemove = childrenToRemove.concat(child.children);
child = child.traverseNextNode(false, this, true);
}

for (var i = 0; i < childrenToRemove.length; ++i) {
var child = childrenToRemove[i];
child.deselect();
child._detach();

child.children = [];
child.dataGrid = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}

this.children = [];
},

sortNodes: function(comparator, reverseMode)
{
function comparatorWrapper(a, b)
{
if (a._dataGridNode._data.summaryRow)
return 1;
if (b._dataGridNode._data.summaryRow)
return -1;

var aDataGirdNode = a._dataGridNode;
var bDataGirdNode = b._dataGridNode;
return reverseMode ? comparator(bDataGirdNode, aDataGirdNode) : comparator(aDataGirdNode, bDataGirdNode);
}

var tbody = this.dataTableBody;
var tbodyParent = tbody.parentElement;
tbodyParent.removeChild(tbody);

var childNodes = tbody.childNodes;
var fillerRow = childNodes[childNodes.length - 1];

var sortedRows = Array.prototype.slice.call(childNodes, 0, childNodes.length - 1);
sortedRows.sort(comparatorWrapper);
var sortedRowsLength = sortedRows.length;

tbody.removeChildren();
var previousSiblingNode = null;
for (var i = 0; i < sortedRowsLength; ++i) {
var row = sortedRows[i];
var node = row._dataGridNode;
node.previousSibling = previousSiblingNode;
if (previousSiblingNode)
previousSiblingNode.nextSibling = node;
tbody.appendChild(row);
previousSiblingNode = node;
}
if (previousSiblingNode)
previousSiblingNode.nextSibling = null;

tbody.appendChild(fillerRow);
tbodyParent.appendChild(tbody);
},

_keyDown: function(event)
{
if (!this.selectedNode || event.shiftKey || event.metaKey || event.ctrlKey || this._editing)
return;

var handled = false;
var nextSelectedNode;
if (event.keyIdentifier === "Up" && !event.altKey) {
nextSelectedNode = this.selectedNode.traversePreviousNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traversePreviousNode(!this.expandTreeNodesWhenArrowing);
handled = nextSelectedNode ? true : false;
} else if (event.keyIdentifier === "Down" && !event.altKey) {
nextSelectedNode = this.selectedNode.traverseNextNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traverseNextNode(!this.expandTreeNodesWhenArrowing);
handled = nextSelectedNode ? true : false;
} else if (event.keyIdentifier === "Left") {
if (this.selectedNode.expanded) {
if (event.altKey)
this.selectedNode.collapseRecursively();
else
this.selectedNode.collapse();
handled = true;
} else if (this.selectedNode.parent && !this.selectedNode.parent.root) {
handled = true;
if (this.selectedNode.parent.selectable) {
nextSelectedNode = this.selectedNode.parent;
handled = nextSelectedNode ? true : false;
} else if (this.selectedNode.parent)
this.selectedNode.parent.collapse();
}
} else if (event.keyIdentifier === "Right") {
if (!this.selectedNode.revealed) {
this.selectedNode.reveal();
handled = true;
} else if (this.selectedNode.hasChildren) {
handled = true;
if (this.selectedNode.expanded) {
nextSelectedNode = this.selectedNode.children[0];
handled = nextSelectedNode ? true : false;
} else {
if (event.altKey)
this.selectedNode.expandRecursively();
else
this.selectedNode.expand();
}
}
} else if (event.keyCode === 8 || event.keyCode === 46) {
if (this._deleteCallback) {
handled = true;
this._deleteCallback(this.selectedNode);
}
} else if (isEnterKey(event)) {
if (this._editCallback) {
handled = true;


this._startEditing(this.selectedNode._element.children[0]);
}
}

if (nextSelectedNode) {
nextSelectedNode.reveal();
nextSelectedNode.select();
}

if (handled) {
event.preventDefault();
event.stopPropagation();
}
},

expand: function()
{

},

collapse: function()
{

},

reveal: function()
{

},

dataGridNodeFromNode: function(target)
{
var rowElement = target.enclosingNodeOrSelfWithNodeName("tr");
return rowElement._dataGridNode;
},

dataGridNodeFromPoint: function(x, y)
{
var node = this._dataTable.ownerDocument.elementFromPoint(x, y);
var rowElement = node.enclosingNodeOrSelfWithNodeName("tr");
return rowElement._dataGridNode;
},

_clickInHeaderCell: function(event)
{
var cell = event.target.enclosingNodeOrSelfWithNodeName("th");
if (!cell || !cell.columnIdentifier || !cell.hasStyleClass("sortable"))
return;

var sortOrder = this.sortOrder;

if (this._sortColumnCell)
this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+");

if (cell == this._sortColumnCell) {
if (sortOrder === "ascending")
sortOrder = "descending";
else
sortOrder = "ascending";
}

this._sortColumnCell = cell;

cell.addStyleClass("sort-" + sortOrder);

this.dispatchEventToListeners("sorting changed");
},

markColumnAsSortedBy: function(columnIdentifier, sortOrder)
{
if (this._sortColumnCell)
this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+");
this._sortColumnCell = this._headerTableHeaders[columnIdentifier];
this._sortColumnCell.addStyleClass("sort-" + sortOrder);
},

headerTableHeader: function(columnIdentifier)
{
return this._headerTableHeaders[columnIdentifier];
},

_mouseDownInDataTable: function(event)
{
var gridNode = this.dataGridNodeFromNode(event.target);
if (!gridNode || !gridNode.selectable)
return;

if (gridNode.isEventWithinDisclosureTriangle(event))
return;

if (event.metaKey) {
if (gridNode.selected)
gridNode.deselect();
else
gridNode.select();
} else
gridNode.select();
},

_contextMenuInDataTable: function(event)
{
var gridNode = this.dataGridNodeFromNode(event.target);
if (!gridNode || !gridNode.selectable)
return;

if (gridNode.isEventWithinDisclosureTriangle(event))
return;

var contextMenu = new WebInspector.ContextMenu();


if (this.dataGrid._editCallback) {
if (gridNode === this.creationNode)
contextMenu.appendItem(WebInspector.UIString("Add New"), this._startEditing.bind(this, event.target));
else
contextMenu.appendItem(WebInspector.UIString("Edit"), this._startEditing.bind(this, event.target));
}
if (this.dataGrid._deleteCallback && gridNode !== this.creationNode)
contextMenu.appendItem(WebInspector.UIString("Delete"), this._deleteCallback.bind(this, gridNode));

contextMenu.show(event);
},

_clickInDataTable: function(event)
{
var gridNode = this.dataGridNodeFromNode(event.target);
if (!gridNode || !gridNode.hasChildren)
return;

if (!gridNode.isEventWithinDisclosureTriangle(event))
return;

if (gridNode.expanded) {
if (event.altKey)
gridNode.collapseRecursively();
else
gridNode.collapse();
} else {
if (event.altKey)
gridNode.expandRecursively();
else
gridNode.expand();
}
},

_startResizerDragging: function(event)
{
this.currentResizer = event.target;
if (!this.currentResizer.rightNeighboringColumnID)
return;
WebInspector.elementDragStart(this.lastResizer, this._resizerDragging.bind(this),
this._endResizerDragging.bind(this), event, "col-resize");
},

_resizerDragging: function(event)
{
var resizer = this.currentResizer;
if (!resizer)
return;



var dragPoint = event.clientX - this.element.totalOffsetLeft;


var leftEdgeOfPreviousColumn = 0;
var firstRowCells = this.headerTableBody.rows[0].cells;
for (var i = 0; i < resizer.leftNeighboringColumnID; i++)
leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth;

var rightEdgeOfNextColumn = leftEdgeOfPreviousColumn + firstRowCells[resizer.leftNeighboringColumnID].offsetWidth + firstRowCells[resizer.rightNeighboringColumnID].offsetWidth;


var leftMinimum = leftEdgeOfPreviousColumn + this.ColumnResizePadding;
var rightMaximum = rightEdgeOfNextColumn - this.ColumnResizePadding;

dragPoint = Number.constrain(dragPoint, leftMinimum, rightMaximum);

resizer.style.left = (dragPoint - this.CenterResizerOverBorderAdjustment) + "px";

var percentLeftColumn = (((dragPoint - leftEdgeOfPreviousColumn) / this._dataTable.offsetWidth) * 100) + "%";
this._headerTableColumnGroup.children[resizer.leftNeighboringColumnID].style.width = percentLeftColumn;
this._dataTableColumnGroup.children[resizer.leftNeighboringColumnID].style.width = percentLeftColumn;

var percentRightColumn = (((rightEdgeOfNextColumn - dragPoint) / this._dataTable.offsetWidth) * 100) + "%";
this._headerTableColumnGroup.children[resizer.rightNeighboringColumnID].style.width =  percentRightColumn;
this._dataTableColumnGroup.children[resizer.rightNeighboringColumnID].style.width = percentRightColumn;

this._positionResizers();
event.preventDefault();
this.dispatchEventToListeners("width changed");
},

_endResizerDragging: function(event)
{
WebInspector.elementDragEnd(event);
this.currentResizer = null;
this.dispatchEventToListeners("width changed");
},

ColumnResizePadding: 10,

CenterResizerOverBorderAdjustment: 3,
}

WebInspector.DataGrid.prototype.__proto__ = WebInspector.Object.prototype;

WebInspector.DataGridNode = function(data, hasChildren)
{
this._expanded = false;
this._selected = false;
this._shouldRefreshChildren = true;
this._data = data || {};
this.hasChildren = hasChildren || false;
this.children = [];
this.dataGrid = null;
this.parent = null;
this.previousSibling = null;
this.nextSibling = null;
this.disclosureToggleWidth = 10;
}

WebInspector.DataGridNode.prototype = {
selectable: true,

get element()
{
if (this._element)
return this._element;

if (!this.dataGrid)
return null;

this._element = document.createElement("tr");
this._element._dataGridNode = this;

if (this.hasChildren)
this._element.addStyleClass("parent");
if (this.expanded)
this._element.addStyleClass("expanded");
if (this.selected)
this._element.addStyleClass("selected");
if (this.revealed)
this._element.addStyleClass("revealed");

this.createCells();
return this._element;
},

createCells: function()
{
for (var columnIdentifier in this.dataGrid.columns) {
var cell = this.createCell(columnIdentifier);
this._element.appendChild(cell);
}
},

get data()
{
return this._data;
},

set data(x)
{
this._data = x || {};
this.refresh();
},

get revealed()
{
if ("_revealed" in this)
return this._revealed;

var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded) {
this._revealed = false;
return false;
}

currentAncestor = currentAncestor.parent;
}

this._revealed = true;
return true;
},

set hasChildren(x)
{
if (this._hasChildren === x)
return;

this._hasChildren = x;

if (!this._element)
return;

if (this._hasChildren)
{
this._element.addStyleClass("parent");
if (this.expanded)
this._element.addStyleClass("expanded");
}
else
{
this._element.removeStyleClass("parent");
this._element.removeStyleClass("expanded");
}
},

get hasChildren()
{
return this._hasChildren;
},

set revealed(x)
{
if (this._revealed === x)
return;

this._revealed = x;

if (this._element) {
if (this._revealed)
this._element.addStyleClass("revealed");
else
this._element.removeStyleClass("revealed");
}

for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = x && this.expanded;
},

get depth()
{
if ("_depth" in this)
return this._depth;
if (this.parent && !this.parent.root)
this._depth = this.parent.depth + 1;
else
this._depth = 0;
return this._depth;
},

get shouldRefreshChildren()
{
return this._shouldRefreshChildren;
},

set shouldRefreshChildren(x)
{
this._shouldRefreshChildren = x;
if (x && this.expanded)
this.expand();
},

get selected()
{
return this._selected;
},

set selected(x)
{
if (x)
this.select();
else
this.deselect();
},

get expanded()
{
return this._expanded;
},

set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},

refresh: function()
{
if (!this._element || !this.dataGrid)
return;

this._element.removeChildren();
this.createCells();
},

createCell: function(columnIdentifier)
{
var cell = document.createElement("td");
cell.className = columnIdentifier + "-column";

var alignment = this.dataGrid.aligned[columnIdentifier];
if (alignment)
cell.addStyleClass(alignment);

var div = document.createElement("div");
div.textContent = this.data[columnIdentifier];
cell.appendChild(div);

if (columnIdentifier === this.dataGrid.disclosureColumnIdentifier) {
cell.addStyleClass("disclosure");
if (this.depth)
cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
}

return cell;
},


appendChild: WebInspector.DataGrid.prototype.appendChild,
insertChild: WebInspector.DataGrid.prototype.insertChild,
removeChild: WebInspector.DataGrid.prototype.removeChild,
removeChildren: WebInspector.DataGrid.prototype.removeChildren,
removeChildrenRecursive: WebInspector.DataGrid.prototype.removeChildrenRecursive,

_recalculateSiblings: function(myIndex)
{
if (!this.parent)
return;

var previousChild = (myIndex > 0 ? this.parent.children[myIndex - 1] : null);

if (previousChild) {
previousChild.nextSibling = this;
this.previousSibling = previousChild;
} else
this.previousSibling = null;

var nextChild = this.parent.children[myIndex + 1];

if (nextChild) {
nextChild.previousSibling = this;
this.nextSibling = nextChild;
} else
this.nextSibling = null;
},

collapse: function()
{
if (this._element)
this._element.removeStyleClass("expanded");

this._expanded = false;

for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = false;

this.dispatchEventToListeners("collapsed");
},

collapseRecursively: function()
{
var item = this;
while (item) {
if (item.expanded)
item.collapse();
item = item.traverseNextNode(false, this, true);
}
},

expand: function()
{
if (!this.hasChildren || this.expanded)
return;

if (this.revealed && !this._shouldRefreshChildren)
for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = true;

if (this._shouldRefreshChildren) {
for (var i = 0; i < this.children.length; ++i)
this.children[i]._detach();

this.dispatchEventToListeners("populate");

if (this._attached) {
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
if (this.revealed)
child.revealed = true;
child._attach();
}
}

delete this._shouldRefreshChildren;
}

if (this._element)
this._element.addStyleClass("expanded");

this._expanded = true;

this.dispatchEventToListeners("expanded");
},

expandRecursively: function()
{
var item = this;
while (item) {
item.expand();
item = item.traverseNextNode(false, this);
}
},

reveal: function()
{
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded)
currentAncestor.expand();
currentAncestor = currentAncestor.parent;
}

this.element.scrollIntoViewIfNeeded(false);

this.dispatchEventToListeners("revealed");
},

select: function(supressSelectedEvent)
{
if (!this.dataGrid || !this.selectable || this.selected)
return;

if (this.dataGrid.selectedNode)
this.dataGrid.selectedNode.deselect();

this._selected = true;
this.dataGrid.selectedNode = this;

if (this._element)
this._element.addStyleClass("selected");

if (!supressSelectedEvent)
this.dispatchEventToListeners("selected");
},

deselect: function(supressDeselectedEvent)
{
if (!this.dataGrid || this.dataGrid.selectedNode !== this || !this.selected)
return;

this._selected = false;
this.dataGrid.selectedNode = null;

if (this._element)
this._element.removeStyleClass("selected");

if (!supressDeselectedEvent)
this.dispatchEventToListeners("deselected");
},

traverseNextNode: function(skipHidden, stayWithin, dontPopulate, info)
{
if (!dontPopulate && this.hasChildren)
this.dispatchEventToListeners("populate");

if (info)
info.depthChange = 0;

var node = (!skipHidden || this.revealed) ? this.children[0] : null;
if (node && (!skipHidden || this.expanded)) {
if (info)
info.depthChange = 1;
return node;
}

if (this === stayWithin)
return null;

node = (!skipHidden || this.revealed) ? this.nextSibling : null;
if (node)
return node;

node = this;
while (node && !node.root && !((!skipHidden || node.revealed) ? node.nextSibling : null) && node.parent !== stayWithin) {
if (info)
info.depthChange -= 1;
node = node.parent;
}

if (!node)
return null;

return (!skipHidden || node.revealed) ? node.nextSibling : null;
},

traversePreviousNode: function(skipHidden, dontPopulate)
{
var node = (!skipHidden || this.revealed) ? this.previousSibling : null;
if (!dontPopulate && node && node.hasChildren)
node.dispatchEventToListeners("populate");

while (node && ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null)) {
if (!dontPopulate && node.hasChildren)
node.dispatchEventToListeners("populate");
node = ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null);
}

if (node)
return node;

if (!this.parent || this.parent.root)
return null;

return this.parent;
},

isEventWithinDisclosureTriangle: function(event)
{
if (!this.hasChildren)
return false;
var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
if (!cell.hasStyleClass("disclosure"))
return false;
var computedLeftPadding = window.getComputedStyle(cell).getPropertyCSSValue("padding-left").getFloatValue(CSSPrimitiveValue.CSS_PX);
var left = cell.totalOffsetLeft + computedLeftPadding;
return event.pageX >= left && event.pageX <= left + this.disclosureToggleWidth;
},

_attach: function()
{
if (!this.dataGrid || this._attached)
return;

this._attached = true;

var nextNode = null;
var previousNode = this.traversePreviousNode(true, true);
if (previousNode && previousNode.element.parentNode && previousNode.element.nextSibling)
var nextNode = previousNode.element.nextSibling;
if (!nextNode)
nextNode = this.dataGrid.dataTableBody.lastChild;
this.dataGrid.dataTableBody.insertBefore(this.element, nextNode);

if (this.expanded)
for (var i = 0; i < this.children.length; ++i)
this.children[i]._attach();
},

_detach: function()
{
if (!this._attached)
return;

this._attached = false;

if (this._element && this._element.parentNode)
this._element.parentNode.removeChild(this._element);

for (var i = 0; i < this.children.length; ++i)
this.children[i]._detach();
},

savePosition: function()
{
if (this._savedPosition)
return;

if (!this.parent)
throw("savePosition: Node must have a parent.");
this._savedPosition = {
parent: this.parent,
index: this.parent.children.indexOf(this)
};
},

restorePosition: function()
{
if (!this._savedPosition)
return;

if (this.parent !== this._savedPosition.parent)
this._savedPosition.parent.insertChild(this, this._savedPosition.index);

delete this._savedPosition;
}
}

WebInspector.DataGridNode.prototype.__proto__ = WebInspector.Object.prototype;

WebInspector.CreationDataGridNode = function(data, hasChildren)
{
WebInspector.DataGridNode.call(this, data, hasChildren);
this.isCreationNode = true;
}

WebInspector.CreationDataGridNode.prototype = {
makeNormal: function()
{
delete this.isCreationNode;
delete this.makeNormal;
}
}

WebInspector.CreationDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;





WebInspector.CookiesTable = function(cookieDomain, expandable, deleteCallback)
{
this._cookieDomain = cookieDomain;

var columns = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} };
columns[0].title = WebInspector.UIString("Name");
columns[0].sortable = true;
columns[0].disclosure = expandable;
columns[0].width = "24%";
columns[1].title = WebInspector.UIString("Value");
columns[1].sortable = true;
columns[1].width = "34%";
columns[2].title = WebInspector.UIString("Domain");
columns[2].sortable = true;
columns[2].width = "7%";
columns[3].title = WebInspector.UIString("Path");
columns[3].sortable = true;
columns[3].width = "7%";
columns[4].title = WebInspector.UIString("Expires");
columns[4].sortable = true;
columns[4].width = "7%";
columns[5].title = WebInspector.UIString("Size");
columns[5].aligned = "right";
columns[5].sortable = true;
columns[5].width = "7%";
columns[6].title = WebInspector.UIString("HTTP");
columns[6].aligned = "centered";
columns[6].sortable = true;
columns[6].width = "7%";
columns[7].title = WebInspector.UIString("Secure");
columns[7].aligned = "centered";
columns[7].sortable = true;
columns[7].width = "7%";

this._dataGrid = new WebInspector.DataGrid(columns, null, deleteCallback ? this._onDeleteFromGrid.bind(this) : null);
this._dataGrid.addEventListener("sorting changed", this._rebuildTable, this);

this.element = this._dataGrid.element;
this._data = [];
this._deleteCallback = deleteCallback;
}

WebInspector.CookiesTable.prototype = {
updateWidths: function()
{
if (this._dataGrid)
this._dataGrid.updateWidths();
},

setCookies: function(cookies)
{
this._data = [{cookies: cookies}];
this._rebuildTable();
},

addCookiesFolder: function(folderName, cookies)
{
this._data.push({cookies: cookies, folderName: folderName});
this._rebuildTable();
},

get selectedCookie()
{
var node = this._dataGrid.selectedNode;
return node ? node.cookie : null;
},

_rebuildTable: function()
{
this._dataGrid.removeChildren();
for (var i = 0; i < this._data.length; ++i) {
var item = this._data[i];
if (item.folderName) {
var groupData = [ item.folderName, "", "", "", "", this._totalSize(item.cookies), "", "" ];
var groupNode = new WebInspector.DataGridNode(groupData);
groupNode.selectable = true;
this._dataGrid.appendChild(groupNode);
groupNode.element.addStyleClass("row-group");
this._populateNode(groupNode, item.cookies);
groupNode.expand();
} else
this._populateNode(this._dataGrid, item.cookies);
}
},

_populateNode: function(parentNode, cookies)
{
var selectedCookie = this.selectedCookie;
parentNode.removeChildren();
if (!cookies)
return;

this._sortCookies(cookies);
for (var i = 0; i < cookies.length; ++i) {
var cookieNode = this._createGridNode(cookies[i]);
parentNode.appendChild(cookieNode);
if (selectedCookie === cookies[i])
cookieNode.selected = true;
}
},

_totalSize: function(cookies)
{
var totalSize = 0;
for (var i = 0; cookies && i < cookies.length; ++i)
totalSize += cookies[i].size;
return totalSize;
},

_sortCookies: function(cookies)
{
var sortDirection = this._dataGrid.sortOrder === "ascending" ? 1 : -1;

function localeCompare(field, cookie1, cookie2)
{
return sortDirection * (cookie1[field] + "").localeCompare(cookie2[field] + "")
}

function numberCompare(field, cookie1, cookie2)
{
return sortDirection * (cookie1[field] - cookie2[field]);
}

function expiresCompare(cookie1, cookie2)
{
if (cookie1.session !== cookie2.session)
return sortDirection * (cookie1.session ? 1 : -1);

if (cookie1.session)
return 0;

return sortDirection * (cookie1.expires - cookie2.expires);
}

var comparator;
switch (parseInt(this._dataGrid.sortColumnIdentifier)) {
case 0: comparator = localeCompare.bind(this, "name"); break;
case 1: comparator = localeCompare.bind(this, "value"); break;
case 2: comparator = localeCompare.bind(this, "domain"); break;
case 3: comparator = localeCompare.bind(this, "path"); break;
case 4: comparator = expiresCompare; break;
case 5: comparator = numberCompare.bind(this, "size"); break;
case 6: comparator = localeCompare.bind(this, "httpOnly"); break;
case 7: comparator = localeCompare.bind(this, "secure"); break;
default: localeCompare.bind(this, "name");
}

cookies.sort(comparator);
},

_createGridNode: function(cookie)
{
var data = {};
data[0] = cookie.name;
data[1] = cookie.value;
data[2] = cookie.domain || "";
data[3] = cookie.path || "";
data[4] = cookie.type === WebInspector.Cookie.Type.Request ? "" :
(cookie.session ? WebInspector.UIString("Session") : new Date(cookie.expires).toGMTString());
data[5] = cookie.size;
const checkmark = "\u2713";
data[6] = (cookie.httpOnly ? checkmark : "");
data[7] = (cookie.secure ? checkmark : "");

var node = new WebInspector.DataGridNode(data);
node.cookie = cookie;
node.selectable = true;
return node;
},

_onDeleteFromGrid: function(node)
{
this._deleteCallback(node.cookie);
}
}





WebInspector.CookieItemsView = function(treeElement, cookieDomain)
{
WebInspector.View.call(this);

this.element.addStyleClass("storage-view");

this._deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item");
this._deleteButton.visible = false;
this._deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);

this._refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
this._refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);

this._treeElement = treeElement;
this._cookieDomain = cookieDomain;

this._emptyMsgElement = document.createElement("div");
this._emptyMsgElement.className = "storage-empty-view";
this._emptyMsgElement.textContent = WebInspector.UIString("This site has no cookies.");
this.element.appendChild(this._emptyMsgElement);
}

WebInspector.CookieItemsView.prototype = {
get statusBarItems()
{
return [this._refreshButton.element, this._deleteButton.element];
},

show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);
this._update();
},

hide: function()
{
WebInspector.View.prototype.hide.call(this);
this._deleteButton.visible = false;
},

resize: function()
{
if (this._cookiesTable)
this._cookiesTable.updateWidths();
},

_update: function()
{
WebInspector.Cookies.getCookiesAsync(this._updateWithCookies.bind(this));
},

_updateWithCookies: function(allCookies, isAdvanced)
{
this._cookies = isAdvanced ? this._filterCookiesForDomain(allCookies) : allCookies;

if (!this._cookies.length) {

this._emptyMsgElement.removeStyleClass("hidden");
this._deleteButton.visible = false;
if (this._cookiesTable)
this._cookiesTable.element.addStyleClass("hidden");
return;
}

if (!this._cookiesTable) {
this._cookiesTable = isAdvanced ? new WebInspector.CookiesTable(this._cookieDomain, false, this._deleteCookie.bind(this)) : new WebInspector.SimpleCookiesTable();
this.element.appendChild(this._cookiesTable.element);
}

this._cookiesTable.setCookies(this._cookies);
this._cookiesTable.element.removeStyleClass("hidden");
this._emptyMsgElement.addStyleClass("hidden");
if (isAdvanced) {
this._treeElement.subtitle = String.sprintf(WebInspector.UIString("%d cookies (%s)"), this._cookies.length,
Number.bytesToString(this._totalSize, WebInspector.UIString));
this._deleteButton.visible = true;
}
},

_filterCookiesForDomain: function(allCookies)
{
var cookies = [];
var resourceURLsForDocumentURL = [];
this._totalSize = 0;

function populateResourcesForDocuments(resource)
{
var url = resource.documentURL.asParsedURL();
if (url && url.host == this._cookieDomain)
resourceURLsForDocumentURL.push(resource.url);
}
WebInspector.forAllResources(populateResourcesForDocuments.bind(this));

for (var i = 0; i < allCookies.length; ++i) {
var pushed = false;
var size = allCookies[i].size;
for (var j = 0; j < resourceURLsForDocumentURL.length; ++j) {
var resourceURL = resourceURLsForDocumentURL[j];
if (WebInspector.Cookies.cookieMatchesResourceURL(allCookies[i], resourceURL)) {
this._totalSize += size;
if (!pushed) {
pushed = true;
cookies.push(allCookies[i]);
}
}
}
}
return cookies;
},

_deleteCookie: function(cookie)
{
InspectorBackend.deleteCookie(cookie.name, this._cookieDomain);
this._update();
},

_deleteButtonClicked: function()
{
if (this._cookiesTable.selectedCookie)
this._deleteCookie(this._cookiesTable.selectedCookie);
},

_refreshButtonClicked: function(event)
{
this._update();
}
}

WebInspector.CookieItemsView.prototype.__proto__ = WebInspector.View.prototype;

WebInspector.SimpleCookiesTable = function()
{
this.element = document.createElement("div");
var columns = {};
columns[0] = {};
columns[1] = {};
columns[0].title = WebInspector.UIString("Name");
columns[1].title = WebInspector.UIString("Value");

this._dataGrid = new WebInspector.DataGrid(columns);
this._dataGrid.autoSizeColumns(20, 80);
this.element.appendChild(this._dataGrid.element);
this._dataGrid.updateWidths();
}

WebInspector.SimpleCookiesTable.prototype = {
setCookies: function(cookies)
{
this._dataGrid.removeChildren();
var addedCookies = {};
for (var i = 0; i < cookies.length; ++i) {
if (addedCookies[cookies[i].name])
continue;
addedCookies[cookies[i].name] = true;
var data = {};
data[0] = cookies[i].name;
data[1] = cookies[i].value;

var node = new WebInspector.DataGridNode(data, false);
node.selectable = true;
this._dataGrid.appendChild(node);
}
this._dataGrid.children[0].selected = true;
},

resize: function()
{
if (this._dataGrid)
this._dataGrid.updateWidths();
}
}





WebInspector.ApplicationCacheItemsView = function(treeElement, appcacheDomain)
{
WebInspector.View.call(this);

this.element.addStyleClass("storage-view");
this.element.addStyleClass("table");



this.deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item");
this.deleteButton.visible = false;
this.deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);



this.refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
this.refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);

if (Preferences.onlineDetectionEnabled) {
this.connectivityIcon = document.createElement("img");
this.connectivityIcon.className = "storage-application-cache-connectivity-icon";
this.connectivityIcon.src = "";
this.connectivityMessage = document.createElement("span");
this.connectivityMessage.className = "storage-application-cache-connectivity";
this.connectivityMessage.textContent = "";
}

this.divider = document.createElement("span");
this.divider.className = "status-bar-item status-bar-divider";

this.statusIcon = document.createElement("img");
this.statusIcon.className = "storage-application-cache-status-icon";
this.statusIcon.src = "";
this.statusMessage = document.createElement("span");
this.statusMessage.className = "storage-application-cache-status";
this.statusMessage.textContent = "";

this._treeElement = treeElement;
this._appcacheDomain = appcacheDomain;

this._emptyMsgElement = document.createElement("div");
this._emptyMsgElement.className = "storage-empty-view";
this._emptyMsgElement.textContent = WebInspector.UIString("No Application Cache information available.");
this.element.appendChild(this._emptyMsgElement);

this.updateStatus(applicationCache.UNCACHED);
}

WebInspector.ApplicationCacheItemsView.prototype = {
get statusBarItems()
{
if (Preferences.onlineDetectionEnabled) {
return [
this.refreshButton.element, this.deleteButton.element,
this.connectivityIcon, this.connectivityMessage, this.divider,
this.statusIcon, this.statusMessage
];
} else {
return [
this.refreshButton.element, this.deleteButton.element, this.divider,
this.statusIcon, this.statusMessage
];
}
},

show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);
this.updateNetworkState(navigator.onLine);
this._update();
},

hide: function()
{
WebInspector.View.prototype.hide.call(this);
this.deleteButton.visible = false;
},

updateStatus: function(status)
{
var statusInformation = {};
statusInformation[applicationCache.UNCACHED]    = { src: "Images/warningOrangeDot.png", text: "UNCACHED"    };
statusInformation[applicationCache.IDLE]        = { src: "Images/warningOrangeDot.png", text: "IDLE"        };
statusInformation[applicationCache.CHECKING]    = { src: "Images/successGreenDot.png",  text: "CHECKING"    };
statusInformation[applicationCache.DOWNLOADING] = { src: "Images/successGreenDot.png",  text: "DOWNLOADING" };
statusInformation[applicationCache.UPDATEREADY] = { src: "Images/successGreenDot.png",  text: "UPDATEREADY" };
statusInformation[applicationCache.OBSOLETE]    = { src: "Images/errorRedDot.png",      text: "OBSOLETE"    };

var info = statusInformation[status];
if (!info) {
console.error("Unknown Application Cache Status was Not Handled: %d", status);
return;
}

this.statusIcon.src = info.src;
this.statusMessage.textContent = info.text;
},

updateNetworkState: function(isNowOnline)
{
if (Preferences.onlineDetectionEnabled) {
if (isNowOnline) {
this.connectivityIcon.src = "Images/successGreenDot.png";
this.connectivityMessage.textContent = WebInspector.UIString("Online");
} else {
this.connectivityIcon.src = "Images/errorRedDot.png";
this.connectivityMessage.textContent = WebInspector.UIString("Offline");
}
}
},

_update: function()
{
WebInspector.ApplicationCache.getApplicationCachesAsync(this._updateCallback.bind(this));
},

_updateCallback: function(applicationCaches)
{


this._manifest = applicationCaches.manifest;
this._creationTime = applicationCaches.creationTime;
this._updateTime = applicationCaches.updateTime;
this._size = applicationCaches.size;
this._resources = applicationCaches.resources;
var lastPathComponent = applicationCaches.lastPathComponent;

if (!this._manifest) {
this._emptyMsgElement.removeStyleClass("hidden");
this.deleteButton.visible = false;
if (this._dataGrid)
this._dataGrid.element.addStyleClass("hidden");
return;
}

if (!this._dataGrid)
this._createDataGrid();

this._populateDataGrid();
this._dataGrid.autoSizeColumns(20, 80);
this._dataGrid.element.removeStyleClass("hidden");
this._emptyMsgElement.addStyleClass("hidden");
this.deleteButton.visible = true;

var totalSizeString = Number.bytesToString(this._size, WebInspector.UIString);
this._treeElement.subtitle = WebInspector.UIString("%s (%s)", lastPathComponent, totalSizeString);




},

_createDataGrid: function()
{
var columns = { 0: {}, 1: {}, 2: {} };
columns[0].title = WebInspector.UIString("Resource");
columns[0].sort = "ascending";
columns[0].sortable = true;
columns[1].title = WebInspector.UIString("Type");
columns[1].sortable = true;
columns[2].title = WebInspector.UIString("Size");
columns[2].aligned = "right";
columns[2].sortable = true;
this._dataGrid = new WebInspector.DataGrid(columns);
this.element.appendChild(this._dataGrid.element);
this._dataGrid.addEventListener("sorting changed", this._populateDataGrid, this);
this._dataGrid.updateWidths();
},

_populateDataGrid: function()
{
var selectedResource = this._dataGrid.selectedNode ? this._dataGrid.selectedNode.resource : null;
var sortDirection = this._dataGrid.sortOrder === "ascending" ? 1 : -1;

function numberCompare(field, resource1, resource2)
{
return sortDirection * (resource1[field] - resource2[field]);
}
function localeCompare(field, resource1, resource2)
{
return sortDirection * (resource1[field] + "").localeCompare(resource2[field] + "")
}

var comparator;
switch (parseInt(this._dataGrid.sortColumnIdentifier)) {
case 0: comparator = localeCompare.bind(this, "name"); break;
case 1: comparator = localeCompare.bind(this, "type"); break;
case 2: comparator = numberCompare.bind(this, "size"); break;
default: localeCompare.bind(this, "resource"); 
}

this._resources.sort(comparator);
this._dataGrid.removeChildren();

var nodeToSelect;
for (var i = 0; i < this._resources.length; ++i) {
var data = {};
var resource = this._resources[i];
data[0] = resource.name;
data[1] = resource.type;
data[2] = Number.bytesToString(resource.size, WebInspector.UIString);
var node = new WebInspector.DataGridNode(data);
node.resource = resource;
node.selectable = true;
this._dataGrid.appendChild(node);
if (resource === selectedResource) {
nodeToSelect = node;
nodeToSelect.selected = true;
}
}

if (!nodeToSelect)
this._dataGrid.children[0].selected = true;
},

resize: function()
{
if (this._dataGrid)
this._dataGrid.updateWidths();
},

_deleteButtonClicked: function(event)
{
if (!this._dataGrid || !this._dataGrid.selectedNode)
return;


this._deleteCallback(this._dataGrid.selectedNode);
},

_deleteCallback: function(node)
{



},

_refreshButtonClicked: function(event)
{


}
}

WebInspector.ApplicationCacheItemsView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.FileSystem = {}


WebInspector.FileSystem.TEMPORARY = 0;
WebInspector.FileSystem.PERSISTENT = 1;

WebInspector.FileSystem.getFileSystemPathsAsync = function(origin)
{
InspectorBackend.getFileSystemPathAsync(WebInspector.FileSystem.PERSISTENT, origin);
InspectorBackend.getFileSystemPathAsync(WebInspector.FileSystem.TEMPORARY, origin);
}

WebInspector.FileSystemView = function(treeElement, fileSystemOrigin)
{
WebInspector.View.call(this);

this.element.addStyleClass("resource-view");
this._treeElement = treeElement;
this._origin = fileSystemOrigin;
this._tabbedPane = new WebInspector.TabbedPane(this.element);

this._persistentFileSystemElement = document.createElement("div");
this._persistentFileSystemElement.className = "resource-view-headers";
this._tabbedPane.appendTab("persistent", WebInspector.UIString("Persistent File System"), this._persistentFileSystemElement, this._selectFileSystemTab.bind(this, true));

this._tempFileSystemElement = document.createElement("div");
this._tempFileSystemElement.className = "resource-view-headers";
this._tabbedPane.appendTab("temp", WebInspector.UIString("Temporary File System"), this._tempFileSystemElement, this.selectTemporaryFileSystemTab.bind(this, true));

this._temporaryRoot = "";
this._persistentRoot = "";
this._isFileSystemDisabled = false;
this._persistentRootError = false;
this._temporaryRootError = false;
this.fileSystemVisible = true;
this._selectFileSystemTab();
this.refreshFileSystem();
}

WebInspector.FileSystemView.prototype = {
show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);
this._update();
},

set fileSystemVisible(x)
{
if (x === this._fileSystemVisible)
return;
this._fileSystemVisible = x;
if (x)
this.element.addStyleClass("headers-visible");
else
this.element.removeStyleClass("headers-visible"); 
this._selectFileSystemTab();
},

_update: function()
{
this._selectFileSystemTab();
WebInspector.FileSystem.getFileSystemPathsAsync(this._origin);
},

updateFileSystemPath: function(root, type, origin)
{
if (origin == this._origin && type == WebInspector.FileSystem.PERSISTENT) {
this._persistentRoot = root;
this._persistentRootError = false;
}

if (origin == this._origin && type == WebInspector.FileSystem.TEMPORARY) {
this._temporaryRoot = root;
this._temporaryRootErrorError = false;
}

this.refreshFileSystem();
},

updateFileSystemError: function(type, origin)
{
if (type == WebInspector.FileSystem.PERSISTENT)
this._persistentRootError = true;

if (type == WebInspector.FileSystem.TEMPORARY)
this._temporaryRootError = true;

this.refreshFileSystem();
},

setFileSystemDisabled: function()
{
this._isFileSystemDisabled = true;
this.refreshFileSystem();
},
_selectFileSystemTab: function()
{
this._tabbedPane.selectTab("persistent");
},

selectTemporaryFileSystemTab: function()
{
this._tabbedPane.selectTab("temp");
},

_revealPersistentFolderInOS: function()
{
InspectorBackend.revealFolderInOS(this._persistentRoot);
},

_revealTemporaryFolderInOS: function()
{
InspectorBackend.revealFolderInOS(this._temporaryRoot);
},

_createTextAndButton: function(fileSystemElement, rootPathText, type, isError)
{
fileSystemElement.removeChildren();
var rootPath = WebInspector.UIString("File System root path not available.");
if (this._isFileSystemDisabled)
rootPath = WebInspector.UIString("File System is disabled.");
else if (isError)
rootPath = WebInspector.UIString("Error in fetching root path for file system.");
else if (rootPathText)
rootPath = rootPathText;

var rootTextNode = document.createTextNode("Root: " + rootPath.escapeHTML());
var rootSystemElement = document.createElement("div");
rootSystemElement.className = "header-value source-code";
rootSystemElement.appendChild(rootTextNode);
fileSystemElement.appendChild(rootSystemElement);

if (!isError && rootPathText) {

var contentElement = document.createElement("div");
contentElement.className = "panel-enabler-view-content";
fileSystemElement.appendChild(contentElement);
var choicesForm = document.createElement("form");
contentElement.appendChild(choicesForm);
var enableButton = document.createElement("button");
enableButton.setAttribute("type", "button");
enableButton.textContent = WebInspector.UIString("Reveal folder in OS");

if (type == WebInspector.FileSystem.PERSISTENT)
enableButton.addEventListener("click", this._revealPersistentFolderInOS.bind(this), false);
if (type == WebInspector.FileSystem.TEMPORARY)
enableButton.addEventListener("click", this._revealTemporaryFolderInOS.bind(this), false);
choicesForm.appendChild(enableButton);
fileSystemElement.appendChild(contentElement);
}
},

refreshFileSystem: function()
{
this._createTextAndButton(this._persistentFileSystemElement, this._persistentRoot, WebInspector.FileSystem.PERSISTENT, this._persistentRootError);
this._createTextAndButton(this._tempFileSystemElement, this._temporaryRoot, WebInspector.FileSystem.TEMPORARY, this._temporaryRootError);
}, 
}

WebInspector.FileSystemView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.Script = function(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, worldType)
{
this.sourceID = sourceID;
this.sourceURL = sourceURL;
this.source = source;
this.startingLine = startingLine;
this.errorLine = errorLine;
this.errorMessage = errorMessage;
this.worldType = worldType;





if (!sourceURL) {

var pattern = /^\s*\/\/[ \t]*@[ \t]*sourceURL[ \t]*=[ \t]*(\S+).*$/m;
var match = pattern.exec(source);

if (match)
this.sourceURL = match[1];
}
}

WebInspector.Script.WorldType = {
MAIN_WORLD: 0,
EXTENSIONS_WORLD: 1
}

WebInspector.Script.WorldType = {
MAIN_WORLD: 0,
EXTENSIONS_WORLD: 1
}

WebInspector.Script.prototype = {
get linesCount()
{
if (!this.source)
return 0;
if (this._linesCount)
return this._linesCount;
this._linesCount = 0;
var lastIndex = this.source.indexOf("\n");
while (lastIndex !== -1) {
lastIndex = this.source.indexOf("\n", lastIndex + 1)
this._linesCount++;
}
return this._linesCount;
}
}





WebInspector.BreakpointManager = function()
{
this._breakpoints = {};
this._nativeBreakpoints = {};
}

WebInspector.BreakpointManager.prototype = {
setOneTimeBreakpoint: function(sourceID, line)
{
var breakpoint = new WebInspector.Breakpoint(this, sourceID, undefined, line, true, undefined);
if (this._breakpoints[breakpoint.id])
return;
if (this._oneTimeBreakpoint)
InspectorBackend.removeBreakpoint(this._oneTimeBreakpoint.sourceID, this._oneTimeBreakpoint.line);
this._oneTimeBreakpoint = breakpoint;

this._setBreakpointOnBackend(breakpoint, true);
},

removeOneTimeBreakpoint: function()
{
if (this._oneTimeBreakpoint) {
InspectorBackend.removeBreakpoint(this._oneTimeBreakpoint.sourceID, this._oneTimeBreakpoint.line);
delete this._oneTimeBreakpoint;
}
},

setBreakpoint: function(sourceID, url, line, enabled, condition)
{
var breakpoint = this._setBreakpoint(sourceID, url, line, enabled, condition);
if (breakpoint)
this._setBreakpointOnBackend(breakpoint);
},

restoredBreakpoint: function(sourceID, url, line, enabled, condition)
{
this._setBreakpoint(sourceID, url, line, enabled, condition);
},

breakpointsForSourceID: function(sourceID)
{
var breakpoints = [];
for (var id in this._breakpoints) {
if (this._breakpoints[id].sourceID === sourceID)
breakpoints.push(this._breakpoints[id]);
}
return breakpoints;
},

breakpointsForURL: function(url)
{
var breakpoints = [];
for (var id in this._breakpoints) {
if (this._breakpoints[id].url === url)
breakpoints.push(this._breakpoints[id]);
}
return breakpoints;
},

reset: function()
{
this._breakpoints = {};
delete this._oneTimeBreakpoint;
this._nativeBreakpoints = {};
},

_setBreakpoint: function(sourceID, url, line, enabled, condition)
{
var breakpoint = new WebInspector.Breakpoint(this, sourceID, url, line, enabled, condition);
if (this._breakpoints[breakpoint.id])
return;
if (this._oneTimeBreakpoint && (this._oneTimeBreakpoint.id == breakpoint.id))
delete this._oneTimeBreakpoint;
this._breakpoints[breakpoint.id] = breakpoint;
breakpoint.addEventListener("removed", this._breakpointRemoved, this);
this.dispatchEventToListeners("breakpoint-added", breakpoint);
return breakpoint;
},

_breakpointRemoved: function(event)
{
delete this._breakpoints[event.target.id];
},

_setBreakpointOnBackend: function(breakpoint, isOneTime)
{
function didSetBreakpoint(success, line)
{
if (success && line == breakpoint.line)
return;
if (isOneTime) {
if (success)
this._oneTimeBreakpoint.line = line;
else
delete this._oneTimeBreakpoint;
} else {
breakpoint.remove();
if (success)
this._setBreakpoint(breakpoint.sourceID, breakpoint.url, line, breakpoint.enabled, breakpoint.condition);
}
}
InspectorBackend.setBreakpoint(breakpoint.sourceID, breakpoint.line, breakpoint.enabled, breakpoint.condition, didSetBreakpoint.bind(this));
},

createDOMBreakpoint: function(nodeId, domEventType, disabled)
{
var frontendId = "dom:" + nodeId + ":" + domEventType;
if (frontendId in this._nativeBreakpoints)
return;

var breakpoint = new WebInspector.DOMBreakpoint(this, frontendId, nodeId, domEventType);
this._nativeBreakpoints[frontendId] = breakpoint;
this.dispatchEventToListeners("dom-breakpoint-added", breakpoint);
breakpoint.enabled = !disabled;
return breakpoint;
},

createEventListenerBreakpoint: function(eventName)
{
var frontendId = eventName;
if (frontendId in this._nativeBreakpoints)
return;

var breakpoint = new WebInspector.EventListenerBreakpoint(this, frontendId, eventName);
this._nativeBreakpoints[frontendId] = breakpoint;
this.dispatchEventToListeners("event-listener-breakpoint-added", { breakpoint: breakpoint, eventName: eventName });
breakpoint.enabled = true;
return breakpoint;
},

createXHRBreakpoint: function(url, disabled)
{
var frontendId = url;
if (frontendId in this._nativeBreakpoints)
return;

var breakpoint = new WebInspector.XHRBreakpoint(this, frontendId, url);
this._nativeBreakpoints[frontendId] = breakpoint;
this.dispatchEventToListeners("xhr-breakpoint-added", breakpoint);
breakpoint.enabled = !disabled
return breakpoint;
},

_removeNativeBreakpoint: function(breakpoint)
{
if (breakpoint._beingSetOnBackend)
return;
if (breakpoint.enabled)
this._removeNativeBreakpointFromBackend(breakpoint);
delete this._nativeBreakpoints[breakpoint._frontendId];
this._updateNativeBreakpointsInSettings();
breakpoint.dispatchEventToListeners("removed");
},

_setNativeBreakpointEnabled: function(breakpoint, enabled)
{
if (breakpoint._beingSetOnBackend)
return;
if (breakpoint.enabled === enabled)
return;
if (enabled)
this._setNativeBreakpointOnBackend(breakpoint);
else
this._removeNativeBreakpointFromBackend(breakpoint);
},

_setNativeBreakpointOnBackend: function(breakpoint)
{
breakpoint._beingSetOnBackend = true;
var data = { type: breakpoint._type, condition: breakpoint._condition };
InspectorBackend.setNativeBreakpoint(data, didSetNativeBreakpoint.bind(this));

function didSetNativeBreakpoint(backendBreakpointId)
{
breakpoint._beingSetOnBackend = false;
if (backendBreakpointId !== "") {
breakpoint._backendId = backendBreakpointId;
this._breakpoints[backendBreakpointId] = breakpoint;
}
breakpoint.dispatchEventToListeners("enable-changed");
this._updateNativeBreakpointsInSettings();
}
},

_removeNativeBreakpointFromBackend: function(breakpoint)
{
InspectorBackend.removeNativeBreakpoint(breakpoint._backendId);
delete this._breakpoints[breakpoint._backendId]
delete breakpoint._backendId;
breakpoint.dispatchEventToListeners("enable-changed");
this._updateNativeBreakpointsInSettings();
},

_updateNativeBreakpointsInSettings: function()
{
var persistentBreakpoints = [];
for (var id in this._nativeBreakpoints) {
var breakpoint = this._nativeBreakpoints[id];
if (breakpoint._persistentCondition)
persistentBreakpoints.push({ type: breakpoint._type, enabled: breakpoint.enabled, condition: breakpoint._persistentCondition });
}
WebInspector.settings.nativeBreakpoints = persistentBreakpoints;
},

debuggerPaused: function(details)
{
if (details.eventType === WebInspector.DebuggerEventTypes.JavaScriptPause)
return;

if (details.eventData && details.eventData.breakpointId)
var breakpointId = details.eventData.breakpointId;
else if (details.callFrames && details.callFrames.length)
var breakpointId = WebInspector.Breakpoint.jsBreakpointId(details.callFrames[0].sourceID, details.callFrames[0].line);
else
return;

var breakpoint = this._breakpoints[breakpointId];
if (!breakpoint)
return;

breakpoint.hit = true;
breakpoint.dispatchEventToListeners("hit-state-changed");
this._lastHitBreakpoint = breakpoint;

this.dispatchEventToListeners("breakpoint-hit", { breakpoint: breakpoint, eventData: details.eventData });
},

debuggerResumed: function()
{
if (!this._lastHitBreakpoint)
return;
this._lastHitBreakpoint.hit = false;
this._lastHitBreakpoint.dispatchEventToListeners("hit-state-changed");
delete this._lastHitBreakpoint;
},

restoreBreakpoints: function()
{
var breakpoints = this._persistentBreakpoints();
for (var i = 0; i < breakpoints.length; ++i) {
if (breakpoints[i].type === "EventListener")
this.createEventListenerBreakpoint(breakpoints[i].condition.eventName);
else if (breakpoints[i].type === "XHR")
this.createXHRBreakpoint(breakpoints[i].condition.url, !breakpoints[i].enabled);
}
},

restoreDOMBreakpoints: function()
{
function didPushNodeByPathToFrontend(path, nodeId)
{
pathToNodeId[path] = nodeId;
pendingCalls -= 1;
if (pendingCalls)
return;
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
var nodeId = pathToNodeId[breakpoint.condition.path];
if (nodeId)
this.createDOMBreakpoint(nodeId, breakpoint.condition.type, !breakpoint.enabled);
}
}

var breakpoints = this._persistentBreakpoints();
var pathToNodeId = {};
var pendingCalls = 0;
for (var i = 0; i < breakpoints.length; ++i) {
if (breakpoints[i].type !== "DOM")
continue;
var path = breakpoints[i].condition.path;
if (path in pathToNodeId)
continue;
pathToNodeId[path] = 0;
pendingCalls += 1;
InspectorBackend.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
}
},

_persistentBreakpoints: function()
{
var result = [];
var breakpoints = WebInspector.settings.nativeBreakpoints;
if (breakpoints instanceof Array) {
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
if ("type" in breakpoint && "condition" in breakpoint)
result.push(breakpoint)
}
}
return result;
}
}

WebInspector.BreakpointManager.prototype.__proto__ = WebInspector.Object.prototype;

WebInspector.Breakpoint = function(breakpointManager, sourceID, url, line, enabled, condition)
{
this.url = url;
this.line = line;
this.sourceID = sourceID;
this._enabled = enabled;
this._condition = condition || "";
this._sourceText = "";
this._breakpointManager = breakpointManager;
}

WebInspector.Breakpoint.jsBreakpointId = function(sourceID, line)
{
return sourceID + ":" + line;
}

WebInspector.Breakpoint.prototype = {
get enabled()
{
return this._enabled;
},

set enabled(x)
{
if (this._enabled === x)
return;

this._enabled = x;
this._breakpointManager._setBreakpointOnBackend(this);
this.dispatchEventToListeners("enable-changed");
},

get sourceText()
{
return this._sourceText;
},

set sourceText(text)
{
this._sourceText = text;
this.dispatchEventToListeners("label-changed");
},

get id()
{
return WebInspector.Breakpoint.jsBreakpointId(this.sourceID, this.line);
},

get condition()
{
return this._condition;
},

set condition(c)
{
c = c || "";
if (this._condition === c)
return;

this._condition = c;
if (this.enabled)
this._breakpointManager._setBreakpointOnBackend(this);
this.dispatchEventToListeners("condition-changed");
},

click: function(event)
{
WebInspector.panels.scripts.showSourceLine(this.url, this.line);
},

compareTo: function(other)
{
if (this.url != other.url)
return this.url < other.url ? -1 : 1;
if (this.line != other.line)
return this.line < other.line ? -1 : 1;
return 0;
},

populateLabelElement: function(element)
{
var displayName = this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)");
var labelElement = document.createTextNode(displayName + ":" + this.line);
element.appendChild(labelElement);

var sourceTextElement = document.createElement("div");
sourceTextElement.textContent = this.sourceText;
sourceTextElement.className = "source-text monospace";
element.appendChild(sourceTextElement);
},

remove: function()
{
InspectorBackend.removeBreakpoint(this.sourceID, this.line);
this.dispatchEventToListeners("removed");
this.removeAllListeners();
delete this._breakpointManager;
}
}

WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype;

WebInspector.NativeBreakpoint = function(manager, frontendId, type)
{
this._manager = manager;
this.__frontendId = frontendId;
this.__type = type;
}

WebInspector.NativeBreakpoint.prototype = {
get enabled()
{
return "_backendId" in this;
},

set enabled(enabled)
{
this._manager._setNativeBreakpointEnabled(this, enabled);
},

remove: function()
{
this._manager._removeNativeBreakpoint(this);
this._onRemove();
},

get _frontendId()
{
return this.__frontendId;
},

get _type()
{
return this.__type;
},

_compare: function(x, y)
{
if (x !== y)
return x < y ? -1 : 1;
return 0;
},

_onRemove: function()
{
}
}

WebInspector.NativeBreakpoint.prototype.__proto__ = WebInspector.Object.prototype;

WebInspector.DOMBreakpoint = function(manager, frontendId, nodeId, domEventType)
{
WebInspector.NativeBreakpoint.call(this, manager, frontendId, "DOM");
this._nodeId = nodeId;
this._domEventType = domEventType;
this._condition = { nodeId: this._nodeId, type: this._domEventType };

var node = WebInspector.domAgent.nodeForId(this._nodeId);
if (node) {
node.breakpoints[this._domEventType] = this;
this._persistentCondition = { path: node.path(), type: this._domEventType };
}
}

WebInspector.DOMBreakpoint.prototype = {
compareTo: function(other)
{
return this._compare(this._domEventType, other._domEventType);
},

populateLabelElement: function(element)
{

var linkifiedNode = WebInspector.panels.elements.linkifyNodeById(this._nodeId);
linkifiedNode.addStyleClass("monospace");
element.appendChild(linkifiedNode);
var description = document.createElement("div");
description.className = "source-text";
description.textContent = WebInspector.domBreakpointTypeLabel(this._domEventType);
element.appendChild(description);
},

populateStatusMessageElement: function(element, eventData)
{
var substitutions = [WebInspector.domBreakpointTypeLabel(this._domEventType), WebInspector.panels.elements.linkifyNodeById(this._nodeId)];
var formatters = {
s: function(substitution)
{
return substitution;
}
};
function append(a, b)
{
if (typeof b === "string")
b = document.createTextNode(b);
element.appendChild(b);
}
if (this._domEventType === WebInspector.DOMBreakpointTypes.SubtreeModified) {
var targetNode = WebInspector.panels.elements.linkifyNodeById(eventData.targetNodeId);
if (eventData.insertion) {
if (eventData.targetNodeId !== this._nodeId)
WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.", substitutions.concat(targetNode), formatters, "", append);
else
WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.", substitutions, formatters, "", append);
} else
WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.", substitutions.concat(targetNode), formatters, "", append);
} else
WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s.", substitutions, formatters, "", append);
},

_onRemove: function()
{
var node = WebInspector.domAgent.nodeForId(this._nodeId);
if (node)
delete node.breakpoints[this._domEventType];
}
}

WebInspector.DOMBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype;

WebInspector.EventListenerBreakpoint = function(manager, frontendId, eventName)
{
WebInspector.NativeBreakpoint.call(this, manager, frontendId, "EventListener");
this._eventName = eventName;
this._condition = { eventName: this._eventName };
this._persistentCondition = this._condition;
}

WebInspector.EventListenerBreakpoint.eventNameForUI = function(eventName)
{
if (!WebInspector.EventListenerBreakpoint._eventNamesForUI) {
WebInspector.EventListenerBreakpoint._eventNamesForUI = {
"instrumentation:setTimer": WebInspector.UIString("Set Timer"),
"instrumentation:clearTimer": WebInspector.UIString("Clear Timer"),
"instrumentation:timerFired": WebInspector.UIString("Timer Fired")
};
}
return WebInspector.EventListenerBreakpoint._eventNamesForUI[eventName] || eventName.substring(eventName.indexOf(":") + 1);
}

WebInspector.EventListenerBreakpoint.prototype = {
compareTo: function(other)
{
return this._compare(this._eventName, other._eventName);
},

populateLabelElement: function(element)
{
element.appendChild(document.createTextNode(this._uiEventName()));
},

populateStatusMessageElement: function(element, eventData)
{
var status = WebInspector.UIString("Paused on a \"%s\" Event Listener.", this._uiEventName());
element.appendChild(document.createTextNode(status));
},

_uiEventName: function()
{
return WebInspector.EventListenerBreakpoint.eventNameForUI(this._eventName);
}
}

WebInspector.EventListenerBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype;

WebInspector.XHRBreakpoint = function(manager, frontendId, url)
{
WebInspector.NativeBreakpoint.call(this, manager, frontendId, "XHR");
this._url = url;
this._condition = { url: this._url };
this._persistentCondition = this._condition;
}

WebInspector.XHRBreakpoint.prototype = {
compareTo: function(other)
{
return this._compare(this._url, other._url);
},

populateEditElement: function(element)
{
element.textContent = this._url;
},

populateLabelElement: function(element)
{
var label;
if (!this._url.length)
label = WebInspector.UIString("Any XHR");
else
label = WebInspector.UIString("URL contains \"%s\"", this._url);
element.appendChild(document.createTextNode(label));
element.addStyleClass("cursor-auto");
},

populateStatusMessageElement: function(element)
{
var status = WebInspector.UIString("Paused on a XMLHttpRequest.");
element.appendChild(document.createTextNode(status));
}
}

WebInspector.XHRBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype;

WebInspector.DebuggerEventTypes = {
JavaScriptPause: 0,
JavaScriptBreakpoint: 1,
NativeBreakpoint: 2
};

WebInspector.DOMBreakpointTypes = {
SubtreeModified: 0,
AttributeModified: 1,
NodeRemoved: 2
};

WebInspector.domBreakpointTypeLabel = function(type)
{
if (!WebInspector._DOMBreakpointTypeLabels) {
WebInspector._DOMBreakpointTypeLabels = {};
WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified");
WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified");
WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed");
}
return WebInspector._DOMBreakpointTypeLabels[type];
}

WebInspector.domBreakpointTypeContextMenuLabel = function(type)
{
if (!WebInspector._DOMBreakpointTypeContextMenuLabels) {
WebInspector._DOMBreakpointTypeContextMenuLabels = {};
WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.SubtreeModified] = WebInspector.UIString("Break on Subtree Modifications");
WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.AttributeModified] = WebInspector.UIString("Break on Attributes Modifications");
WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.NodeRemoved] = WebInspector.UIString("Break on Node Removal");
}
return WebInspector._DOMBreakpointTypeContextMenuLabels[type];
}





WebInspector.SidebarPane = function(title)
{
this.element = document.createElement("div");
this.element.className = "pane";

this.titleElement = document.createElement("div");
this.titleElement.className = "title";
this.titleElement.tabIndex = 0;
this.titleElement.addEventListener("click", this.toggleExpanded.bind(this), false);
this.titleElement.addEventListener("keydown", this._onTitleKeyDown.bind(this), false);

this.bodyElement = document.createElement("div");
this.bodyElement.className = "body";

this.element.appendChild(this.titleElement);
this.element.appendChild(this.bodyElement);

this.title = title;
this.growbarVisible = false;
this.expanded = false;
}

WebInspector.SidebarPane.prototype = {
get title()
{
return this._title;
},

set title(x)
{
if (this._title === x)
return;
this._title = x;
this.titleElement.textContent = x;
},

get growbarVisible()
{
return this._growbarVisible;
},

set growbarVisible(x)
{
if (this._growbarVisible === x)
return;

this._growbarVisible = x;

if (x && !this._growbarElement) {
this._growbarElement = document.createElement("div");
this._growbarElement.className = "growbar";
this.element.appendChild(this._growbarElement);
} else if (!x && this._growbarElement) {
if (this._growbarElement.parentNode)
this._growbarElement.parentNode(this._growbarElement);
delete this._growbarElement;
}
},

get expanded()
{
return this._expanded;
},

set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},

expand: function()
{
if (this._expanded)
return;
this._expanded = true;
this.element.addStyleClass("expanded");
if (this.onexpand)
this.onexpand(this);
},

collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
this.element.removeStyleClass("expanded");
if (this.oncollapse)
this.oncollapse(this);
},

toggleExpanded: function()
{
this.expanded = !this.expanded;
},

_onTitleKeyDown: function(event)
{
if (isEnterKey(event) || event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
this.toggleExpanded();
}
}

WebInspector.SidebarPane.prototype.__proto__ = WebInspector.Object.prototype;





WebInspector.ElementsTreeOutline = function() {
this.element = document.createElement("ol");
this.element.addEventListener("mousedown", this._onmousedown.bind(this), false);
this.element.addEventListener("mousemove", this._onmousemove.bind(this), false);
this.element.addEventListener("mouseout", this._onmouseout.bind(this), false);

TreeOutline.call(this, this.element);

this.includeRootDOMNode = true;
this.selectEnabled = false;
this.showInElementsPanelEnabled = false;
this.rootDOMNode = null;
this.focusedDOMNode = null;

this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
}

WebInspector.ElementsTreeOutline.prototype = {
get rootDOMNode()
{
return this._rootDOMNode;
},

set rootDOMNode(x)
{
if (this._rootDOMNode === x)
return;

this._rootDOMNode = x;

this._isXMLMimeType = !!(WebInspector.mainResource && WebInspector.mainResource.mimeType && WebInspector.mainResource.mimeType.match(/x(?:ht)?ml/i));

this.update();
},

get isXMLMimeType()
{
return this._isXMLMimeType;
},

nodeNameToCorrectCase: function(nodeName)
{
return this.isXMLMimeType ? nodeName : nodeName.toLowerCase();
},

get focusedDOMNode()
{
return this._focusedDOMNode;
},

set focusedDOMNode(x)
{
if (this._focusedDOMNode === x) {
this.revealAndSelectNode(x);
return;
}

this._focusedDOMNode = x;

this.revealAndSelectNode(x);





if (this._focusedDOMNode === x)
this.focusedNodeChanged();
},

get editing()
{
return this._editing;
},

update: function()
{
var selectedNode = this.selectedTreeElement ? this.selectedTreeElement.representedObject : null;

this.removeChildren();

if (!this.rootDOMNode)
return;

var treeElement;
if (this.includeRootDOMNode) {
treeElement = new WebInspector.ElementsTreeElement(this.rootDOMNode);
treeElement.selectable = this.selectEnabled;
this.appendChild(treeElement);
} else {

var node = this.rootDOMNode.firstChild;
while (node) {
treeElement = new WebInspector.ElementsTreeElement(node);
treeElement.selectable = this.selectEnabled;
this.appendChild(treeElement);
node = node.nextSibling;
}
}

if (selectedNode)
this.revealAndSelectNode(selectedNode);
},

updateSelection: function()
{
if (!this.selectedTreeElement)
return;
var element = this.treeOutline.selectedTreeElement;
element.updateSelection();
},

focusedNodeChanged: function(forceUpdate) {},

findTreeElement: function(node)
{
var treeElement = TreeOutline.prototype.findTreeElement.call(this, node, isAncestorNode, parentNode);
if (!treeElement && node.nodeType === Node.TEXT_NODE) {

treeElement = TreeOutline.prototype.findTreeElement.call(this, node.parentNode, isAncestorNode, parentNode);
}

return treeElement;
},

createTreeElementFor: function(node)
{
var treeElement = this.findTreeElement(node);
if (treeElement)
return treeElement;
if (!node.parentNode)
return null;

var treeElement = this.createTreeElementFor(node.parentNode);
if (treeElement && treeElement.showChild(node.index))
return treeElement.children[node.index];

return null;
},

set suppressRevealAndSelect(x)
{
if (this._suppressRevealAndSelect === x)
return;
this._suppressRevealAndSelect = x;
},

revealAndSelectNode: function(node)
{
if (!node || this._suppressRevealAndSelect)
return;

var treeElement = this.createTreeElementFor(node);
if (!treeElement)
return;

treeElement.reveal();
treeElement.select();
},

_treeElementFromEvent: function(event)
{
var root = this.element;



var x = root.totalOffsetLeft + root.offsetWidth - 20;

var y = event.pageY;




var elementUnderMouse = this.treeElementFromPoint(x, y);
var elementAboveMouse = this.treeElementFromPoint(x, y - 2);
var element;
if (elementUnderMouse === elementAboveMouse)
element = elementUnderMouse;
else
element = this.treeElementFromPoint(x, y + 2);

return element;
},

_onmousedown: function(event)
{
var element = this._treeElementFromEvent(event);

if (!element || element.isEventWithinDisclosureTriangle(event))
return;

element.select();
},

_onmousemove: function(event)
{
var element = this._treeElementFromEvent(event);
if (element && this._previousHoveredElement === element)
return;

if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}

if (element) {
element.hovered = true;
this._previousHoveredElement = element;


if (element.representedObject && !element.tooltip)
element._createTooltipForNode();
}

WebInspector.highlightDOMNode(element ? element.representedObject.id : 0);
},

_onmouseout: function(event)
{
var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
if (nodeUnderMouse && nodeUnderMouse.isDescendant(this.element))
return;

if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}

WebInspector.highlightDOMNode(0);
},

_contextMenuEventFired: function(event)
{
var listItem = event.target.enclosingNodeOrSelfWithNodeName("LI");
if (!listItem || !listItem.treeElement)
return;

var contextMenu = new WebInspector.ContextMenu();
if (this.showInElementsPanelEnabled) {
function focusElement()
{
WebInspector.panels.elements.focusedDOMNode = listItem.treeElement.representedObject;
}
contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), focusElement.bind(this));
} else {
var href = event.target.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || event.target.enclosingNodeOrSelfWithClass("webkit-html-external-link");
var tag = event.target.enclosingNodeOrSelfWithClass("webkit-html-tag");
var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node");
var needSeparator;
if (href)
needSeparator = WebInspector.panels.elements.populateHrefContextMenu(contextMenu, event, href);
if (tag && listItem.treeElement._populateTagContextMenu) {
if (needSeparator)
contextMenu.appendSeparator();
listItem.treeElement._populateTagContextMenu(contextMenu, event);
} else if (textNode && listItem.treeElement._populateTextContextMenu) {
if (needSeparator)
contextMenu.appendSeparator();
listItem.treeElement._populateTextContextMenu(contextMenu, textNode);
}
}
contextMenu.show(event);
}
}

WebInspector.ElementsTreeOutline.prototype.__proto__ = TreeOutline.prototype;

WebInspector.ElementsTreeElement = function(node, elementCloseTag)
{
this._elementCloseTag = elementCloseTag;
var hasChildrenOverride = !elementCloseTag && node.hasChildNodes() && !this._showInlineText(node);


TreeElement.call(this, "", node, hasChildrenOverride);

if (this.representedObject.nodeType == Node.ELEMENT_NODE && !elementCloseTag)
this._canAddAttributes = true;
this._searchQuery = null;
this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildrenLimit;
}

WebInspector.ElementsTreeElement.InitialChildrenLimit = 500;




WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [
"area", "base", "basefont", "br", "canvas", "col", "command", "embed", "frame",
"hr", "img", "input", "isindex", "keygen", "link", "meta", "param", "source"
].keySet();


WebInspector.ElementsTreeElement.EditTagBlacklist = [
"html", "head", "body"
].keySet();

WebInspector.ElementsTreeElement.prototype = {
highlightSearchResults: function(searchQuery)
{
if (this._searchQuery === searchQuery)
return;

this._searchQuery = searchQuery;
this.updateTitle();
},

get hovered()
{
return this._hovered;
},

set hovered(x)
{
if (this._hovered === x)
return;

this._hovered = x;

if (this.listItemElement) {
if (x) {
this.updateSelection();
this.listItemElement.addStyleClass("hovered");
} else {
this.listItemElement.removeStyleClass("hovered");
}
}
},

get expandedChildrenLimit()
{
return this._expandedChildrenLimit;
},

set expandedChildrenLimit(x)
{
if (this._expandedChildrenLimit === x)
return;

this._expandedChildrenLimit = x;
if (this.treeOutline && !this._updateChildrenInProgress)
this._updateChildren(true);
},

get expandedChildCount()
{
var count = this.children.length;
if (count && this.children[count - 1]._elementCloseTag)
count--;
if (count && this.children[count - 1].expandAllButton)
count--;
return count;
},

showChild: function(index)
{
if (this._elementCloseTag)
return;

if (index >= this.expandedChildrenLimit) {
this._expandedChildrenLimit = index + 1;
this._updateChildren(true);
}


return this.expandedChildCount > index;
},

_createTooltipForNode: function()
{
var node = this.representedObject;
if (!node.nodeName || node.nodeName.toLowerCase() !== "img")
return;

function setTooltip(properties)
{
if (!properties)
return;

if (properties.offsetHeight === properties.naturalHeight && properties.offsetWidth === properties.naturalWidth)
this.tooltip = WebInspector.UIString("%d × %d pixels", properties.offsetWidth, properties.offsetHeight);
else
this.tooltip = WebInspector.UIString("%d × %d pixels (Natural: %d × %d pixels)", properties.offsetWidth, properties.offsetHeight, properties.naturalWidth, properties.naturalHeight);
}

InjectedScriptAccess.getForNode(node).getNodeProperties(node.id, ["naturalHeight", "naturalWidth", "offsetHeight", "offsetWidth"], setTooltip.bind(this));
},

updateSelection: function()
{
var listItemElement = this.listItemElement;
if (!listItemElement)
return;

if (document.body.offsetWidth <= 0) {


return;
}

if (!this.selectionElement) {
this.selectionElement = document.createElement("div");
this.selectionElement.className = "selection selected";
listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild);
}

this.selectionElement.style.height = listItemElement.offsetHeight + "px";
},

onattach: function()
{
if (this._hovered) {
this.updateSelection();
this.listItemElement.addStyleClass("hovered");
}

this.updateTitle();

this._preventFollowingLinksOnDoubleClick();
},

_preventFollowingLinksOnDoubleClick: function()
{
var links = this.listItemElement.querySelectorAll("li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-external-link, li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-resource-link");
if (!links)
return;

for (var i = 0; i < links.length; ++i)
links[i].preventFollowOnDoubleClick = true;
},

onpopulate: function()
{
if (this.children.length || this._showInlineText(this.representedObject) || this._elementCloseTag)
return;

this.updateChildren();
},

updateChildren: function(fullRefresh)
{
if (this._elementCloseTag)
return;

WebInspector.domAgent.getChildNodesAsync(this.representedObject, this._updateChildren.bind(this, fullRefresh));
},

insertChildElement: function(child, index, closingTag)
{
var newElement = new WebInspector.ElementsTreeElement(child, closingTag);
newElement.selectable = this.treeOutline.selectEnabled;
this.insertChild(newElement, index);
return newElement;
},

moveChild: function(child, targetIndex)
{
var wasSelected = child.selected;
this.removeChild(child);
this.insertChild(child, targetIndex);
if (wasSelected)
child.select();
},

_updateChildren: function(fullRefresh)
{
if (this._updateChildrenInProgress)
return;

this._updateChildrenInProgress = true;
var focusedNode = this.treeOutline.focusedDOMNode;
var originalScrollTop;
if (fullRefresh) {
var treeOutlineContainerElement = this.treeOutline.element.parentNode;
originalScrollTop = treeOutlineContainerElement.scrollTop;
var selectedTreeElement = this.treeOutline.selectedTreeElement;
if (selectedTreeElement && selectedTreeElement.hasAncestor(this))
this.select();
this.removeChildren();
}

var treeElement = this;
var treeChildIndex = 0;
var elementToSelect;

function updateChildrenOfNode(node)
{
var treeOutline = treeElement.treeOutline;
var child = node.firstChild;
while (child) {
var currentTreeElement = treeElement.children[treeChildIndex];
if (!currentTreeElement || currentTreeElement.representedObject !== child) {

var existingTreeElement = null;
for (var i = (treeChildIndex + 1), size = treeElement.expandedChildCount; i < size; ++i) {
if (treeElement.children[i].representedObject === child) {
existingTreeElement = treeElement.children[i];
break;
}
}

if (existingTreeElement && existingTreeElement.parent === treeElement) {

treeElement.moveChild(existingTreeElement, treeChildIndex);
} else {

if (treeChildIndex < treeElement.expandedChildrenLimit) {
var newElement = treeElement.insertChildElement(child, treeChildIndex);
if (child === focusedNode)
elementToSelect = newElement;
if (treeElement.expandedChildCount > treeElement.expandedChildrenLimit)
treeElement.expandedChildrenLimit++;
}
}
}

child = child.nextSibling;
++treeChildIndex;
}
}


for (var i = (this.children.length - 1); i >= 0; --i) {
var currentChild = this.children[i];
var currentNode = currentChild.representedObject;
var currentParentNode = currentNode.parentNode;

if (currentParentNode === this.representedObject)
continue;

var selectedTreeElement = this.treeOutline.selectedTreeElement;
if (selectedTreeElement && (selectedTreeElement === currentChild || selectedTreeElement.hasAncestor(currentChild)))
this.select();

this.removeChildAtIndex(i);
}

updateChildrenOfNode(this.representedObject);
this.adjustCollapsedRange(false);

var lastChild = this.children[this.children.length - 1];
if (this.representedObject.nodeType == Node.ELEMENT_NODE && (!lastChild || !lastChild._elementCloseTag))
this.insertChildElement(this.representedObject, this.children.length, true);


if (fullRefresh && elementToSelect) {
elementToSelect.select();
if (treeOutlineContainerElement && originalScrollTop <= treeOutlineContainerElement.scrollHeight)
treeOutlineContainerElement.scrollTop = originalScrollTop;
}

delete this._updateChildrenInProgress;
},

adjustCollapsedRange: function()
{


if (this.expandAllButtonElement && this.expandAllButtonElement.__treeElement.parent)
this.removeChild(this.expandAllButtonElement.__treeElement);

const node = this.representedObject;
if (!node.children)
return;
const childNodeCount = node.children.length;


for (var i = this.expandedChildCount, limit = Math.min(this.expandedChildrenLimit, childNodeCount); i < limit; ++i)
this.insertChildElement(node.children[i], i);

const expandedChildCount = this.expandedChildCount;
if (childNodeCount > this.expandedChildCount) {
var targetButtonIndex = expandedChildCount;
if (!this.expandAllButtonElement) {
var item = new TreeElement(null, null, false);
item.titleHTML = "<button class=\"show-all-nodes\" value=\"\" />";
item.selectable = false;
item.expandAllButton = true;
this.insertChild(item, targetButtonIndex);
this.expandAllButtonElement = item.listItemElement.firstChild;
this.expandAllButtonElement.__treeElement = item;
this.expandAllButtonElement.addEventListener("click", this.handleLoadAllChildren.bind(this), false);
} else if (!this.expandAllButtonElement.__treeElement.parent)
this.insertChild(this.expandAllButtonElement.__treeElement, targetButtonIndex);
this.expandAllButtonElement.textContent = WebInspector.UIString("Show All Nodes (%d More)", childNodeCount - expandedChildCount);
} else if (this.expandAllButtonElement)
delete this.expandAllButtonElement;
},

handleLoadAllChildren: function()
{
this.expandedChildrenLimit = Math.max(this.representedObject._childNodeCount, this.expandedChildrenLimit + WebInspector.ElementsTreeElement.InitialChildrenLimit);
},

onexpand: function()
{
if (this._elementCloseTag)
return;

this.updateTitle();
this.treeOutline.updateSelection();
},

oncollapse: function()
{
if (this._elementCloseTag)
return;

this.updateTitle();
this.treeOutline.updateSelection();
},

onreveal: function()
{
if (this.listItemElement)
this.listItemElement.scrollIntoViewIfNeeded(false);
},

onselect: function(treeElement, selectedByUser)
{
this.treeOutline.suppressRevealAndSelect = true;
this.treeOutline.focusedDOMNode = this.representedObject;
if (selectedByUser)
WebInspector.highlightDOMNode(this.representedObject.id);
this.updateSelection();
this.treeOutline.suppressRevealAndSelect = false;
},

ondelete: function()
{
var startTagTreeElement = this.treeOutline.findTreeElement(this.representedObject);
startTagTreeElement ? startTagTreeElement.remove() : this.remove();
return true;
},

onenter: function()
{


if (this.treeOutline.editing)
return false;

this._startEditing();


return true;
},

selectOnMouseDown: function(event)
{
TreeElement.prototype.selectOnMouseDown.call(this, event);

if (this._editing)
return;

if (this.treeOutline.showInElementsPanelEnabled) {
WebInspector.showPanel("elements");
WebInspector.panels.elements.focusedDOMNode = this.representedObject;
}


if (event.detail >= 2)
event.preventDefault();
},

ondblclick: function(event)
{
if (this._editing || this._elementCloseTag)
return;

if (this._startEditingTarget(event.target))
return;

if (this.hasChildren && !this.expanded)
this.expand();
},

_insertInLastAttributePosition: function(tag, node)
{
if (tag.getElementsByClassName("webkit-html-attribute").length > 0)
tag.insertBefore(node, tag.lastChild);
else {
var nodeName = tag.textContent.match(/^<(.*?)>$/)[1];
tag.textContent = '';
tag.appendChild(document.createTextNode('<'+nodeName));
tag.appendChild(node);
tag.appendChild(document.createTextNode('>'));
}

this.updateSelection();
},

_startEditingTarget: function(eventTarget)
{
if (this.treeOutline.focusedDOMNode != this.representedObject)
return;

if (this.representedObject.nodeType != Node.ELEMENT_NODE && this.representedObject.nodeType != Node.TEXT_NODE)
return false;

var textNode = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (textNode)
return this._startEditingTextNode(textNode);

var attribute = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-attribute");
if (attribute)
return this._startEditingAttribute(attribute, eventTarget);

var tagName = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-tag-name");
if (tagName)
return this._startEditingTagName(tagName);

var newAttribute = eventTarget.enclosingNodeOrSelfWithClass("add-attribute");
if (newAttribute)
return this._addNewAttribute();

return false;
},

_populateTagContextMenu: function(contextMenu, event)
{
var attribute = event.target.enclosingNodeOrSelfWithClass("webkit-html-attribute");
var newAttribute = event.target.enclosingNodeOrSelfWithClass("add-attribute");


contextMenu.appendItem(WebInspector.UIString("Add Attribute"), this._addNewAttribute.bind(this));
if (attribute && !newAttribute)
contextMenu.appendItem(WebInspector.UIString("Edit Attribute"), this._startEditingAttribute.bind(this, attribute, event.target));
contextMenu.appendSeparator();


contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Delete Node"), this.remove.bind(this));

if (Preferences.nativeInstrumentationEnabled) {

contextMenu.appendSeparator();

function handlerFunction(nodeId, breakType)
{
WebInspector.breakpointManager.createDOMBreakpoint(nodeId, breakType);
WebInspector.panels.elements.sidebarPanes.domBreakpoints.expand();
}
var node = this.representedObject;
for (var key in WebInspector.DOMBreakpointTypes) {
var type = WebInspector.DOMBreakpointTypes[key];
var label = WebInspector.domBreakpointTypeContextMenuLabel(type);
var breakpoint = node.breakpoints[type];
if (!breakpoint)
var handler = handlerFunction.bind(this, node.id, type);
else
var handler = breakpoint.remove.bind(breakpoint);
contextMenu.appendCheckboxItem(label, handler, !!breakpoint);
}
}
},

_populateTextContextMenu: function(contextMenu, textNode)
{
contextMenu.appendItem(WebInspector.UIString("Edit Text"), this._startEditingTextNode.bind(this, textNode));
},

_startEditing: function()
{
if (this.treeOutline.focusedDOMNode !== this.representedObject)
return;

var listItem = this._listItemNode;

if (this._canAddAttributes) {
var attribute = listItem.getElementsByClassName("webkit-html-attribute")[0];
if (attribute)
return this._startEditingAttribute(attribute, attribute.getElementsByClassName("webkit-html-attribute-value")[0]);

return this._addNewAttribute();
}

if (this.representedObject.nodeType === Node.TEXT_NODE) {
var textNode = listItem.getElementsByClassName("webkit-html-text-node")[0];
if (textNode)
return this._startEditingTextNode(textNode);
return;
}
},

_addNewAttribute: function()
{


var container = document.createElement("span");
container.innerHTML = this._attributeHTML(" ", "");
var attr = container.firstChild;
attr.style.marginLeft = "2px"; 
attr.style.marginRight = "2px"; 

var tag = this.listItemElement.getElementsByClassName("webkit-html-tag")[0];
this._insertInLastAttributePosition(tag, attr);
return this._startEditingAttribute(attr, attr);
},

_triggerEditAttribute: function(attributeName)
{
var attributeElements = this.listItemElement.getElementsByClassName("webkit-html-attribute-name");
for (var i = 0, len = attributeElements.length; i < len; ++i) {
if (attributeElements[i].textContent === attributeName) {
for (var elem = attributeElements[i].nextSibling; elem; elem = elem.nextSibling) {
if (elem.nodeType !== Node.ELEMENT_NODE)
continue;

if (elem.hasStyleClass("webkit-html-attribute-value"))
return this._startEditingAttribute(elem.parentNode, elem);
}
}
}
},

_startEditingAttribute: function(attribute, elementForSelection)
{
if (WebInspector.isBeingEdited(attribute))
return true;

var attributeNameElement = attribute.getElementsByClassName("webkit-html-attribute-name")[0];
if (!attributeNameElement)
return false;

var attributeName = attributeNameElement.innerText;

function removeZeroWidthSpaceRecursive(node)
{
if (node.nodeType === Node.TEXT_NODE) {
node.nodeValue = node.nodeValue.replace(/\u200B/g, "");
return;
}

if (node.nodeType !== Node.ELEMENT_NODE)
return;

for (var child = node.firstChild; child; child = child.nextSibling)
removeZeroWidthSpaceRecursive(child);
}


removeZeroWidthSpaceRecursive(attribute);

this._editing = WebInspector.startEditing(attribute, this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);
window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1);

return true;
},

_startEditingTextNode: function(textNode)
{
if (WebInspector.isBeingEdited(textNode))
return true;

this._editing = WebInspector.startEditing(textNode, this._textNodeEditingCommitted.bind(this), this._editingCancelled.bind(this));
window.getSelection().setBaseAndExtent(textNode, 0, textNode, 1);

return true;
},

_startEditingTagName: function(tagNameElement)
{
if (!tagNameElement) {
tagNameElement = this.listItemElement.getElementsByClassName("webkit-html-tag-name")[0];
if (!tagNameElement)
return false;
}

var tagName = tagNameElement.textContent;
if (WebInspector.ElementsTreeElement.EditTagBlacklist[tagName.toLowerCase()])
return false;

if (WebInspector.isBeingEdited(tagNameElement))
return true;

var closingTagElement = this._distinctClosingTagElement();

function keyupListener(event)
{
if (closingTagElement)
closingTagElement.textContent = "</" + tagNameElement.textContent + ">";
}

function editingComitted(element, newTagName)
{
tagNameElement.removeEventListener('keyup', keyupListener, false);
this._tagNameEditingCommitted.apply(this, arguments);
}

function editingCancelled()
{
tagNameElement.removeEventListener('keyup', keyupListener, false);
this._editingCancelled.apply(this, arguments);
}

tagNameElement.addEventListener('keyup', keyupListener, false);

this._editing = WebInspector.startEditing(tagNameElement, editingComitted.bind(this), editingCancelled.bind(this), tagName);
window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1);
return true;
},

_startEditingAsHTML: function(commitCallback, initialValue)
{
if (this._htmlEditElement && WebInspector.isBeingEdited(this._htmlEditElement))
return true;

this._htmlEditElement = document.createElement("div");
this._htmlEditElement.className = "source-code elements-tree-editor";
this._htmlEditElement.textContent = initialValue;


var child = this.listItemElement.firstChild;
while (child) {
child.style.display = "none";
child = child.nextSibling;
}

if (this._childrenListNode)
this._childrenListNode.style.display = "none";

this.listItemElement.appendChild(this._htmlEditElement);

this.updateSelection();

function commit()
{
commitCallback(this._htmlEditElement.textContent);
dispose.call(this);
}

function dispose()
{
delete this._editing;


this.listItemElement.removeChild(this._htmlEditElement);
delete this._htmlEditElement;

if (this._childrenListNode)
this._childrenListNode.style.removeProperty("display");

var child = this.listItemElement.firstChild;
while (child) {
child.style.removeProperty("display");
child = child.nextSibling;
}

this.updateSelection();
}

this._editing = WebInspector.startEditing(this._htmlEditElement, commit.bind(this), dispose.bind(this), null, true);
},

_attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection)
{
delete this._editing;



var moveToAttribute, moveToTagName, moveToNewAttribute;
if (moveDirection) {
var found = false;


var attributes = this.representedObject.attributes;
for (var i = 0; i < attributes.length; ++i) {
if (attributes[i].name === attributeName) {
found = true;
if (moveDirection === "backward") {
if (i === 0)
moveToTagName = true;
else
moveToAttribute = attributes[i - 1].name;
} else if (moveDirection === "forward") {
if (i === attributes.length - 1)
moveToNewAttribute = true;
else
moveToAttribute = attributes[i + 1].name;
}
}
}


if (!found) {
if (moveDirection === "backward" && attributes.length > 0)
moveToAttribute = attributes[attributes.length - 1].name;
else if (moveDirection === "forward" && !/^\s*$/.test(newText))
moveToNewAttribute = true;
}
}

function moveToNextAttributeIfNeeded()
{

if (element.textContent.trim().length === 0)
element.parentNode.removeChild(element);


if (moveToAttribute)
this._triggerEditAttribute(moveToAttribute);
else if (moveToNewAttribute)
this._addNewAttribute();
else if (moveToTagName)
this._startEditingTagName();
}

function regenerateStyledAttribute(name, value)
{
var previous = element.previousSibling;
if (!previous || previous.nodeType !== Node.TEXT_NODE)
element.parentNode.insertBefore(document.createTextNode(" "), element);
element.outerHTML = this._attributeHTML(name, value);
}

var parseContainerElement = document.createElement("span");
parseContainerElement.innerHTML = "<span " + newText + "></span>";
var parseElement = parseContainerElement.firstChild;

if (!parseElement) {
this._editingCancelled(element, attributeName);
moveToNextAttributeIfNeeded.call(this);
return;
}

if (!parseElement.hasAttributes()) {
this.representedObject.removeAttribute(attributeName);
moveToNextAttributeIfNeeded.call(this);
return;
}

var foundOriginalAttribute = false;
for (var i = 0; i < parseElement.attributes.length; ++i) {
var attr = parseElement.attributes[i];
foundOriginalAttribute = foundOriginalAttribute || attr.name === attributeName;
try {
this.representedObject.setAttribute(attr.name, attr.value);
regenerateStyledAttribute.call(this, attr.name, attr.value);
} catch(e) {} 
}

if (!foundOriginalAttribute)
this.representedObject.removeAttribute(attributeName);

this.treeOutline.focusedNodeChanged(true);

moveToNextAttributeIfNeeded.call(this);
},

_tagNameEditingCommitted: function(element, newText, oldText, tagName, moveDirection)
{
delete this._editing;
var self = this;

function cancel()
{
var closingTagElement = self._distinctClosingTagElement();
if (closingTagElement)
closingTagElement.textContent = "</" + tagName + ">";

self._editingCancelled(element, tagName);
moveToNextAttributeIfNeeded.call(self);
}

function moveToNextAttributeIfNeeded()
{
if (moveDirection !== "forward")
return;

var attributes = this.representedObject.attributes;
if (attributes.length > 0)
this._triggerEditAttribute(attributes[0].name);
else
this._addNewAttribute();
}

newText = newText.trim();
if (newText === oldText) {
cancel();
return;
}

var treeOutline = this.treeOutline;
var wasExpanded = this.expanded;

function changeTagNameCallback(nodeId)
{
if (!nodeId) {
cancel();
return;
}


WebInspector.panels.elements.updateModifiedNodes();

WebInspector.updateFocusedNode(nodeId);
var newTreeItem = treeOutline.findTreeElement(WebInspector.domAgent.nodeForId(nodeId));
if (wasExpanded)
newTreeItem.expand();

moveToNextAttributeIfNeeded.call(newTreeItem);
}

InspectorBackend.changeTagName(this.representedObject.id, newText, changeTagNameCallback);
},

_textNodeEditingCommitted: function(element, newText)
{
delete this._editing;

var textNode;
if (this.representedObject.nodeType === Node.ELEMENT_NODE) {


textNode = this.representedObject.firstChild;
} else if (this.representedObject.nodeType == Node.TEXT_NODE)
textNode = this.representedObject;

textNode.nodeValue = newText;
},

_editingCancelled: function(element, context)
{
delete this._editing;


this.updateTitle();
},

_distinctClosingTagElement: function()
{




if (this.expanded) {
var closers = this._childrenListNode.querySelectorAll(".close");
return closers[closers.length-1];
}




var tags = this.listItemElement.getElementsByClassName("webkit-html-tag");
return (tags.length === 1 ? null : tags[tags.length-1]);
},

updateTitle: function()
{


if (this._editing)
return;

this.titleHTML = "<span class=\"highlight\">" + this._nodeTitleInfo(WebInspector.linkifyURL).titleHTML + "</span>";
delete this.selectionElement;
this.updateSelection();
this._preventFollowingLinksOnDoubleClick();
this._highlightSearchResults();
},

_attributeHTML: function(name, value, node, linkify)
{
var hasText = (value.length > 0);
var html = "<span class=\"webkit-html-attribute\"><span class=\"webkit-html-attribute-name\">" + name.escapeHTML() + "</span>";

if (hasText)
html += "=&#8203;\"";

if (linkify && (name === "src" || name === "href")) {
var rewrittenHref = WebInspector.resourceURLForRelatedNode(node, value);
value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
html += linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName.toLowerCase() === "a");
} else {
value = value.escapeHTML().replace(/([\/;:\)\]\}])/g, "$1&#8203;");
html += "<span class=\"webkit-html-attribute-value\">" + value + "</span>";
}

if (hasText)
html += "\"";

html += "</span>";
return html;
},

_tagHTML: function(tagName, isClosingTag, isDistinctTreeElement, linkify)
{
var node = this.representedObject;
var result = "<span class=\"webkit-html-tag" + (isClosingTag && isDistinctTreeElement ? " close" : "")  + "\">&lt;";
result += "<span " + (isClosingTag ? "" : "class=\"webkit-html-tag-name\"") + ">" + (isClosingTag ? "/" : "") + tagName + "</span>";
if (!isClosingTag && node.hasAttributes()) {
for (var i = 0; i < node.attributes.length; ++i) {
var attr = node.attributes[i];
result += " " + this._attributeHTML(attr.name, attr.value, node, linkify);
}
}
result += "&gt;</span>&#8203;";

return result;
},

_nodeTitleInfo: function(linkify)
{
var node = this.representedObject;
var info = {titleHTML: "", hasChildren: this.hasChildren};

switch (node.nodeType) {
case Node.DOCUMENT_NODE:
info.titleHTML = "Document";
break;

case Node.DOCUMENT_FRAGMENT_NODE:
info.titleHTML = "Document Fragment";
break;

case Node.ATTRIBUTE_NODE:
var value = node.value || "\u200B"; 
info.titleHTML = this._attributeHTML(node.name, value);
break;

case Node.ELEMENT_NODE:
var tagName = this.treeOutline.nodeNameToCorrectCase(node.nodeName).escapeHTML();
if (this._elementCloseTag) {
info.titleHTML = this._tagHTML(tagName, true, true);
info.hasChildren = false;
break;
}

var titleHTML = this._tagHTML(tagName, false, false, linkify);

var textChild = onlyTextChild.call(node);
var showInlineText = textChild && textChild.textContent.length < Preferences.maxInlineTextChildLength;

if (!this.expanded && (!showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]))) {
if (this.hasChildren)
titleHTML += "<span class=\"webkit-html-text-node\">&#8230;</span>&#8203;";
titleHTML += this._tagHTML(tagName, true, false);
}




if (showInlineText) {
titleHTML += "<span class=\"webkit-html-text-node\">" + textChild.nodeValue.escapeHTML() + "</span>&#8203;" + this._tagHTML(tagName, true, false);
info.hasChildren = false;
}
info.titleHTML = titleHTML;
break;

case Node.TEXT_NODE:
if (isNodeWhitespace.call(node))
info.titleHTML = "(whitespace)";
else {
if (node.parentNode && node.parentNode.nodeName.toLowerCase() === "script") {
var newNode = document.createElement("span");
newNode.textContent = node.textContent;

var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript");
javascriptSyntaxHighlighter.syntaxHighlightNode(newNode);

info.titleHTML = "<span class=\"webkit-html-text-node webkit-html-js-node\">" + newNode.innerHTML.replace(/^[\n\r]*/, "").replace(/\s*$/, "") + "</span>";
} else if (node.parentNode && node.parentNode.nodeName.toLowerCase() === "style") {
var newNode = document.createElement("span");
newNode.textContent = node.textContent;

var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/css");
cssSyntaxHighlighter.syntaxHighlightNode(newNode);

info.titleHTML = "<span class=\"webkit-html-text-node webkit-html-css-node\">" + newNode.innerHTML.replace(/^[\n\r]*/, "").replace(/\s*$/, "") + "</span>";
} else
info.titleHTML = "\"<span class=\"webkit-html-text-node\">" + node.nodeValue.escapeHTML() + "</span>\"";
}
break;

case Node.COMMENT_NODE:
info.titleHTML = "<span class=\"webkit-html-comment\">&lt;!--" + node.nodeValue.escapeHTML() + "--&gt;</span>";
break;

case Node.DOCUMENT_TYPE_NODE:
var titleHTML = "<span class=\"webkit-html-doctype\">&lt;!DOCTYPE " + node.nodeName;
if (node.publicId) {
titleHTML += " PUBLIC \"" + node.publicId + "\"";
if (node.systemId)
titleHTML += " \"" + node.systemId + "\"";
} else if (node.systemId)
titleHTML += " SYSTEM \"" + node.systemId + "\"";
if (node.internalSubset)
titleHTML += " [" + node.internalSubset + "]";
titleHTML += "&gt;</span>";
info.titleHTML = titleHTML;
break;

case Node.CDATA_SECTION_NODE:
info.titleHTML = "<span class=\"webkit-html-text-node\">&lt;![CDATA[" + node.nodeValue.escapeHTML() + "]]&gt;</span>";
break;
default:
info.titleHTML = this.treeOutline.nodeNameToCorrectCase(node.nodeName).collapseWhitespace().escapeHTML();
}

return info;
},

_showInlineText: function(node)
{
if (node.nodeType === Node.ELEMENT_NODE) {
var textChild = onlyTextChild.call(node);
if (textChild && textChild.textContent.length < Preferences.maxInlineTextChildLength)
return true;
}
return false;
},

remove: function()
{
var parentElement = this.parent;
if (!parentElement)
return;

var self = this;
function removeNodeCallback(removedNodeId)
{


if (removedNodeId === -1)
return;

parentElement.removeChild(self);
parentElement.adjustCollapsedRange(true);
}

InspectorBackend.removeNode(this.representedObject.id, removeNodeCallback);
},

_editAsHTML: function()
{
var treeOutline = this.treeOutline;
var node = this.representedObject;
var wasExpanded = this.expanded;

function selectNode(nodeId)
{
if (!nodeId)
return;


WebInspector.panels.elements.updateModifiedNodes();

WebInspector.updateFocusedNode(nodeId);
if (wasExpanded) {
var newTreeItem = treeOutline.findTreeElement(WebInspector.domAgent.nodeForId(nodeId));
if (newTreeItem)
newTreeItem.expand();
}
}

function commitChange(value)
{
InspectorBackend.setOuterHTML(node.id, value, selectNode);
}

InspectorBackend.getOuterHTML(node.id, this._startEditingAsHTML.bind(this, commitChange));
},

_copyHTML: function()
{
InspectorBackend.copyNode(this.representedObject.id);
},

_highlightSearchResults: function()
{
if (!this._searchQuery)
return;
var text = this.listItemElement.textContent;
var regexObject = createSearchRegex(this._searchQuery);

var offset = 0;
var match = regexObject.exec(text);
while (match) {
highlightSearchResult(this.listItemElement, offset + match.index, match[0].length);
offset += match.index + 1;
text = text.substring(match.index + 1);
match = regexObject.exec(text);
}
}
}

WebInspector.ElementsTreeElement.prototype.__proto__ = TreeElement.prototype;





WebInspector.SidebarSectionTreeElement = function(title, representedObject, hasChildren)
{
TreeElement.call(this, title.escapeHTML(), representedObject || {}, hasChildren);
}

WebInspector.SidebarSectionTreeElement.prototype = {
selectable: false,

get smallChildren()
{
return this._smallChildren;
},

set smallChildren(x)
{
if (this._smallChildren === x)
return;

this._smallChildren = x;

if (this._smallChildren)
this._childrenListNode.addStyleClass("small");
else
this._childrenListNode.removeStyleClass("small");
},

onattach: function()
{
this._listItemNode.addStyleClass("sidebar-tree-section");
},

onreveal: function()
{
if (this.listItemElement)
this.listItemElement.scrollIntoViewIfNeeded(false);
}
}

WebInspector.SidebarSectionTreeElement.prototype.__proto__ = TreeElement.prototype;

WebInspector.SidebarTreeElement = function(className, title, subtitle, representedObject, hasChildren)
{
TreeElement.call(this, "", representedObject || {}, hasChildren);

if (hasChildren) {
this.disclosureButton = document.createElement("button");
this.disclosureButton.className = "disclosure-button";
}

if (!this.iconElement) {
this.iconElement = document.createElement("img");
this.iconElement.className = "icon";
}

this.statusElement = document.createElement("div");
this.statusElement.className = "status";

this.titlesElement = document.createElement("div");
this.titlesElement.className = "titles";

this.titleElement = document.createElement("span");
this.titleElement.className = "title";
this.titlesElement.appendChild(this.titleElement);

this.subtitleElement = document.createElement("span");
this.subtitleElement.className = "subtitle";
this.titlesElement.appendChild(this.subtitleElement);

this.className = className;
this.mainTitle = title;
this.subtitle = subtitle;
}

WebInspector.SidebarTreeElement.prototype = {
get small()
{
return this._small;
},

set small(x)
{
this._small = x;

if (this._listItemNode) {
if (this._small)
this._listItemNode.addStyleClass("small");
else
this._listItemNode.removeStyleClass("small");
}
},

get mainTitle()
{
return this._mainTitle;
},

set mainTitle(x)
{
this._mainTitle = x;
this.refreshTitles();
},

get subtitle()
{
return this._subtitle;
},

set subtitle(x)
{
this._subtitle = x;
this.refreshTitles();
},

get bubbleText()
{
return this._bubbleText;
},

set bubbleText(x)
{
if (!this.bubbleElement) {
this.bubbleElement = document.createElement("div");
this.bubbleElement.className = "bubble";
this.statusElement.appendChild(this.bubbleElement);
}

this._bubbleText = x;
this.bubbleElement.textContent = x;
},

refreshTitles: function()
{
var mainTitle = this.mainTitle;
if (this.titleElement.textContent !== mainTitle)
this.titleElement.textContent = mainTitle;

var subtitle = this.subtitle;
if (subtitle) {
if (this.subtitleElement.textContent !== subtitle)
this.subtitleElement.textContent = subtitle;
this.titlesElement.removeStyleClass("no-subtitle");
} else
this.titlesElement.addStyleClass("no-subtitle");
},

isEventWithinDisclosureTriangle: function(event)
{
return event.target === this.disclosureButton;
},

onattach: function()
{
this._listItemNode.addStyleClass("sidebar-tree-item");

if (this.className)
this._listItemNode.addStyleClass(this.className);

if (this.small)
this._listItemNode.addStyleClass("small");

if (this.hasChildren && this.disclosureButton)
this._listItemNode.appendChild(this.disclosureButton);

this._listItemNode.appendChild(this.iconElement);
this._listItemNode.appendChild(this.statusElement);
this._listItemNode.appendChild(this.titlesElement);
},

onreveal: function()
{
if (this._listItemNode)
this._listItemNode.scrollIntoViewIfNeeded(false);
}
}

WebInspector.SidebarTreeElement.prototype.__proto__ = TreeElement.prototype;





WebInspector.Section = function(title, subtitle)
{
this.element = document.createElement("div");
this.element.className = "section";
this.element.sectionForTest = this;

this.headerElement = document.createElement("div");
this.headerElement.className = "header";

this.titleElement = document.createElement("div");
this.titleElement.className = "title";

this.subtitleElement = document.createElement("div");
this.subtitleElement.className = "subtitle";

this.headerElement.appendChild(this.subtitleElement);
this.headerElement.appendChild(this.titleElement);

this.headerElement.addEventListener("click", this.toggleExpanded.bind(this), false);
this.element.appendChild(this.headerElement);

this.title = title;
this.subtitle = subtitle;
this._expanded = false;
}

WebInspector.Section.prototype = {
get title()
{
return this._title;
},

set title(x)
{
if (this._title === x)
return;
this._title = x;

if (x instanceof Node) {
this.titleElement.removeChildren();
this.titleElement.appendChild(x);
} else
this.titleElement.textContent = x;
},

get subtitle()
{
return this._subtitle;
},

set subtitle(x)
{
if (this._subtitle === x)
return;
this._subtitle = x;
this.subtitleElement.textContent = x;
},

get subtitleAsTextForTest()

{

var result = this.subtitleElement.textContent;

var child = this.subtitleElement.querySelector("[data-uncopyable]");

if (child) {

var linkData = child.getAttribute("data-uncopyable");

if (linkData)

result += linkData;

}

return result;
},

get expanded()
{
return this._expanded;
},

set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},

get populated()
{
return this._populated;
},

set populated(x)
{
this._populated = x;
if (!x && this.onpopulate && this._expanded) {
this.onpopulate(this);
this._populated = true;
}
},

expand: function()
{
if (this._expanded)
return;
this._expanded = true;
this.element.addStyleClass("expanded");

if (!this._populated && this.onpopulate) {
this.onpopulate(this);
this._populated = true;
}
},

collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
this.element.removeStyleClass("expanded");
},

toggleExpanded: function()
{
this.expanded = !this.expanded;
}
}





WebInspector.PropertiesSection = function(title, subtitle)
{
WebInspector.Section.call(this, title, subtitle);

this.headerElement.addStyleClass("monospace");
this.propertiesElement = document.createElement("ol");
this.propertiesElement.className = "properties properties-tree monospace";
this.propertiesElement.tabIndex = 0;
this.propertiesTreeOutline = new TreeOutline(this.propertiesElement);
this.propertiesTreeOutline.section = this;

this.element.appendChild(this.propertiesElement);
}

WebInspector.PropertiesSection.prototype.__proto__ = WebInspector.Section.prototype;





WebInspector.RemoteObject = function(objectId, type, description, hasChildren)
{
this._objectId = objectId;
this._type = type;
this._description = description;
this._hasChildren = hasChildren;
}

WebInspector.RemoteObject.fromPrimitiveValue = function(value)
{
return new WebInspector.RemoteObject(null, typeof value, value);
}

WebInspector.RemoteObject.fromLocalObject = function(value)
{
return new WebInspector.LocalJSONObject(value);
}

WebInspector.RemoteObject.resolveNode = function(node, callback)
{
function mycallback(object)
{
callback(object ? WebInspector.RemoteObject.fromPayload(object) : null);
}
InjectedScriptAccess.getForNode(node).resolveNode(node.id, mycallback);
}

WebInspector.RemoteObject.fromPayload = function(payload)
{
if (typeof payload === "object")
return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.description, payload.hasChildren);

return payload;
}

WebInspector.RemoteObject.type = function(remoteObject)
{
if (remoteObject === null)
return "null";

var type = typeof remoteObject;
if (type !== "object" && type !== "function")
return type;

return remoteObject.type;
}

WebInspector.RemoteObject.prototype = {
get objectId()
{
return this._objectId;
},

get type()
{
return this._type;
},

get description()
{
return this._description;
},

get hasChildren()
{
return this._hasChildren;
},

isError: function()
{
return this._type === "error";
},

getOwnProperties: function(abbreviate, callback)
{
this.getProperties(false, abbreviate, callback);
},

getProperties: function(ignoreHasOwnProperty, abbreviate, callback)
{
if (!this._objectId) {
callback([]);
return;
}
function remoteObjectBinder(properties)
{
for (var i = 0; properties && i < properties.length; ++i)
properties[i].value = WebInspector.RemoteObject.fromPayload(properties[i].value);
callback(properties);
}
InjectedScriptAccess.getForObjectId(this._objectId).getProperties(this._objectId, ignoreHasOwnProperty, abbreviate, remoteObjectBinder);
},

setPropertyValue: function(name, value, callback)
{
if (!this._objectId) {
callback(false);
return;
}
InjectedScriptAccess.getForObjectId(this._objectId).setPropertyValue(this._objectId, name, value, callback);
},

pushNodeToFrontend: function(callback)
{
InjectedScriptAccess.getForObjectId(this._objectId).pushNodeToFrontend(this._objectId, callback);
}
}

WebInspector.RemoteObjectProperty = function(name, value)
{
this.name = name;
this.value = value;
}







WebInspector.LocalJSONObject = function(value)
{
this._value = value;
}

WebInspector.LocalJSONObject.prototype = {
get description()
{
var type = this.type;
switch (type) {
case "array":
return "[" + this._value.length + "]";
case "object":
return this.hasChildren ? "{...}" : "{ }";
default:
return JSON.stringify(this._value);
}
},

get type()
{
if (this._value === null)
return "null";
if (this._value instanceof Array)
return "array";
return typeof this._value;
},

get hasChildren()
{
return typeof this._value === "object" && this._value !== null && Object.keys(this._value).length;
},

getOwnProperties: function(abbreviate, callback)
{
return this.getProperties(false, abbreviate, callback);
},

getProperties: function(ignoreHasOwnProperty, abbreviate, callback)
{
function buildProperty(propName)
{
return new WebInspector.RemoteObjectProperty(propName, new WebInspector.LocalJSONObject(this._value[propName]));
}
callback(Object.keys(this._value).map(buildProperty.bind(this)));
},

isError: function()
{
return false;
}
}





WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor)
{
this.emptyPlaceholder = (emptyPlaceholder || WebInspector.UIString("No Properties"));
this.object = object;
this.ignoreHasOwnProperty = ignoreHasOwnProperty;
this.extraProperties = extraProperties;
this.treeElementConstructor = treeElementConstructor || WebInspector.ObjectPropertyTreeElement;
this.editable = true;

WebInspector.PropertiesSection.call(this, title, subtitle);
}

WebInspector.ObjectPropertiesSection.prototype = {
onpopulate: function()
{
this.update();
},

update: function()
{
var self = this;
var callback = function(properties) {
if (!properties)
return;
self.updateProperties(properties);
};
this.object.getProperties(this.ignoreHasOwnProperty, true, callback);
},

updateProperties: function(properties, rootTreeElementConstructor, rootPropertyComparer)
{
if (!rootTreeElementConstructor)
rootTreeElementConstructor = this.treeElementConstructor;

if (!rootPropertyComparer)
rootPropertyComparer = WebInspector.ObjectPropertiesSection.CompareProperties;

if (this.extraProperties)
for (var i = 0; i < this.extraProperties.length; ++i)
properties.push(this.extraProperties[i]);

properties.sort(rootPropertyComparer);

this.propertiesTreeOutline.removeChildren();

for (var i = 0; i < properties.length; ++i) {
properties[i].parentObject = this.object;
this.propertiesTreeOutline.appendChild(new rootTreeElementConstructor(properties[i]));
}

if (!this.propertiesTreeOutline.children.length) {
var title = "<div class=\"info\">" + this.emptyPlaceholder + "</div>";
var infoElement = new TreeElement(null, null, false);
infoElement.titleHTML = title;
this.propertiesTreeOutline.appendChild(infoElement);
}
this.propertiesForTest = properties;
}
}

WebInspector.ObjectPropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;

WebInspector.ObjectPropertiesSection.CompareProperties = function(propertyA, propertyB) 
{
var a = propertyA.name;
var b = propertyB.name;
if (a === "__proto__")
return 1;
if (b === "__proto__")
return -1;





var diff = 0;
var chunk = /^\d+|^\D+/;
var chunka, chunkb, anum, bnum;
while (diff === 0) {
if (!a && b)
return -1;
if (!b && a)
return 1;
chunka = a.match(chunk)[0];
chunkb = b.match(chunk)[0];
anum = !isNaN(chunka);
bnum = !isNaN(chunkb);
if (anum && !bnum)
return -1;
if (bnum && !anum)
return 1;
if (anum && bnum) {
diff = chunka - chunkb;
if (diff === 0 && chunka.length !== chunkb.length) {
if (!+chunka && !+chunkb) 
return chunka.length - chunkb.length;
else
return chunkb.length - chunka.length;
}
} else if (chunka !== chunkb)
return (chunka < chunkb) ? -1 : 1;
a = a.substring(chunka.length);
b = b.substring(chunkb.length);
}
return diff;
}

WebInspector.ObjectPropertyTreeElement = function(property)
{
this.property = property;


TreeElement.call(this, "", null, false);
}

WebInspector.ObjectPropertyTreeElement.prototype = {
onpopulate: function()
{
if (this.children.length && !this.shouldRefreshChildren)
return;

var callback = function(properties) {
this.removeChildren();
if (!properties)
return;

properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
this.appendChild(new this.treeOutline.section.treeElementConstructor(properties[i]));
}
};
this.property.value.getOwnProperties(true, callback.bind(this));
},

ondblclick: function(event)
{
this.startEditing();
},

onattach: function()
{
this.update();
},

update: function()
{
this.nameElement = document.createElement("span");
this.nameElement.className = "name";
this.nameElement.textContent = this.property.name;

var separatorElement = document.createElement("span");
separatorElement.className = "separator";
separatorElement.textContent = ": ";

this.valueElement = document.createElement("span");
this.valueElement.className = "value";
this.valueElement.textContent = this.property.value.description;
if (this.property.isGetter)
this.valueElement.addStyleClass("dimmed");
if (this.property.value.isError())
this.valueElement.addStyleClass("error");
if (this.property.value.type)
this.valueElement.addStyleClass("console-formatted-" + this.property.value.type);
if (this.property.value.type === "node")
this.valueElement.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);

this.listItemElement.removeChildren();

this.listItemElement.appendChild(this.nameElement);
this.listItemElement.appendChild(separatorElement);
this.listItemElement.appendChild(this.valueElement);
this.hasChildren = this.property.value.hasChildren;
},

_contextMenuEventFired: function()
{
function selectNode(nodeId)
{
if (nodeId)
WebInspector.panels.elements.focusedDOMNode = WebInspector.domAgent.nodeForId(nodeId);
}

function revealElement()
{
this.property.value.pushNodeToFrontend(selectNode);
}

var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), revealElement.bind(this));
contextMenu.show(event);
},

updateSiblings: function()
{
if (this.parent.root)
this.treeOutline.section.update();
else
this.parent.shouldRefreshChildren = true;
},

startEditing: function()
{
if (WebInspector.isBeingEdited(this.valueElement) || !this.treeOutline.section.editable)
return;

var context = { expanded: this.expanded };


this.hasChildren = false;

this.listItemElement.addStyleClass("editing-sub-part");

WebInspector.startEditing(this.valueElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
},

editingEnded: function(context)
{
this.listItemElement.scrollLeft = 0;
this.listItemElement.removeStyleClass("editing-sub-part");
if (context.expanded)
this.expand();
},

editingCancelled: function(element, context)
{
this.update();
this.editingEnded(context);
},

editingCommitted: function(element, userInput, previousContent, context)
{
if (userInput === previousContent)
return this.editingCancelled(element, context); 

this.applyExpression(userInput, true);

this.editingEnded(context);
},

applyExpression: function(expression, updateInterface)
{
expression = expression.trim();
var expressionLength = expression.length;
var self = this;
var callback = function(success) {
if (!updateInterface)
return;

if (!success)
self.update();

if (!expressionLength) {

self.parent.removeChild(this);
} else {

self.updateSiblings();
}
};
this.property.parentObject.setPropertyValue(this.property.name, expression.trim(), callback);
}
}

WebInspector.ObjectPropertyTreeElement.prototype.__proto__ = TreeElement.prototype;





WebInspector.BreakpointsSidebarPane = function(title)
{
WebInspector.SidebarPane.call(this, title);

this.listElement = document.createElement("ol");
this.listElement.className = "breakpoint-list";

this.emptyElement = document.createElement("div");
this.emptyElement.className = "info";
this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");

this.bodyElement.appendChild(this.emptyElement);
}

WebInspector.BreakpointsSidebarPane.prototype = {
reset: function()
{
this.listElement.removeChildren();
if (this.listElement.parentElement) {
this.bodyElement.removeChild(this.listElement);
this.bodyElement.appendChild(this.emptyElement);
}
},

addBreakpointItem: function(breakpointItem)
{
var element = breakpointItem.element;
element._breakpointItem = breakpointItem;

breakpointItem.addEventListener("breakpoint-hit", this.expand, this);
breakpointItem.addEventListener("removed", this._removeListElement.bind(this, element), this);

var currentElement = this.listElement.firstChild;
while (currentElement) {
if (currentElement._breakpointItem && currentElement._breakpointItem.compareTo(element._breakpointItem) > 0)
break;
currentElement = currentElement.nextSibling;
}
this._addListElement(element, currentElement);

if (breakpointItem.click) {
element.addStyleClass("cursor-pointer");
element.addEventListener("click", breakpointItem.click.bind(breakpointItem), false);
}
element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointItem), true);
},

_contextMenuEventFired: function(breakpointItem, event)
{
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpointItem.remove.bind(breakpointItem));
contextMenu.show(event);
},

_addListElement: function(element, beforeElement)
{
if (beforeElement)
this.listElement.insertBefore(element, beforeElement);
else {
if (!this.listElement.firstChild) {
this.bodyElement.removeChild(this.emptyElement);
this.bodyElement.appendChild(this.listElement);
}
this.listElement.appendChild(element);
}
},

_removeListElement: function(element)
{
this.listElement.removeChild(element);
if (!this.listElement.firstChild) {
this.bodyElement.removeChild(this.listElement);
this.bodyElement.appendChild(this.emptyElement);
}
}
}

WebInspector.BreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;

WebInspector.XHRBreakpointsSidebarPane = function()
{
WebInspector.BreakpointsSidebarPane.call(this, WebInspector.UIString("XHR Breakpoints"));

function addButtonClicked(event)
{
event.stopPropagation();
this._startEditingBreakpoint(null);
}

var addButton = document.createElement("button");
addButton.className = "add";
addButton.addEventListener("click", addButtonClicked.bind(this), false);
this.titleElement.appendChild(addButton);
}

WebInspector.XHRBreakpointsSidebarPane.prototype = {
addBreakpointItem: function(breakpointItem)
{
WebInspector.BreakpointsSidebarPane.prototype.addBreakpointItem.call(this, breakpointItem);
breakpointItem._labelElement.addEventListener("dblclick", this._startEditingBreakpoint.bind(this, breakpointItem), false);
},

_startEditingBreakpoint: function(breakpointItem)
{
if (this._editingBreakpoint)
return;
this._editingBreakpoint = true;

if (!this.expanded)
this.expanded = true;

var inputElement = document.createElement("span");
inputElement.className = "breakpoint-condition editing";
if (breakpointItem) {
breakpointItem.populateEditElement(inputElement);
this.listElement.insertBefore(inputElement, breakpointItem.element);
breakpointItem.element.addStyleClass("hidden");
} else
this._addListElement(inputElement, this.listElement.firstChild);

var commitHandler = this._hideEditBreakpointDialog.bind(this, inputElement, true, breakpointItem);
var cancelHandler = this._hideEditBreakpointDialog.bind(this, inputElement, false, breakpointItem);
WebInspector.startEditing(inputElement, commitHandler, cancelHandler);
},

_hideEditBreakpointDialog: function(inputElement, accept, breakpointItem)
{
this._removeListElement(inputElement);
this._editingBreakpoint = false;
if (accept) {
if (breakpointItem)
breakpointItem.remove();
WebInspector.breakpointManager.createXHRBreakpoint(inputElement.textContent.toLowerCase());
} else if (breakpointItem)
breakpointItem.element.removeStyleClass("hidden");
}
}

WebInspector.XHRBreakpointsSidebarPane.prototype.__proto__ = WebInspector.BreakpointsSidebarPane.prototype;

WebInspector.BreakpointItem = function(breakpoint)
{
this._breakpoint = breakpoint;

this._element = document.createElement("li");

var checkboxElement = document.createElement("input");
checkboxElement.className = "checkbox-elem";
checkboxElement.type = "checkbox";
checkboxElement.checked = this._breakpoint.enabled;
checkboxElement.addEventListener("click", this._checkboxClicked.bind(this), false);
this._element.appendChild(checkboxElement);

this._createLabelElement();

this._breakpoint.addEventListener("enable-changed", this._enableChanged, this);
this._breakpoint.addEventListener("hit-state-changed", this._hitStateChanged, this);
this._breakpoint.addEventListener("label-changed", this._labelChanged, this);
this._breakpoint.addEventListener("removed", this.dispatchEventToListeners.bind(this, "removed"));
if (breakpoint.click)
this.click = breakpoint.click.bind(breakpoint);
}

WebInspector.BreakpointItem.prototype = {
get element()
{
return this._element;
},

compareTo: function(other)
{
return this._breakpoint.compareTo(other._breakpoint);
},

populateEditElement: function(element)
{
this._breakpoint.populateEditElement(element);
},

remove: function()
{
this._breakpoint.remove();
},

_checkboxClicked: function(event)
{
this._breakpoint.enabled = !this._breakpoint.enabled;


event.stopPropagation();
},

_enableChanged: function(event)
{
var checkbox = this._element.firstChild;
checkbox.checked = this._breakpoint.enabled;
},

_hitStateChanged: function(event)
{
if (event.target.hit) {
this._element.addStyleClass("breakpoint-hit");
this.dispatchEventToListeners("breakpoint-hit");
} else
this._element.removeStyleClass("breakpoint-hit");
},

_labelChanged: function(event)
{
this._element.removeChild(this._labelElement);
this._createLabelElement();
},

_createLabelElement: function()
{
this._labelElement = document.createElement("span");
this._breakpoint.populateLabelElement(this._labelElement);
this._element.appendChild(this._labelElement);
}
}

WebInspector.BreakpointItem.prototype.__proto__ = WebInspector.Object.prototype;

WebInspector.EventListenerBreakpointsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listener Breakpoints"));

this.categoriesElement = document.createElement("ol");
this.categoriesElement.tabIndex = 0;
this.categoriesElement.addStyleClass("properties-tree event-listener-breakpoints");
this.categoriesTreeOutline = new TreeOutline(this.categoriesElement);
this.bodyElement.appendChild(this.categoriesElement);

WebInspector.breakpointManager.addEventListener("event-listener-breakpoint-added", this._breakpointAdded, this);

this._breakpointItems = {};
this._createCategory("Keyboard", "listener", ["keydown", "keyup", "keypress", "textInput"]);
this._createCategory("Mouse", "listener", ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mousewheel"]);



this._createCategory("Control", "listener", ["resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset"]);
this._createCategory("Clipboard", "listener", ["copy", "cut", "paste", "beforecopy", "beforecut", "beforepaste"]);
this._createCategory("Load", "listener", ["load", "unload", "abort", "error"]);
this._createCategory("DOM Mutation", "listener", ["DOMActivate", "DOMFocusIn", "DOMFocusOut", "DOMAttrModified", "DOMCharacterDataModified", "DOMNodeInserted", "DOMNodeInsertedIntoDocument", "DOMNodeRemoved", "DOMNodeRemovedFromDocument", "DOMSubtreeModified", "DOMContentLoaded"]);
this._createCategory("Device", "listener", ["deviceorientation", "devicemotion"]);
this._createCategory("Timer", "instrumentation", ["setTimer", "clearTimer", "timerFired"]);
}

WebInspector.EventListenerBreakpointsSidebarPane.prototype = {
_createCategory: function(name, type, eventNames)
{
var categoryItem = {};
categoryItem.element = new TreeElement(WebInspector.UIString(name));
this.categoriesTreeOutline.appendChild(categoryItem.element);
categoryItem.element.listItemElement.addStyleClass("event-category");
categoryItem.element.selectable = true;

categoryItem.checkbox = this._createCheckbox(categoryItem.element);
categoryItem.checkbox.addEventListener("click", this._categoryCheckboxClicked.bind(this, categoryItem), true);

categoryItem.children = {};
for (var i = 0; i < eventNames.length; ++i) {
var eventName = type + ":" + eventNames[i];

var breakpointItem = {};
var title = WebInspector.EventListenerBreakpoint.eventNameForUI(eventName);
breakpointItem.element = new TreeElement(title);
categoryItem.element.appendChild(breakpointItem.element);
var hitMarker = document.createElement("div");
hitMarker.className = "breakpoint-hit-marker";
breakpointItem.element.listItemElement.appendChild(hitMarker);
breakpointItem.element.listItemElement.addStyleClass("source-code");
breakpointItem.element.selectable = true;

breakpointItem.checkbox = this._createCheckbox(breakpointItem.element);
breakpointItem.checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, breakpointItem), true);
breakpointItem.parent = categoryItem;
breakpointItem.eventName = eventName;

this._breakpointItems[eventName] = breakpointItem;
categoryItem.children[eventName] = breakpointItem;
}
},

_createCheckbox: function(treeElement)
{
var checkbox = document.createElement("input");
checkbox.className = "checkbox-elem";
checkbox.type = "checkbox";
treeElement.listItemElement.insertBefore(checkbox, treeElement.listItemElement.firstChild);
return checkbox;
},

_categoryCheckboxClicked: function(categoryItem)
{
var checked = categoryItem.checkbox.checked;
for (var eventName in categoryItem.children) {
var breakpointItem = categoryItem.children[eventName];
if (breakpointItem.checkbox.checked !== checked) {
breakpointItem.checkbox.checked = checked;
this._breakpointCheckboxClicked(breakpointItem);
}
}
},

_breakpointCheckboxClicked: function(breakpointItem)
{
if (breakpointItem.checkbox.checked)
WebInspector.breakpointManager.createEventListenerBreakpoint(breakpointItem.eventName);
else
breakpointItem.breakpoint.remove();
},

_breakpointAdded: function(event)
{
var breakpoint = event.data.breakpoint;
var eventName = event.data.eventName;

var breakpointItem = this._breakpointItems[eventName];
breakpointItem.breakpoint = breakpoint;
breakpoint.addEventListener("hit-state-changed", this._breakpointHitStateChanged.bind(this, breakpointItem));
breakpoint.addEventListener("removed", this._breakpointRemoved.bind(this, breakpointItem));
breakpointItem.checkbox.checked = true;
this._updateCategoryCheckbox(breakpointItem);
},

_breakpointHitStateChanged: function(breakpointItem, event)
{
if (event.target.hit) {
this.expanded = true;
var categoryItem = breakpointItem.parent;
categoryItem.element.expand();
breakpointItem.element.listItemElement.addStyleClass("breakpoint-hit");
} else
breakpointItem.element.listItemElement.removeStyleClass("breakpoint-hit");
},

_breakpointRemoved: function(breakpointItem)
{
breakpointItem.breakpoint = null;
breakpointItem.checkbox.checked = false;
this._updateCategoryCheckbox(breakpointItem);
},

_updateCategoryCheckbox: function(breakpointItem)
{
var categoryItem = breakpointItem.parent;
var hasEnabled = false, hasDisabled = false;
for (var eventName in categoryItem.children) {
var breakpointItem = categoryItem.children[eventName];
if (breakpointItem.checkbox.checked)
hasEnabled = true;
else
hasDisabled = true;
}
categoryItem.checkbox.checked = hasEnabled;
categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled;
},

reset: function()
{
for (var eventName in this._breakpointItems) {
var breakpointItem = this._breakpointItems[eventName];
breakpointItem.breakpoint = null;
breakpointItem.checkbox.checked = false;
this._updateCategoryCheckbox(breakpointItem);
}
}
}

WebInspector.EventListenerBreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;





WebInspector.CallStackSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Call Stack"));
WebInspector.breakpointManager.addEventListener("breakpoint-hit", this._breakpointHit, this);
}

WebInspector.CallStackSidebarPane.prototype = {
update: function(callFrames, sourceIDMap)
{
this.bodyElement.removeChildren();

this.placards = [];
delete this._selectedCallFrame;

if (!callFrames) {
var infoElement = document.createElement("div");
infoElement.className = "info";
infoElement.textContent = WebInspector.UIString("Not Paused");
this.bodyElement.appendChild(infoElement);
return;
}

var title;
var subtitle;
var scriptOrResource;

for (var i = 0; i < callFrames.length; ++i) {
var callFrame = callFrames[i];
switch (callFrame.type) {
case "function":
title = callFrame.functionName || WebInspector.UIString("(anonymous function)");
break;
case "program":
title = WebInspector.UIString("(program)");
break;
}

scriptOrResource = sourceIDMap[callFrame.sourceID];
if (scriptOrResource)
subtitle = WebInspector.displayNameForURL(scriptOrResource.sourceURL || scriptOrResource.url);
else
subtitle = WebInspector.UIString("(internal script)");

if (callFrame.line > 0) {
if (subtitle)
subtitle += ":" + callFrame.line;
else
subtitle = WebInspector.UIString("line %d", callFrame.line);
}

var placard = new WebInspector.Placard(title, subtitle);
placard.callFrame = callFrame;

placard.element.addEventListener("click", this._placardSelected.bind(this), false);

this.placards.push(placard);
this.bodyElement.appendChild(placard.element);
}
},

get selectedCallFrame()
{
return this._selectedCallFrame;
},

set selectedCallFrame(x)
{
if (this._selectedCallFrame === x)
return;

this._selectedCallFrame = x;

for (var i = 0; i < this.placards.length; ++i) {
var placard = this.placards[i];
placard.selected = (placard.callFrame === this._selectedCallFrame);
}

this.dispatchEventToListeners("call frame selected");
},

handleShortcut: function(event)
{
var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcut];
if (handler) {
handler(event);
event.handled = true;
}
},

_selectNextCallFrameOnStack: function()
{
var index = this._selectedCallFrameIndex();
if (index == -1)
return;
this._selectedPlacardByIndex(index + 1);
},

_selectPreviousCallFrameOnStack: function()
{
var index = this._selectedCallFrameIndex();
if (index == -1)
return;
this._selectedPlacardByIndex(index - 1);
},

_selectedPlacardByIndex: function(index)
{
if (index < 0 || index >= this.placards.length)
return;
var placard = this.placards[index];
this.selectedCallFrame = placard.callFrame
},

_selectedCallFrameIndex: function()
{
if (!this._selectedCallFrame)
return -1;
for (var i = 0; i < this.placards.length; ++i) {
var placard = this.placards[i];
if (placard.callFrame === this._selectedCallFrame)
return i;
}
return -1;
},

_placardSelected: function(event)
{
var placardElement = event.target.enclosingNodeOrSelfWithClass("placard");
this.selectedCallFrame = placardElement.placard.callFrame;
},

registerShortcuts: function(section)
{
this._shortcuts = {};

var nextCallFrame = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Period,
WebInspector.KeyboardShortcut.Modifiers.Ctrl);
this._shortcuts[nextCallFrame.key] = this._selectNextCallFrameOnStack.bind(this);

var prevCallFrame = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Comma,
WebInspector.KeyboardShortcut.Modifiers.Ctrl);
this._shortcuts[prevCallFrame.key] = this._selectPreviousCallFrameOnStack.bind(this);

section.addRelatedKeys([ nextCallFrame.name, prevCallFrame.name ], WebInspector.UIString("Next/previous call frame"));
},

_breakpointHit:  function(event)
{
var breakpoint = event.data.breakpoint;
if (breakpoint.populateStatusMessageElement) {
var statusMessageElement = document.createElement("div");
statusMessageElement.className = "info";
breakpoint.populateStatusMessageElement(statusMessageElement, event.data.eventData);
this.bodyElement.appendChild(statusMessageElement);
}
}
}

WebInspector.CallStackSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;





WebInspector.ScopeChainSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Scope Variables"));
this._expandedProperties = [];
}

WebInspector.ScopeChainSidebarPane.prototype = {
update: function(callFrame)
{
this.bodyElement.removeChildren();

this.sections = [];
this.callFrame = callFrame;

if (!callFrame) {
var infoElement = document.createElement("div");
infoElement.className = "info";
infoElement.textContent = WebInspector.UIString("Not Paused");
this.bodyElement.appendChild(infoElement);
return;
}

var foundLocalScope = false;
var scopeChain = callFrame.scopeChain;
for (var i = 0; i < scopeChain.length; ++i) {
var scopeObjectProxy = scopeChain[i];
var title = null;
var subtitle = scopeObjectProxy.description;
var emptyPlaceholder = null;
var extraProperties = null;

if (scopeObjectProxy.isLocal) {
foundLocalScope = true;
title = WebInspector.UIString("Local");
emptyPlaceholder = WebInspector.UIString("No Variables");
subtitle = null;
if (scopeObjectProxy.thisObject)
extraProperties = [ new WebInspector.RemoteObjectProperty("this", WebInspector.RemoteObject.fromPayload(scopeObjectProxy.thisObject)) ];
} else if (scopeObjectProxy.isClosure) {
title = WebInspector.UIString("Closure");
emptyPlaceholder = WebInspector.UIString("No Variables");
subtitle = null;
} else if (i === (scopeChain.length - 1))
title = WebInspector.UIString("Global");
else if (scopeObjectProxy.isElement)
title = WebInspector.UIString("Event Target");
else if (scopeObjectProxy.isDocument)
title = WebInspector.UIString("Event Document");
else if (scopeObjectProxy.isWithBlock)
title = WebInspector.UIString("With Block");

if (!title || title === subtitle)
subtitle = null;

var section = new WebInspector.ObjectPropertiesSection(WebInspector.RemoteObject.fromPayload(scopeObjectProxy), title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement);
section.editInSelectedCallFrameWhenPaused = true;
section.pane = this;

if (!foundLocalScope || scopeObjectProxy.isLocal)
section.expanded = true;

this.sections.push(section);
this.bodyElement.appendChild(section.element);
}
}
}

WebInspector.ScopeChainSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;

WebInspector.ScopeVariableTreeElement = function(property)
{
WebInspector.ObjectPropertyTreeElement.call(this, property);
}

WebInspector.ScopeVariableTreeElement.prototype = {
onattach: function()
{
WebInspector.ObjectPropertyTreeElement.prototype.onattach.call(this);
if (this.hasChildren && this.propertyIdentifier in this.treeOutline.section.pane._expandedProperties)
this.expand();
},

onexpand: function()
{
this.treeOutline.section.pane._expandedProperties[this.propertyIdentifier] = true;
},

oncollapse: function()
{
delete this.treeOutline.section.pane._expandedProperties[this.propertyIdentifier];
},

get propertyIdentifier()
{
if ("_propertyIdentifier" in this)
return this._propertyIdentifier;
var section = this.treeOutline.section;
this._propertyIdentifier = section.title + ":" + (section.subtitle ? section.subtitle + ":" : "") + this.propertyPath;
return this._propertyIdentifier;
},

get propertyPath()
{
if ("_propertyPath" in this)
return this._propertyPath;

var current = this;
var result;

do {
if (result)
result = current.property.name + "." + result;
else
result = current.property.name;
current = current.parent;
} while (current && !current.root);

this._propertyPath = result;
return result;
}
}

WebInspector.ScopeVariableTreeElement.prototype.__proto__ = WebInspector.ObjectPropertyTreeElement.prototype;





WebInspector.WatchExpressionsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Watch Expressions"));
this.reset();
}

WebInspector.WatchExpressionsSidebarPane.prototype = {
reset: function()
{
this.bodyElement.removeChildren();

this.expanded = WebInspector.settings.watchExpressions.length > 0;
this.section = new WebInspector.WatchExpressionsSection();
this.bodyElement.appendChild(this.section.element);

var addElement = document.createElement("button");
addElement.setAttribute("type", "button");
addElement.textContent = WebInspector.UIString("Add");
addElement.addEventListener("click", this.section.addExpression.bind(this.section), false);

var refreshElement = document.createElement("button");
refreshElement.setAttribute("type", "button");
refreshElement.textContent = WebInspector.UIString("Refresh");
refreshElement.addEventListener("click", this.section.update.bind(this.section), false);

var centerElement = document.createElement("div");
centerElement.addStyleClass("watch-expressions-buttons-container");
centerElement.appendChild(addElement);
centerElement.appendChild(refreshElement);
this.bodyElement.appendChild(centerElement);

this.onexpand = this.refreshExpressions.bind(this);
},

refreshExpressions: function()
{
if (this.section)
this.section.update();
}
}

WebInspector.WatchExpressionsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;

WebInspector.WatchExpressionsSection = function()
{
this._watchObjectGroupId = "watch-group";

WebInspector.ObjectPropertiesSection.call(this);

this.watchExpressions = WebInspector.settings.watchExpressions;

this.headerElement.className = "hidden";
this.editable = true;
this.expanded = true;
this.propertiesElement.addStyleClass("watch-expressions");
}

WebInspector.WatchExpressionsSection.NewWatchExpression = "\xA0";

WebInspector.WatchExpressionsSection.prototype = {
update: function()
{
function appendResult(expression, watchIndex, result)
{
var property = new WebInspector.RemoteObjectProperty(expression, result);
property.watchIndex = watchIndex;








properties.push(property);

if (properties.length == propertyCount) {
this.updateProperties(properties, WebInspector.WatchExpressionTreeElement, WebInspector.WatchExpressionsSection.CompareProperties);



if (this._newExpressionAdded) {
delete this._newExpressionAdded;

treeElement = this.findAddedTreeElement();
if (treeElement)
treeElement.startEditing();
}
}
}


InspectorBackend.releaseWrapperObjectGroup(0, this._watchObjectGroupId)
var properties = [];



var propertyCount = 0;
for (var i = 0; i < this.watchExpressions.length; ++i) {
if (!this.watchExpressions[i]) 
continue;
++propertyCount;
}



for (var i = 0; i < this.watchExpressions.length; ++i) {
var expression = this.watchExpressions[i];
if (!expression)
continue;

WebInspector.console.evalInInspectedWindow("(" + expression + ")", this._watchObjectGroupId, appendResult.bind(this, expression, i));
}








this.expanded = (propertyCount != 0);
},

addExpression: function()
{
this._newExpressionAdded = true;
this.watchExpressions.push(WebInspector.WatchExpressionsSection.NewWatchExpression);
this.update();
},

updateExpression: function(element, value)
{
this.watchExpressions[element.property.watchIndex] = value;
this.saveExpressions();
this.update();
},

findAddedTreeElement: function()
{
var children = this.propertiesTreeOutline.children;
for (var i = 0; i < children.length; ++i)
if (children[i].property.name === WebInspector.WatchExpressionsSection.NewWatchExpression)
return children[i];
},

saveExpressions: function()
{
var toSave = [];
for (var i = 0; i < this.watchExpressions.length; i++)
if (this.watchExpressions[i])
toSave.push(this.watchExpressions[i]);

WebInspector.settings.watchExpressions = toSave;
return toSave.length;
}
}

WebInspector.WatchExpressionsSection.prototype.__proto__ = WebInspector.ObjectPropertiesSection.prototype;

WebInspector.WatchExpressionsSection.CompareProperties = function(propertyA, propertyB) 
{
if (propertyA.watchIndex == propertyB.watchIndex)
return 0;
else if (propertyA.watchIndex < propertyB.watchIndex)
return -1;
else
return 1;
}

WebInspector.WatchExpressionTreeElement = function(property)
{
WebInspector.ObjectPropertyTreeElement.call(this, property);
}

WebInspector.WatchExpressionTreeElement.prototype = {
update: function()
{
WebInspector.ObjectPropertyTreeElement.prototype.update.call(this);

if (this.property.value.isError())
this.valueElement.addStyleClass("watch-expressions-error-level");

var deleteButton = document.createElement("input");
deleteButton.type = "button";
deleteButton.title = WebInspector.UIString("Delete watch expression.");
deleteButton.addStyleClass("enabled-button");
deleteButton.addStyleClass("delete-button");
deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);

this.listItemElement.insertBefore(deleteButton, this.listItemElement.firstChild);
},

_deleteButtonClicked: function()
{
this.treeOutline.section.updateExpression(this, null);
},

startEditing: function()
{
if (WebInspector.isBeingEdited(this.nameElement) || !this.treeOutline.section.editable)
return;

this.nameElement.textContent = this.property.name.trim();

var context = { expanded: this.expanded };


this.hasChildren = false;

this.listItemElement.addStyleClass("editing-sub-part");

WebInspector.startEditing(this.nameElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
},

editingCancelled: function(element, context)
{
if (!this.nameElement.textContent)
this.treeOutline.section.updateExpression(this, null);

this.update();
this.editingEnded(context);
},

applyExpression: function(expression, updateInterface)
{
expression = expression.trim();

if (!expression)
expression = null;

this.property.name = expression;
this.treeOutline.section.updateExpression(this, expression);
}
}

WebInspector.WatchExpressionTreeElement.prototype.__proto__ = WebInspector.ObjectPropertyTreeElement.prototype;





WebInspector.WorkersSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Workers"));

this._workers = {};

this._enableWorkersCheckbox = new WebInspector.Checkbox(
WebInspector.UIString("Debug"),
"sidebar-pane-subtitle",
WebInspector.UIString("Allow debugging workers. Enabling this option will replace native workers with the iframe-based JavaScript implementation"));
this.titleElement.insertBefore(this._enableWorkersCheckbox.element, this.titleElement.firstChild);

this._enableWorkersCheckbox.addEventListener(this._onTriggerInstrument.bind(this));
this._enableWorkersCheckbox.checked = false;

this._listElement = document.createElement("ol");
this._listElement.className = "workers-list";

this.bodyElement.appendChild(this._listElement);
this._treeOutline = new TreeOutline(this._listElement);
}

WebInspector.WorkersSidebarPane.prototype = {
addWorker: function(id, url, isShared)
{
if (id in this._workers) 
return;
var worker = new WebInspector.Worker(id, url, isShared);
this._workers[id] = worker;

var title = WebInspector.linkifyURL(url, WebInspector.displayNameForURL(url), "worker-item", true, url);
var treeElement = new TreeElement(null, worker, false);
treeElement.titleHTML = title;
this._treeOutline.appendChild(treeElement);
},

removeWorker: function(id)
{
if (id in this._workers) {
this._treeOutline.removeChild(this._treeOutline.findTreeElement(this._workers[id]));
delete this._workers[id];
}
},

setInstrumentation: function(enabled)
{
InspectorBackend.removeAllScriptsToEvaluateOnLoad();
if (enabled)
InspectorBackend.addScriptToEvaluateOnLoad("(" + InjectedFakeWorker + ")");
},

reset: function()
{
this.setInstrumentation(this._enableWorkersCheckbox.checked);
this._treeOutline.removeChildren();
this._workers = {};
},

_onTriggerInstrument: function(event)
{
this.setInstrumentation(this._enableWorkersCheckbox.checked);
}
};

WebInspector.WorkersSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;

WebInspector.Worker = function(id, url, shared)
{
this.id = id;
this.url = url;
this.shared = shared;
}

WebInspector.didCreateWorker = function()
{
var workersPane = WebInspector.panels.scripts.sidebarPanes.workers;
workersPane.addWorker.apply(workersPane, arguments);
}

WebInspector.didDestroyWorker = function()
{
var workersPane = WebInspector.panels.scripts.sidebarPanes.workers;
workersPane.removeWorker.apply(workersPane, arguments);
}





WebInspector.MetricsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Metrics"));
this._inlineStyleId = null;
}

WebInspector.MetricsSidebarPane.prototype = {
update: function(node)
{
if (node)
this.node = node;
else
node = this.node;

if (!node || !node.ownerDocument.defaultView || node.nodeType !== Node.ELEMENT_NODE) {
this.bodyElement.removeChildren();
return;
}

var self = this;
var callback = function(style) {
if (!style)
return;
self._update(style);
};
WebInspector.cssModel.getComputedStyleAsync(node.id, callback);

var inlineStyleCallback = function(style) {
if (!style)
return;
self.inlineStyle = style;
};
WebInspector.cssModel.getInlineStyleAsync(node.id, inlineStyleCallback);
},

_update: function(style)
{

var metricsElement = document.createElement("div");
metricsElement.className = "metrics";

function createBoxPartElement(style, name, side, suffix)
{
var propertyName = (name !== "position" ? name + "-" : "") + side + suffix;
var value = style.getPropertyValue(propertyName);
if (value === "" || (name !== "position" && value === "0px"))
value = "\u2012";
else if (name === "position" && value === "auto")
value = "\u2012";
value = value.replace(/px$/, "");

var element = document.createElement("div");
element.className = side;
element.textContent = value;
element.addEventListener("dblclick", this.startEditing.bind(this, element, name, propertyName), false);
return element;
}


var noMarginDisplayType = {
"table-cell": true,
"table-column": true,
"table-column-group": true,
"table-footer-group": true,
"table-header-group": true,
"table-row": true,
"table-row-group": true
};


var noPaddingDisplayType = {
"table-column": true,
"table-column-group": true,
"table-footer-group": true,
"table-header-group": true,
"table-row": true,
"table-row-group": true
};


var noPositionType = {
"static": true
};

var boxes = ["content", "padding", "border", "margin", "position"];
var boxLabels = [WebInspector.UIString("content"), WebInspector.UIString("padding"), WebInspector.UIString("border"), WebInspector.UIString("margin"), WebInspector.UIString("position")];
var previousBox;
for (var i = 0; i < boxes.length; ++i) {
var name = boxes[i];

if (name === "margin" && noMarginDisplayType[style.getPropertyValue("display")])
continue;
if (name === "padding" && noPaddingDisplayType[style.getPropertyValue("display")])
continue;
if (name === "position" && noPositionType[style.getPropertyValue("position")])
continue;

var boxElement = document.createElement("div");
boxElement.className = name;

if (name === "content") {
var width = style.getPropertyValue("width").replace(/px$/, "");
var widthElement = document.createElement("span");
widthElement.textContent = width;
widthElement.addEventListener("dblclick", this.startEditing.bind(this, widthElement, "width", "width"), false);

var height = style.getPropertyValue("height").replace(/px$/, "");
var heightElement = document.createElement("span");
heightElement.textContent = height;
heightElement.addEventListener("dblclick", this.startEditing.bind(this, heightElement, "height", "height"), false);

boxElement.appendChild(widthElement);
boxElement.appendChild(document.createTextNode(" \u00D7 "));
boxElement.appendChild(heightElement);
} else {
var suffix = (name === "border" ? "-width" : "");

var labelElement = document.createElement("div");
labelElement.className = "label";
labelElement.textContent = boxLabels[i];
boxElement.appendChild(labelElement);

boxElement.appendChild(createBoxPartElement.call(this, style, name, "top", suffix));
boxElement.appendChild(document.createElement("br"));
boxElement.appendChild(createBoxPartElement.call(this, style, name, "left", suffix));

if (previousBox)
boxElement.appendChild(previousBox);

boxElement.appendChild(createBoxPartElement.call(this, style, name, "right", suffix));
boxElement.appendChild(document.createElement("br"));
boxElement.appendChild(createBoxPartElement.call(this, style, name, "bottom", suffix));
}

previousBox = boxElement;
}

metricsElement.appendChild(previousBox);
this.bodyElement.removeChildren();
this.bodyElement.appendChild(metricsElement);
},

startEditing: function(targetElement, box, styleProperty)
{
if (WebInspector.isBeingEdited(targetElement))
return;

var context = { box: box, styleProperty: styleProperty };

WebInspector.startEditing(targetElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
},

editingCancelled: function(element, context)
{
this.update();
},

editingCommitted: function(element, userInput, previousContent, context)
{
if (!this.inlineStyle) {

return this.editingCancelled(element, context); 
}

if (userInput === previousContent)
return this.editingCancelled(element, context); 

if (context.box !== "position" && (!userInput || userInput === "\u2012"))
userInput = "0px";
else if (context.box === "position" && (!userInput || userInput === "\u2012"))
userInput = "auto";


if (/^\d+$/.test(userInput))
userInput += "px";

var self = this;
var callback = function(style) {
if (!style)
return;
self.inlineStyle = style;
self.dispatchEventToListeners("metrics edited");
self.update();
};

function setEnabledValueCallback(context, style)
{
var property = style.getLiveProperty(context.styleProperty);
if (!property)
style.appendProperty(context.styleProperty, userInput, callback);
else
property.setValue(userInput, callback);
}

var allProperties = this.inlineStyle.allProperties;
for (var i = 0; i < allProperties.length; ++i) {
var property = allProperties[i];
if (property.name !== context.styleProperty || property.inactive)
continue;
if (property.disabled)
property.setDisabled(false, setEnabledValueCallback.bind(null, context));
else
property.setValue(userInput, callback);
return;
}

this.inlineStyle.appendProperty(context.styleProperty, userInput, callback);
}
}

WebInspector.MetricsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;





WebInspector.PropertiesSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Properties"));
}

WebInspector.PropertiesSidebarPane.prototype = {
update: function(node)
{
var body = this.bodyElement;

if (!node) {
body.removeChildren();
this.sections = [];
return;
}

var self = this;
var callback = function(prototypes) {
var body = self.bodyElement;
body.removeChildren();
self.sections = [];


for (var i = 0; i < prototypes.length; ++i) {
var prototype = WebInspector.RemoteObject.fromPayload(prototypes[i]);
var title = prototype.description;
if (title.match(/Prototype$/))
title = title.replace(/Prototype$/, "");
var section = new WebInspector.ObjectPropertiesSection(prototype, title);
self.sections.push(section);
body.appendChild(section.element);
}
};
InjectedScriptAccess.getForNode(node).getPrototypes(node.id, callback);
}
}

WebInspector.PropertiesSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;





WebInspector.EventListenersSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listeners"));
this.bodyElement.addStyleClass("events-pane");

this.sections = [];

this.settingsSelectElement = document.createElement("select");

var option = document.createElement("option");
option.value = "all";
option.label = WebInspector.UIString("All Nodes");
this.settingsSelectElement.appendChild(option);

option = document.createElement("option");
option.value = "selected";
option.label = WebInspector.UIString("Selected Node Only");
this.settingsSelectElement.appendChild(option);

var filter = WebInspector.settings.eventListenersFilter;
if (filter === "all")
this.settingsSelectElement[0].selected = true;
else if (filter === "selected")
this.settingsSelectElement[1].selected = true;
this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false);
this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);

this.titleElement.appendChild(this.settingsSelectElement);
}

WebInspector.EventListenersSidebarPane.prototype = {
update: function(node)
{
var body = this.bodyElement;
body.removeChildren();
this.sections = [];

var self = this;
function callback(nodeId, eventListeners) {
var sectionNames = [];
var sectionMap = {};
for (var i = 0; i < eventListeners.length; ++i) {
var eventListener = eventListeners[i];
eventListener.node = WebInspector.domAgent.nodeForId(eventListener.nodeId);
delete eventListener.nodeId; 
if (/^function _inspectorCommandLineAPI_logEvent\(/.test(eventListener.listenerBody.toString()))
continue; 
var type = eventListener.type;
var section = sectionMap[type];
if (!section) {
section = new WebInspector.EventListenersSection(type, nodeId);
sectionMap[type] = section;
sectionNames.push(type);
self.sections.push(section);
}
section.addListener(eventListener);
}

if (sectionNames.length === 0) {
var div = document.createElement("div");
div.className = "info";
div.textContent = WebInspector.UIString("No Event Listeners");
body.appendChild(div);
return;
}

sectionNames.sort();
for (var i = 0; i < sectionNames.length; ++i) {
var section = sectionMap[sectionNames[i]];
section.update();
body.appendChild(section.element);
}
}

WebInspector.EventListeners.getEventListenersForNodeAsync(node, callback);
},

_changeSetting: function(event)
{
var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
WebInspector.settings.eventListenersFilter = selectedOption.value;

for (var i = 0; i < this.sections.length; ++i)
this.sections[i].update();
}
}

WebInspector.EventListenersSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;

WebInspector.EventListenersSection = function(title, nodeId)
{
this.eventListeners = [];
this._nodeId = nodeId;
WebInspector.PropertiesSection.call(this, title);


this.propertiesElement.parentNode.removeChild(this.propertiesElement);
delete this.propertiesElement;
delete this.propertiesTreeOutline;

this.eventBars = document.createElement("div");
this.eventBars.className = "event-bars";
this.element.appendChild(this.eventBars);
}

WebInspector.EventListenersSection.prototype = {
update: function()
{

var filteredEventListeners = this.eventListeners;
if (WebInspector.settings.eventListenersFilter === "selected") {
filteredEventListeners = [];
for (var i = 0; i < this.eventListeners.length; ++i) {
var eventListener = this.eventListeners[i];
if (eventListener.node.id === this._nodeId)
filteredEventListeners.push(eventListener);
}
}

this.eventBars.removeChildren();
var length = filteredEventListeners.length;
for (var i = 0; i < length; ++i) {
var eventListener = filteredEventListeners[i];
var eventListenerBar = new WebInspector.EventListenerBar(eventListener, this._nodeId);
this.eventBars.appendChild(eventListenerBar.element);
}
},

addListener: function(eventListener)
{
this.eventListeners.push(eventListener);
}
}

WebInspector.EventListenersSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;

WebInspector.EventListenerBar = function(eventListener, nodeId)
{
this.eventListener = eventListener;
this._nodeId = nodeId;
WebInspector.ObjectPropertiesSection.call(this);
this._setNodeTitle();
this._setFunctionSubtitle();
this.editable = false;
this.element.className = "event-bar";  
this.headerElement.addStyleClass("source-code");
this.propertiesElement.className = "event-properties properties-tree source-code";  
}

WebInspector.EventListenerBar.prototype = {
update: function()
{
function updateWithNodeObject(nodeObject)
{
var properties = [];
if (nodeObject)
properties.push(new WebInspector.RemoteObjectProperty("node", nodeObject));

for (var propertyName in this.eventListener) {
var value = WebInspector.RemoteObject.fromPrimitiveValue(this.eventListener[propertyName]);
properties.push(new WebInspector.RemoteObjectProperty(propertyName, value));
}
this.updateProperties(properties);
}
var node = this.eventListener.node;
delete this.eventListener.node;
WebInspector.RemoteObject.resolveNode(node, updateWithNodeObject.bind(this));
},

_setNodeTitle: function()
{
var node = this.eventListener.node;
if (!node)
return;

if (node.nodeType === Node.DOCUMENT_NODE) {
this.titleElement.textContent = "document";
return;
}

if (node.id === this._nodeId) {
this.titleElement.textContent = appropriateSelectorForNode(node);
return;
}

this.titleElement.removeChildren();
this.titleElement.appendChild(WebInspector.panels.elements.linkifyNodeReference(this.eventListener.node));
},

_setFunctionSubtitle: function()
{

if (this.eventListener.sourceName) {
this.subtitleElement.removeChildren();
this.subtitleElement.appendChild(WebInspector.linkifyResourceAsNode(this.eventListener.sourceName, "scripts", this.eventListener.lineNumber));
} else {
var match = this.eventListener.listenerBody.match(/function ([^\(]+?)\(/);
if (match)
this.subtitleElement.textContent = match[1];
else
this.subtitleElement.textContent = WebInspector.UIString("(anonymous function)");
}
}
}

WebInspector.EventListenerBar.prototype.__proto__ = WebInspector.ObjectPropertiesSection.prototype;





WebInspector.Color = function(str)
{
this.value = str;
this._parse();
}

WebInspector.Color.prototype = {
get shorthex()
{
if ("_short" in this)
return this._short;

if (!this.simple)
return null;

var hex = this.hex;
if (hex.charAt(0) === hex.charAt(1) && hex.charAt(2) === hex.charAt(3) && hex.charAt(4) === hex.charAt(5))
this._short = hex.charAt(0) + hex.charAt(2) + hex.charAt(4);
else
this._short = hex;

return this._short;
},

get hex()
{
if (!this.simple)
return null;

return this._hex;
},

set hex(x)
{
this._hex = x;
},

get rgb()
{
if ("_rgb" in this)
return this._rgb;

if (this.simple)
this._rgb = this._hexToRGB(this.hex);
else {
var rgba = this.rgba;
this._rgb = [rgba[0], rgba[1], rgba[2]];
}

return this._rgb;
},

set rgb(x)
{
this._rgb = x;
},

get hsl()
{
if ("_hsl" in this)
return this._hsl;

this._hsl = this._rgbToHSL(this.rgb);
return this._hsl;
},

set hsl(x)
{
this._hsl = x;
},

get nickname()
{
if (typeof this._nickname !== "undefined") 
return this._nickname;
else
return null;
},

set nickname(x)
{
this._nickname = x;
},

get rgba()
{
return this._rgba;
},

set rgba(x)
{
this._rgba = x;
},

get hsla()
{
return this._hsla;
},

set hsla(x)
{
this._hsla = x;
},

hasShortHex: function()
{
var shorthex = this.shorthex;
return (shorthex && shorthex.length === 3);
},

toString: function(format)
{
if (!format)
format = this.format;

switch (format) {
case "original":
return this.value;
case "rgb":
return "rgb(" + this.rgb.join(", ") + ")";
case "rgba":
return "rgba(" + this.rgba.join(", ") + ")";
case "hsl":
var hsl = this.hsl;
return "hsl(" + hsl[0] + ", " + hsl[1] + "%, " + hsl[2] + "%)";
case "hsla":
var hsla = this.hsla;
return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " + hsla[3] + ")";
case "hex":
return "#" + this.hex;
case "shorthex":
return "#" + this.shorthex;
case "nickname":
return this.nickname;
}

throw "invalid color format";
},

_rgbToHex: function(rgb)
{
var r = parseInt(rgb[0]).toString(16);
var g = parseInt(rgb[1]).toString(16);
var b = parseInt(rgb[2]).toString(16);
if (r.length === 1)
r = "0" + r;
if (g.length === 1)
g = "0" + g;
if (b.length === 1)
b = "0" + b;

return (r + g + b).toUpperCase();
},

_hexToRGB: function(hex)
{
var r = parseInt(hex.substring(0,2), 16);
var g = parseInt(hex.substring(2,4), 16);
var b = parseInt(hex.substring(4,6), 16);

return [r, g, b];
},

_rgbToHSL: function(rgb)
{
var r = parseInt(rgb[0]) / 255;
var g = parseInt(rgb[1]) / 255;
var b = parseInt(rgb[2]) / 255;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var diff = max - min;
var add = max + min;

if (min === max)
var h = 0;
else if (r === max)
var h = ((60 * (g - b) / diff) + 360) % 360;
else if (g === max)
var h = (60 * (b - r) / diff) + 120;
else
var h = (60 * (r - g) / diff) + 240;

var l = 0.5 * add;

if (l === 0)
var s = 0;
else if (l === 1)
var s = 1;
else if (l <= 0.5)
var s = diff / add;
else
var s = diff / (2 - add);

h = Math.round(h);
s = Math.round(s*100);
l = Math.round(l*100);

return [h, s, l];
},

_hslToRGB: function(hsl)
{
var h = parseFloat(hsl[0]) / 360;
var s = parseFloat(hsl[1]) / 100;
var l = parseFloat(hsl[2]) / 100;

if (l <= 0.5)
var q = l * (1 + s);
else
var q = l + s - (l * s);

var p = 2 * l - q;

var tr = h + (1 / 3);
var tg = h;
var tb = h - (1 / 3);

var r = Math.round(hueToRGB(p, q, tr) * 255);
var g = Math.round(hueToRGB(p, q, tg) * 255);
var b = Math.round(hueToRGB(p, q, tb) * 255);
return [r, g, b];

function hueToRGB(p, q, h) {
if (h < 0)
h += 1;
else if (h > 1)
h -= 1;

if ((h * 6) < 1)
return p + (q - p) * h * 6;
else if ((h * 2) < 1)
return q;
else if ((h * 3) < 2)
return p + (q - p) * ((2 / 3) - h) * 6;
else
return p;
}
},

_rgbaToHSLA: function(rgba)
{
var alpha = rgba[3];
var hsl = this._rgbToHSL(rgba)
hsl.push(alpha);
return hsl;
},

_hslaToRGBA: function(hsla)
{
var alpha = hsla[3];
var rgb = this._hslToRGB(hsla);
rgb.push(alpha);
return rgb;
},

_parse: function()
{

var value = this.value.toLowerCase().replace(/%|\s+/g, "");
if (value in WebInspector.Color.AdvancedNickNames) {
this.format = "nickname";
var set = WebInspector.Color.AdvancedNickNames[value];
this.simple = false;
this.rgba = set[0];
this.hsla = set[1];
this.nickname = set[2];
this.alpha = set[0][3];
return;
}


var simple = /^(?:#([0-9a-f]{3,6})|rgb\(([^)]+)\)|(\w+)|hsl\(([^)]+)\))$/i;
var match = this.value.match(simple);
if (match) {
this.simple = true;

if (match[1]) { 
var hex = match[1].toUpperCase();
if (hex.length === 3) {
this.format = "shorthex";
this.hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
} else {
this.format = "hex";
this.hex = hex;
}
} else if (match[2]) { 
this.format = "rgb";
var rgb = match[2].split(/\s*,\s*/);
this.rgb = rgb;
this.hex = this._rgbToHex(rgb);
} else if (match[3]) { 
var nickname = match[3].toLowerCase();
if (nickname in WebInspector.Color.Nicknames) {
this.format = "nickname";
this.hex = WebInspector.Color.Nicknames[nickname];
} else 
throw "unknown color name";
} else if (match[4]) { 
this.format = "hsl";
var hsl = match[4].replace(/%/g, "").split(/\s*,\s*/);
this.hsl = hsl;
this.rgb = this._hslToRGB(hsl);
this.hex = this._rgbToHex(this.rgb);
}


var hex = this.hex;
if (hex && hex in WebInspector.Color.HexTable) {
var set = WebInspector.Color.HexTable[hex];
this.rgb = set[0];
this.hsl = set[1];
this.nickname = set[2];
}

return;
}


var advanced = /^(?:rgba\(([^)]+)\)|hsla\(([^)]+)\))$/;
match = this.value.match(advanced);
if (match) {
this.simple = false;
if (match[1]) { 
this.format = "rgba";
this.rgba = match[1].split(/\s*,\s*/);
this.hsla = this._rgbaToHSLA(this.rgba);
this.alpha = this.rgba[3];
} else if (match[2]) { 
this.format = "hsla";
this.hsla = match[2].replace(/%/g, "").split(/\s*,\s*/);
this.rgba = this._hslaToRGBA(this.hsla);
this.alpha = this.hsla[3];
}

return;
}


throw "could not parse color";
}
}


WebInspector.Color.HexTable = {
"000000": [[0, 0, 0], [0, 0, 0], "black"],
"000080": [[0, 0, 128], [240, 100, 25], "navy"],
"00008B": [[0, 0, 139], [240, 100, 27], "darkBlue"],
"0000CD": [[0, 0, 205], [240, 100, 40], "mediumBlue"],
"0000FF": [[0, 0, 255], [240, 100, 50], "blue"],
"006400": [[0, 100, 0], [120, 100, 20], "darkGreen"],
"008000": [[0, 128, 0], [120, 100, 25], "green"],
"008080": [[0, 128, 128], [180, 100, 25], "teal"],
"008B8B": [[0, 139, 139], [180, 100, 27], "darkCyan"],
"00BFFF": [[0, 191, 255], [195, 100, 50], "deepSkyBlue"],
"00CED1": [[0, 206, 209], [181, 100, 41], "darkTurquoise"],
"00FA9A": [[0, 250, 154], [157, 100, 49], "mediumSpringGreen"],
"00FF00": [[0, 255, 0], [120, 100, 50], "lime"],
"00FF7F": [[0, 255, 127], [150, 100, 50], "springGreen"],
"00FFFF": [[0, 255, 255], [180, 100, 50], "cyan"],
"191970": [[25, 25, 112], [240, 64, 27], "midnightBlue"],
"1E90FF": [[30, 144, 255], [210, 100, 56], "dodgerBlue"],
"20B2AA": [[32, 178, 170], [177, 70, 41], "lightSeaGreen"],
"228B22": [[34, 139, 34], [120, 61, 34], "forestGreen"],
"2E8B57": [[46, 139, 87], [146, 50, 36], "seaGreen"],
"2F4F4F": [[47, 79, 79], [180, 25, 25], "darkSlateGray"],
"32CD32": [[50, 205, 50], [120, 61, 50], "limeGreen"],
"3CB371": [[60, 179, 113], [147, 50, 47], "mediumSeaGreen"],
"40E0D0": [[64, 224, 208], [174, 72, 56], "turquoise"],
"4169E1": [[65, 105, 225], [225, 73, 57], "royalBlue"],
"4682B4": [[70, 130, 180], [207, 44, 49], "steelBlue"],
"483D8B": [[72, 61, 139], [248, 39, 39], "darkSlateBlue"],
"48D1CC": [[72, 209, 204], [178, 60, 55], "mediumTurquoise"],
"4B0082": [[75, 0, 130], [275, 100, 25], "indigo"],
"556B2F": [[85, 107, 47], [82, 39, 30], "darkOliveGreen"],
"5F9EA0": [[95, 158, 160], [182, 25, 50], "cadetBlue"],
"6495ED": [[100, 149, 237], [219, 79, 66], "cornflowerBlue"],
"66CDAA": [[102, 205, 170], [160, 51, 60], "mediumAquaMarine"],
"696969": [[105, 105, 105], [0, 0, 41], "dimGray"],
"6A5ACD": [[106, 90, 205], [248, 53, 58], "slateBlue"],
"6B8E23": [[107, 142, 35], [80, 60, 35], "oliveDrab"],
"708090": [[112, 128, 144], [210, 13, 50], "slateGray"],
"778899": [[119, 136, 153], [210, 14, 53], "lightSlateGray"],
"7B68EE": [[123, 104, 238], [249, 80, 67], "mediumSlateBlue"],
"7CFC00": [[124, 252, 0], [90, 100, 49], "lawnGreen"],
"7FFF00": [[127, 255, 0], [90, 100, 50], "chartreuse"],
"7FFFD4": [[127, 255, 212], [160, 100, 75], "aquamarine"],
"800000": [[128, 0, 0], [0, 100, 25], "maroon"],
"800080": [[128, 0, 128], [300, 100, 25], "purple"],
"808000": [[128, 128, 0], [60, 100, 25], "olive"],
"808080": [[128, 128, 128], [0, 0, 50], "gray"],
"87CEEB": [[135, 206, 235], [197, 71, 73], "skyBlue"],
"87CEFA": [[135, 206, 250], [203, 92, 75], "lightSkyBlue"],
"8A2BE2": [[138, 43, 226], [271, 76, 53], "blueViolet"],
"8B0000": [[139, 0, 0], [0, 100, 27], "darkRed"],
"8B008B": [[139, 0, 139], [300, 100, 27], "darkMagenta"],
"8B4513": [[139, 69, 19], [25, 76, 31], "saddleBrown"],
"8FBC8F": [[143, 188, 143], [120, 25, 65], "darkSeaGreen"],
"90EE90": [[144, 238, 144], [120, 73, 75], "lightGreen"],
"9370D8": [[147, 112, 219], [260, 60, 65], "mediumPurple"],
"9400D3": [[148, 0, 211], [282, 100, 41], "darkViolet"],
"98FB98": [[152, 251, 152], [120, 93, 79], "paleGreen"],
"9932CC": [[153, 50, 204], [280, 61, 50], "darkOrchid"],
"9ACD32": [[154, 205, 50], [80, 61, 50], "yellowGreen"],
"A0522D": [[160, 82, 45], [19, 56, 40], "sienna"],
"A52A2A": [[165, 42, 42], [0, 59, 41], "brown"],
"A9A9A9": [[169, 169, 169], [0, 0, 66], "darkGray"],
"ADD8E6": [[173, 216, 230], [195, 53, 79], "lightBlue"],
"ADFF2F": [[173, 255, 47], [84, 100, 59], "greenYellow"],
"AFEEEE": [[175, 238, 238], [180, 65, 81], "paleTurquoise"],
"B0C4DE": [[176, 196, 222], [214, 41, 78], "lightSteelBlue"],
"B0E0E6": [[176, 224, 230], [187, 52, 80], "powderBlue"],
"B22222": [[178, 34, 34], [0, 68, 42], "fireBrick"],
"B8860B": [[184, 134, 11], [43, 89, 38], "darkGoldenrod"],
"BA55D3": [[186, 85, 211], [288, 59, 58], "mediumOrchid"],
"BC8F8F": [[188, 143, 143], [0, 25, 65], "rosyBrown"],
"BDB76B": [[189, 183, 107], [56, 38, 58], "darkKhaki"],
"C0C0C0": [[192, 192, 192], [0, 0, 75], "silver"],
"C71585": [[199, 21, 133], [322, 81, 43], "mediumVioletRed"],
"CD5C5C": [[205, 92, 92], [0, 53, 58], "indianRed"],
"CD853F": [[205, 133, 63], [30, 59, 53], "peru"],
"D2691E": [[210, 105, 30], [25, 75, 47], "chocolate"],
"D2B48C": [[210, 180, 140], [34, 44, 69], "tan"],
"D3D3D3": [[211, 211, 211], [0, 0, 83], "lightGrey"],
"D87093": [[219, 112, 147], [340, 60, 65], "paleVioletRed"],
"D8BFD8": [[216, 191, 216], [300, 24, 80], "thistle"],
"DA70D6": [[218, 112, 214], [302, 59, 65], "orchid"],
"DAA520": [[218, 165, 32], [43, 74, 49], "goldenrod"],
"DC143C": [[237, 164, 61], [35, 83, 58], "crimson"],
"DCDCDC": [[220, 220, 220], [0, 0, 86], "gainsboro"],
"DDA0DD": [[221, 160, 221], [300, 47, 75], "plum"],
"DEB887": [[222, 184, 135], [34, 57, 70], "burlyWood"],
"E0FFFF": [[224, 255, 255], [180, 100, 94], "lightCyan"],
"E6E6FA": [[230, 230, 250], [240, 67, 94], "lavender"],
"E9967A": [[233, 150, 122], [15, 72, 70], "darkSalmon"],
"EE82EE": [[238, 130, 238], [300, 76, 72], "violet"],
"EEE8AA": [[238, 232, 170], [55, 67, 80], "paleGoldenrod"],
"F08080": [[240, 128, 128], [0, 79, 72], "lightCoral"],
"F0E68C": [[240, 230, 140], [54, 77, 75], "khaki"],
"F0F8FF": [[240, 248, 255], [208, 100, 97], "aliceBlue"],
"F0FFF0": [[240, 255, 240], [120, 100, 97], "honeyDew"],
"F0FFFF": [[240, 255, 255], [180, 100, 97], "azure"],
"F4A460": [[244, 164, 96], [28, 87, 67], "sandyBrown"],
"F5DEB3": [[245, 222, 179], [39, 77, 83], "wheat"],
"F5F5DC": [[245, 245, 220], [60, 56, 91], "beige"],
"F5F5F5": [[245, 245, 245], [0, 0, 96], "whiteSmoke"],
"F5FFFA": [[245, 255, 250], [150, 100, 98], "mintCream"],
"F8F8FF": [[248, 248, 255], [240, 100, 99], "ghostWhite"],
"FA8072": [[250, 128, 114], [6, 93, 71], "salmon"],
"FAEBD7": [[250, 235, 215], [34, 78, 91], "antiqueWhite"],
"FAF0E6": [[250, 240, 230], [30, 67, 94], "linen"],
"FAFAD2": [[250, 250, 210], [60, 80, 90], "lightGoldenrodYellow"],
"FDF5E6": [[253, 245, 230], [39, 85, 95], "oldLace"],
"FF0000": [[255, 0, 0], [0, 100, 50], "red"],
"FF00FF": [[255, 0, 255], [300, 100, 50], "magenta"],
"FF1493": [[255, 20, 147], [328, 100, 54], "deepPink"],
"FF4500": [[255, 69, 0], [16, 100, 50], "orangeRed"],
"FF6347": [[255, 99, 71], [9, 100, 64], "tomato"],
"FF69B4": [[255, 105, 180], [330, 100, 71], "hotPink"],
"FF7F50": [[255, 127, 80], [16, 100, 66], "coral"],
"FF8C00": [[255, 140, 0], [33, 100, 50], "darkOrange"],
"FFA07A": [[255, 160, 122], [17, 100, 74], "lightSalmon"],
"FFA500": [[255, 165, 0], [39, 100, 50], "orange"],
"FFB6C1": [[255, 182, 193], [351, 100, 86], "lightPink"],
"FFC0CB": [[255, 192, 203], [350, 100, 88], "pink"],
"FFD700": [[255, 215, 0], [51, 100, 50], "gold"],
"FFDAB9": [[255, 218, 185], [28, 100, 86], "peachPuff"],
"FFDEAD": [[255, 222, 173], [36, 100, 84], "navajoWhite"],
"FFE4B5": [[255, 228, 181], [38, 100, 85], "moccasin"],
"FFE4C4": [[255, 228, 196], [33, 100, 88], "bisque"],
"FFE4E1": [[255, 228, 225], [6, 100, 94], "mistyRose"],
"FFEBCD": [[255, 235, 205], [36, 100, 90], "blanchedAlmond"],
"FFEFD5": [[255, 239, 213], [37, 100, 92], "papayaWhip"],
"FFF0F5": [[255, 240, 245], [340, 100, 97], "lavenderBlush"],
"FFF5EE": [[255, 245, 238], [25, 100, 97], "seaShell"],
"FFF8DC": [[255, 248, 220], [48, 100, 93], "cornsilk"],
"FFFACD": [[255, 250, 205], [54, 100, 90], "lemonChiffon"],
"FFFAF0": [[255, 250, 240], [40, 100, 97], "floralWhite"],
"FFFAFA": [[255, 250, 250], [0, 100, 99], "snow"],
"FFFF00": [[255, 255, 0], [60, 100, 50], "yellow"],
"FFFFE0": [[255, 255, 224], [60, 100, 94], "lightYellow"],
"FFFFF0": [[255, 255, 240], [60, 100, 97], "ivory"],
"FFFFFF": [[255, 255, 255], [0, 100, 100], "white"]
};


WebInspector.Color.Nicknames = {
"aliceblue": "F0F8FF",
"antiquewhite": "FAEBD7",
"aqua": "00FFFF",
"aquamarine": "7FFFD4",
"azure": "F0FFFF",
"beige": "F5F5DC",
"bisque": "FFE4C4",
"black": "000000",
"blanchedalmond": "FFEBCD",
"blue": "0000FF",
"blueviolet": "8A2BE2",
"brown": "A52A2A",
"burlywood": "DEB887",
"cadetblue": "5F9EA0",
"chartreuse": "7FFF00",
"chocolate": "D2691E",
"coral": "FF7F50",
"cornflowerblue": "6495ED",
"cornsilk": "FFF8DC",
"crimson": "DC143C",
"cyan": "00FFFF",
"darkblue": "00008B",
"darkcyan": "008B8B",
"darkgoldenrod": "B8860B",
"darkgray": "A9A9A9",
"darkgreen": "006400",
"darkkhaki": "BDB76B",
"darkmagenta": "8B008B",
"darkolivegreen": "556B2F",
"darkorange": "FF8C00",
"darkorchid": "9932CC",
"darkred": "8B0000",
"darksalmon": "E9967A",
"darkseagreen": "8FBC8F",
"darkslateblue": "483D8B",
"darkslategray": "2F4F4F",
"darkturquoise": "00CED1",
"darkviolet": "9400D3",
"deeppink": "FF1493",
"deepskyblue": "00BFFF",
"dimgray": "696969",
"dodgerblue": "1E90FF",
"firebrick": "B22222",
"floralwhite": "FFFAF0",
"forestgreen": "228B22",
"fuchsia": "FF00FF",
"gainsboro": "DCDCDC",
"ghostwhite": "F8F8FF",
"gold": "FFD700",
"goldenrod": "DAA520",
"gray": "808080",
"green": "008000",
"greenyellow": "ADFF2F",
"honeydew": "F0FFF0",
"hotpink": "FF69B4",
"indianred": "CD5C5C",
"indigo": "4B0082",
"ivory": "FFFFF0",
"khaki": "F0E68C",
"lavender": "E6E6FA",
"lavenderblush": "FFF0F5",
"lawngreen": "7CFC00",
"lemonchiffon": "FFFACD",
"lightblue": "ADD8E6",
"lightcoral": "F08080",
"lightcyan": "E0FFFF",
"lightgoldenrodyellow": "FAFAD2",
"lightgreen": "90EE90",
"lightgrey": "D3D3D3",
"lightpink": "FFB6C1",
"lightsalmon": "FFA07A",
"lightseagreen": "20B2AA",
"lightskyblue": "87CEFA",
"lightslategray": "778899",
"lightsteelblue": "B0C4DE",
"lightyellow": "FFFFE0",
"lime": "00FF00",
"limegreen": "32CD32",
"linen": "FAF0E6",
"magenta": "FF00FF",
"maroon": "800000",
"mediumaquamarine": "66CDAA",
"mediumblue": "0000CD",
"mediumorchid": "BA55D3",
"mediumpurple": "9370D8",
"mediumseagreen": "3CB371",
"mediumslateblue": "7B68EE",
"mediumspringgreen": "00FA9A",
"mediumturquoise": "48D1CC",
"mediumvioletred": "C71585",
"midnightblue": "191970",
"mintcream": "F5FFFA",
"mistyrose": "FFE4E1",
"moccasin": "FFE4B5",
"navajowhite": "FFDEAD",
"navy": "000080",
"oldlace": "FDF5E6",
"olive": "808000",
"olivedrab": "6B8E23",
"orange": "FFA500",
"orangered": "FF4500",
"orchid": "DA70D6",
"palegoldenrod": "EEE8AA",
"palegreen": "98FB98",
"paleturquoise": "AFEEEE",
"palevioletred": "D87093",
"papayawhip": "FFEFD5",
"peachpuff": "FFDAB9",
"peru": "CD853F",
"pink": "FFC0CB",
"plum": "DDA0DD",
"powderblue": "B0E0E6",
"purple": "800080",
"red": "FF0000",
"rosybrown": "BC8F8F",
"royalblue": "4169E1",
"saddlebrown": "8B4513",
"salmon": "FA8072",
"sandybrown": "F4A460",
"seagreen": "2E8B57",
"seashell": "FFF5EE",
"sienna": "A0522D",
"silver": "C0C0C0",
"skyblue": "87CEEB",
"slateblue": "6A5ACD",
"slategray": "708090",
"snow": "FFFAFA",
"springgreen": "00FF7F",
"steelblue": "4682B4",
"tan": "D2B48C",
"teal": "008080",
"thistle": "D8BFD8",
"tomato": "FF6347",
"turquoise": "40E0D0",
"violet": "EE82EE",
"wheat": "F5DEB3",
"white": "FFFFFF",
"whitesmoke": "F5F5F5",
"yellow": "FFFF00",
"yellowgreen": "9ACD32"
};


WebInspector.Color.AdvancedNickNames = {
"transparent": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
"rgba(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
"hsla(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
};



WebInspector.CSSCompletions = [];

WebInspector.CSSCompletions.startsWith = function(prefix)
{
var firstIndex = this._firstIndexOfPrefix(prefix);
if (firstIndex === -1)
return [];

var results = [];
while (this[firstIndex].indexOf(prefix) === 0)
results.push(this[firstIndex++]);
return results;
}

WebInspector.CSSCompletions.firstStartsWith = function(prefix)
{
var foundIndex = this._firstIndexOfPrefix(prefix);
return (foundIndex === -1 ? "" : this[foundIndex]);
}

WebInspector.CSSCompletions._firstIndexOfPrefix = function(prefix)
{
if (!prefix)
return -1;
if (!this.length)
return -1;

var maxIndex = this.length - 1;
var minIndex = 0;
var foundIndex;

do {
var middleIndex = (maxIndex + minIndex) >> 1;
if (this[middleIndex].indexOf(prefix) === 0) {
foundIndex = middleIndex;
break;
}
if (this[middleIndex] < prefix)
minIndex = middleIndex + 1;
else
maxIndex = middleIndex - 1;
} while (minIndex <= maxIndex);

if (!foundIndex)
return -1;

while (foundIndex && this[foundIndex - 1].indexOf(prefix) === 0)
foundIndex--;

return foundIndex;
}

WebInspector.CSSCompletions.next = function(str, prefix)
{
return WebInspector.CSSCompletions._closest(str, prefix, 1);
}

WebInspector.CSSCompletions.previous = function(str, prefix)
{
return WebInspector.CSSCompletions._closest(str, prefix, -1);
}

WebInspector.CSSCompletions._closest = function(str, prefix, shift)
{
if (!str)
return "";

var index = this.indexOf(str);
if (index === -1)
return "";

if (!prefix) {
index = (index + this.length + shift) % this.length;
return this[index];
}

var propertiesWithPrefix = this.startsWith(prefix);
var j = propertiesWithPrefix.indexOf(str);
j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length;
return propertiesWithPrefix[j];
}

WebInspector.CSSCompletions._load = function(properties)
{
for (var i = 0; i < properties.length; ++i)
WebInspector.CSSCompletions.push(properties[i]);
WebInspector.CSSCompletions.sort();
}





WebInspector.StylesSidebarPane = function(computedStylePane)
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Styles"));

this.settingsSelectElement = document.createElement("select");

var option = document.createElement("option");
option.value = "original";
option.action = this._changeColorFormat.bind(this);
option.label = WebInspector.UIString("As Authored");
this.settingsSelectElement.appendChild(option);

var option = document.createElement("option");
option.value = "hex";
option.action = this._changeColorFormat.bind(this);
option.label = WebInspector.UIString("Hex Colors");
this.settingsSelectElement.appendChild(option);

option = document.createElement("option");
option.value = "rgb";
option.action = this._changeColorFormat.bind(this);
option.label = WebInspector.UIString("RGB Colors");
this.settingsSelectElement.appendChild(option);

option = document.createElement("option");
option.value = "hsl";
option.action = this._changeColorFormat.bind(this);
option.label = WebInspector.UIString("HSL Colors");
this.settingsSelectElement.appendChild(option);

this.settingsSelectElement.appendChild(document.createElement("hr"));

option = document.createElement("option");
option.action = this._createNewRule.bind(this);
option.label = WebInspector.UIString("New Style Rule");
this.settingsSelectElement.appendChild(option);

this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false);
this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);
var format = WebInspector.settings.colorFormat;
if (format === "original")
this.settingsSelectElement[0].selected = true;
else if (format === "hex")
this.settingsSelectElement[1].selected = true;
else if (format === "rgb")
this.settingsSelectElement[2].selected = true;
else if (format === "hsl")
this.settingsSelectElement[3].selected = true;

this.titleElement.appendChild(this.settingsSelectElement);
this._computedStylePane = computedStylePane;
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
}


WebInspector.StylesSidebarPane.InheritedProperties = [
"azimuth", "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "elevation",
"empty-cells", "font-family", "font-size", "font-style", "font-variant", "font-weight", "font", "letter-spacing",
"line-height", "list-style-image", "list-style-position", "list-style-type", "list-style", "orphans", "pitch-range",
"pitch", "quotes", "richness", "speak-header", "speak-numeral", "speak-punctuation", "speak", "speech-rate", "stress",
"text-align", "text-indent", "text-transform", "text-shadow", "visibility", "voice-family", "volume", "white-space", "widows", "word-spacing"
].keySet();





WebInspector.StylesSidebarPane.PseudoIdNames = [
"", "first-line", "first-letter", "before", "after", "selection", "", "-webkit-scrollbar", "-webkit-file-upload-button",
"-webkit-input-placeholder", "-webkit-slider-thumb", "-webkit-search-cancel-button", "-webkit-search-decoration",
"-webkit-search-results-decoration", "-webkit-search-results-button", "-webkit-media-controls-panel",
"-webkit-media-controls-play-button", "-webkit-media-controls-mute-button", "-webkit-media-controls-timeline",
"-webkit-media-controls-timeline-container", "-webkit-media-controls-volume-slider",
"-webkit-media-controls-volume-slider-container", "-webkit-media-controls-current-time-display",
"-webkit-media-controls-time-remaining-display", "-webkit-media-controls-seek-back-button", "-webkit-media-controls-seek-forward-button",
"-webkit-media-controls-fullscreen-button", "-webkit-media-controls-rewind-button", "-webkit-media-controls-return-to-realtime-button",
"-webkit-media-controls-toggle-closed-captions-button", "-webkit-media-controls-status-display", "-webkit-scrollbar-thumb",
"-webkit-scrollbar-button", "-webkit-scrollbar-track", "-webkit-scrollbar-track-piece", "-webkit-scrollbar-corner",
"-webkit-resizer", "-webkit-input-list-button", "-webkit-inner-spin-button", "-webkit-outer-spin-button"
];

WebInspector.StylesSidebarPane.prototype = {
_contextMenuEventFired: function(event)
{
var href = event.target.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || event.target.enclosingNodeOrSelfWithClass("webkit-html-external-link");
if (href) {
var contextMenu = new WebInspector.ContextMenu();
var filled = WebInspector.panels.elements.populateHrefContextMenu(contextMenu, event, href);
if (filled)
contextMenu.show(event);
}
},

update: function(node, editedSection, forceUpdate)
{
var refresh = false;

if (forceUpdate)
delete this.node;

if (!forceUpdate && (!node || node === this.node))
refresh = true;

if (node && node.nodeType === Node.TEXT_NODE && node.parentNode)
node = node.parentNode;

if (node && node.nodeType !== Node.ELEMENT_NODE)
node = null;

if (node)
this.node = node;
else
node = this.node;

if (!node) {
this.bodyElement.removeChildren();
this._computedStylePane.bodyElement.removeChildren();
this.sections = {};
return;
}

function stylesCallback(styles)
{
if (styles)
this._rebuildUpdate(node, styles);
}

function computedStyleCallback(computedStyle)
{
if (computedStyle)
this._refreshUpdate(node, computedStyle, editedSection);
}

if (refresh)
WebInspector.cssModel.getComputedStyleAsync(node.id, computedStyleCallback.bind(this));
else
WebInspector.cssModel.getStylesAsync(node.id, stylesCallback.bind(this));
},

_refreshUpdate: function(node, computedStyle, editedSection)
{
for (var pseudoId in this.sections) {
var styleRules = this._refreshStyleRules(this.sections[pseudoId], computedStyle);
var usedProperties = {};
var disabledComputedProperties = {};
this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties);
this._refreshSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, editedSection);
}

this.sections[0][0].rebuildComputedTrace(this.sections[0]);
},

_rebuildUpdate: function(node, styles)
{
this.bodyElement.removeChildren();
this._computedStylePane.bodyElement.removeChildren();

var styleRules = this._rebuildStyleRules(node, styles);
var usedProperties = {};
var disabledComputedProperties = {};
this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties);
this.sections[0] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, 0);
var anchorElement = this.sections[0].inheritedPropertiesSeparatorElement;

this.sections[0][0].rebuildComputedTrace(this.sections[0]);

for (var i = 0; i < styles.pseudoElements.length; ++i) {
var pseudoElementCSSRules = styles.pseudoElements[i];

styleRules = [];
var pseudoId = pseudoElementCSSRules.pseudoId;

var entry = { isStyleSeparator: true, pseudoId: pseudoId };
styleRules.push(entry);


for (var j = pseudoElementCSSRules.rules.length - 1; j >= 0; --j) {
var rule = pseudoElementCSSRules.rules[j];
styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, editable: !!(rule.style && rule.style.id) });
}
usedProperties = {};
disabledComputedProperties = {};
this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties);
this.sections[pseudoId] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, pseudoId, anchorElement);
}
},

_refreshStyleRules: function(sections, computedStyle)
{
var nodeComputedStyle = computedStyle;
var styleRules = [];
for (var i = 0; sections && i < sections.length; ++i) {
var section = sections[i];
if (section instanceof WebInspector.BlankStylePropertiesSection)
continue;
if (section.computedStyle)
section.styleRule.style = nodeComputedStyle;
var styleRule = { section: section, style: section.styleRule.style, computedStyle: section.computedStyle, rule: section.rule, editable: !!(section.styleRule.style && section.styleRule.style.id) };
styleRules.push(styleRule);
}
return styleRules;
},

_rebuildStyleRules: function(node, styles)
{
var nodeComputedStyle = styles.computedStyle;
this.sections = {};

var styleRules = [];

styleRules.push({ computedStyle: true, selectorText: "", style: nodeComputedStyle, editable: false });

var styleAttributes = {};
for (var name in styles.styleAttributes) {
var attrStyle = { style: styles.styleAttributes[name], editable: false };
attrStyle.selectorText = WebInspector.panels.elements.treeOutline.nodeNameToCorrectCase(node.nodeName) + "[" + name;
if (node.getAttribute(name))
attrStyle.selectorText += "=" + node.getAttribute(name);
attrStyle.selectorText += "]";
styleRules.push(attrStyle);
}


if (styles.inlineStyle && node.nodeType === Node.ELEMENT_NODE) {
var inlineStyle = { selectorText: "element.style", style: styles.inlineStyle, isAttribute: true };
styleRules.push(inlineStyle);
}


if (styles.matchedCSSRules.length)
styleRules.push({ isStyleSeparator: true, text: WebInspector.UIString("Matched CSS Rules") });
for (var i = styles.matchedCSSRules.length - 1; i >= 0; --i) {
var rule = styles.matchedCSSRules[i];
styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, editable: !!(rule.style && rule.style.id) });
}


var parentNode = node.parentNode;
function insertInheritedNodeSeparator(node)
{
var entry = {};
entry.isStyleSeparator = true;
entry.node = node;
styleRules.push(entry);
}

for (var parentOrdinal = 0; parentOrdinal < styles.inherited.length; ++parentOrdinal) {
var parentStyles = styles.inherited[parentOrdinal];
var separatorInserted = false;
if (parentStyles.inlineStyle) {
if (this._containsInherited(parentStyles.inlineStyle)) {
var inlineStyle = { selectorText: WebInspector.UIString("Style Attribute"), style: parentStyles.inlineStyle, isAttribute: true, isInherited: true };
if (!separatorInserted) {
insertInheritedNodeSeparator(parentNode);
separatorInserted = true;
}
styleRules.push(inlineStyle);
}
}

for (var i = parentStyles.matchedCSSRules.length - 1; i >= 0; --i) {
var rulePayload = parentStyles.matchedCSSRules[i];
if (!this._containsInherited(rulePayload.style))
continue;
var rule = rulePayload;
if (!separatorInserted) {
insertInheritedNodeSeparator(parentNode);
separatorInserted = true;
}
styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, isInherited: true, editable: !!(rule.style && rule.style.id) });
}
parentNode = parentNode.parentNode;
}
return styleRules;
},

_markUsedProperties: function(styleRules, usedProperties, disabledComputedProperties)
{
var priorityUsed = false;


for (var i = 0; i < styleRules.length; ++i) {
var styleRule = styleRules[i];
if (styleRule.computedStyle || styleRule.isStyleSeparator)
continue;
if (styleRule.section && styleRule.section.noAffect)
continue;

styleRule.usedProperties = {};

var style = styleRule.style;
var allProperties = style.allProperties;
for (var j = 0; j < allProperties.length; ++j) {
var property = allProperties[j];
if (!property.isLive)
continue;
var name = property.name;

if (!priorityUsed && property.priority.length)
priorityUsed = true;



if (!(name in usedProperties))
styleRule.usedProperties[name] = true;

if (name === "font") {



styleRule.usedProperties["font-family"] = true;
styleRule.usedProperties["font-size"] = true;
styleRule.usedProperties["font-style"] = true;
styleRule.usedProperties["font-variant"] = true;
styleRule.usedProperties["font-weight"] = true;
styleRule.usedProperties["line-height"] = true;
}
}



for (var name in styleRules[i].usedProperties)
usedProperties[name] = true;
}

if (priorityUsed) {

var foundPriorityProperties = [];


for (var i = (styleRules.length - 1); i >= 0; --i) {
if (styleRules[i].computedStyle || styleRules[i].isStyleSeparator)
continue;

var style = styleRules[i].style;
var allProperties = style.allProperties;
for (var j = 0; j < allProperties.length; ++j) {
var property = allProperties[j];
if (!property.isLive)
continue;
var name = property.name;
if (property.priority.length) {
if (!(name in foundPriorityProperties))
styleRules[i].usedProperties[name] = true;
else
delete styleRules[i].usedProperties[name];
foundPriorityProperties[name] = true;
} else if (name in foundPriorityProperties)
delete styleRules[i].usedProperties[name];
}
}
}
},

_refreshSectionsForStyleRules: function(styleRules, usedProperties, disabledComputedProperties, editedSection)
{

for (var i = 0; i < styleRules.length; ++i) {
var styleRule = styleRules[i];
var section = styleRule.section;
if (styleRule.computedStyle) {
section._disabledComputedProperties = disabledComputedProperties;
section._usedProperties = usedProperties;
section.update();
} else {
section._usedProperties = styleRule.usedProperties;
section.update(section === editedSection);
}
}
},

_rebuildSectionsForStyleRules: function(styleRules, usedProperties, disabledComputedProperties, pseudoId, anchorElement)
{

var sections = [];
var lastWasSeparator = true;
for (var i = 0; i < styleRules.length; ++i) {
var styleRule = styleRules[i];
if (styleRule.isStyleSeparator) {
var separatorElement = document.createElement("div");
separatorElement.className = "styles-sidebar-separator";
if (styleRule.node) {
var link = WebInspector.panels.elements.linkifyNodeReference(styleRule.node);
separatorElement.appendChild(document.createTextNode(WebInspector.UIString("Inherited from") + " "));
separatorElement.appendChild(link);
if (!sections.inheritedPropertiesSeparatorElement)
sections.inheritedPropertiesSeparatorElement = separatorElement;
} else if ("pseudoId" in styleRule) {
var pseudoName = WebInspector.StylesSidebarPane.PseudoIdNames[styleRule.pseudoId];
if (pseudoName)
separatorElement.textContent = WebInspector.UIString("Pseudo ::%s element", pseudoName);
else
separatorElement.textContent = WebInspector.UIString("Pseudo element");
} else
separatorElement.textContent = styleRule.text;
this.bodyElement.insertBefore(separatorElement, anchorElement);
lastWasSeparator = true;
continue;
}
var computedStyle = styleRule.computedStyle;


var editable = styleRule.editable;
if (typeof editable === "undefined")
editable = true;

if (computedStyle)
var section = new WebInspector.ComputedStylePropertiesSection(styleRule, usedProperties, disabledComputedProperties, styleRules);
else
var section = new WebInspector.StylePropertiesSection(styleRule, editable, styleRule.isInherited, lastWasSeparator);
section.pane = this;
section.expanded = true;

if (computedStyle) {
this._computedStylePane.bodyElement.appendChild(section.element);
lastWasSeparator = true;
} else {
this.bodyElement.insertBefore(section.element, anchorElement);
lastWasSeparator = false;
}
sections.push(section);
}
return sections;
},

_containsInherited: function(style)
{
var properties = style.allProperties;
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];

if (property.isLive && property.name in WebInspector.StylesSidebarPane.InheritedProperties)
return true;
}
return false;
},

_changeSetting: function(event)
{
var options = this.settingsSelectElement.options;
var selectedOption = options[this.settingsSelectElement.selectedIndex];
selectedOption.action(event);


var selectedIndex = 0;
for (var i = 0; i < options.length; ++i) {
if (options[i].value === WebInspector.settings.colorFormat) {
selectedIndex = i;
break;
}
}

this.settingsSelectElement.selectedIndex = selectedIndex;
},

_changeColorFormat: function(event)
{
var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
WebInspector.settings.colorFormat = selectedOption.value;

for (var pseudoId in this.sections) {
var sections = this.sections[pseudoId];
for (var i = 0; i < sections.length; ++i)
sections[i].update(true);
}
},

_createNewRule: function(event)
{
this.addBlankSection().startEditingSelector();
},

addBlankSection: function()
{
var blankSection = new WebInspector.BlankStylePropertiesSection(appropriateSelectorForNode(this.node, true));
blankSection.pane = this;

var elementStyleSection = this.sections[0][1];
this.bodyElement.insertBefore(blankSection.element, elementStyleSection.element.nextSibling);

this.sections[0].splice(2, 0, blankSection);

return blankSection;
},

removeSection: function(section)
{
for (var pseudoId in this.sections) {
var sections = this.sections[pseudoId];
var index = sections.indexOf(section);
if (index === -1)
continue;
sections.splice(index, 1);
if (section.element.parentNode)
section.element.parentNode.removeChild(section.element);
}
},

registerShortcuts: function()
{
var section = WebInspector.shortcutsHelp.section(WebInspector.UIString("Styles Pane"));
var shortcut = WebInspector.KeyboardShortcut;
var keys = [
shortcut.shortcutToString(shortcut.Keys.Tab),
shortcut.shortcutToString(shortcut.Keys.Tab, shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous property"));
keys = [
shortcut.shortcutToString(shortcut.Keys.Up),
shortcut.shortcutToString(shortcut.Keys.Down)
];
section.addRelatedKeys(keys, WebInspector.UIString("Increment/decrement value"));
keys = [
shortcut.shortcutToString(shortcut.Keys.Up, shortcut.Modifiers.Shift),
shortcut.shortcutToString(shortcut.Keys.Down, shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Increment/decrement by %f", 10));
keys = [
shortcut.shortcutToString(shortcut.Keys.PageUp),
shortcut.shortcutToString(shortcut.Keys.PageDown)
];
section.addRelatedKeys(keys, WebInspector.UIString("Increment/decrement by %f", 10));
keys = [
shortcut.shortcutToString(shortcut.Keys.PageUp, shortcut.Modifiers.Shift),
shortcut.shortcutToString(shortcut.Keys.PageDown, shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Increment/decrement by %f", 100));
keys = [
shortcut.shortcutToString(shortcut.Keys.PageUp, shortcut.Modifiers.Alt),
shortcut.shortcutToString(shortcut.Keys.PageDown, shortcut.Modifiers.Alt)
];
section.addRelatedKeys(keys, WebInspector.UIString("Increment/decrement by %f", 0.1));
}
}

WebInspector.StylesSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;

WebInspector.ComputedStyleSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Computed Style"));
var showInheritedCheckbox = new WebInspector.Checkbox(WebInspector.UIString("Show inherited"), "sidebar-pane-subtitle");
this.titleElement.appendChild(showInheritedCheckbox.element);

if (WebInspector.settings.showInheritedComputedStyleProperties) {
this.bodyElement.addStyleClass("show-inherited");
showInheritedCheckbox.checked = true;
}

function showInheritedToggleFunction(event)
{
WebInspector.settings.showInheritedComputedStyleProperties = showInheritedCheckbox.checked;
if (WebInspector.settings.showInheritedComputedStyleProperties)
this.bodyElement.addStyleClass("show-inherited");
else
this.bodyElement.removeStyleClass("show-inherited");
}

showInheritedCheckbox.addEventListener(showInheritedToggleFunction.bind(this));
}

WebInspector.ComputedStyleSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;

WebInspector.StylePropertiesSection = function(styleRule, editable, isInherited, isFirstSection)
{
WebInspector.PropertiesSection.call(this, "");
this.element.className = "styles-section monospace" + (isFirstSection ? " first-styles-section" : "");

this._selectorElement = document.createElement("span");
this._selectorElement.textContent = styleRule.selectorText;
this.titleElement.appendChild(this._selectorElement);
if (Preferences.debugMode)
this._selectorElement.addEventListener("click", this._debugShowStyle.bind(this), false);

var openBrace = document.createElement("span");
openBrace.textContent = " {";
this.titleElement.appendChild(openBrace);

var closeBrace = document.createElement("div");
closeBrace.textContent = "}";
this.element.appendChild(closeBrace);

this._selectorElement.addEventListener("dblclick", this._handleSelectorDoubleClick.bind(this), false);
this.element.addEventListener("dblclick", this._handleEmptySpaceDoubleClick.bind(this), false);

this.styleRule = styleRule;
this.rule = this.styleRule.rule;
this.editable = editable;
this.isInherited = isInherited;


var isUserAgent = this.rule && this.rule.isUserAgent;
var isUser = this.rule && this.rule.isUser;
var isViaInspector = this.rule && this.rule.isViaInspector;

if (isUserAgent || isUser)
this.editable = false;

this._usedProperties = styleRule.usedProperties;

if (this.rule)
this.titleElement.addStyleClass("styles-selector");

function linkifyUncopyable(url, line)
{
var link = WebInspector.linkifyResourceAsNode(url, "resources", line + 1);
link.setAttribute("data-uncopyable", link.textContent);
link.textContent = "";
return link;
}

var subtitle = "";
if (this.styleRule.sourceURL)
this.subtitleElement.appendChild(linkifyUncopyable(this.styleRule.sourceURL, this.rule.sourceLine));
else if (isUserAgent)
subtitle = WebInspector.UIString("user agent stylesheet");
else if (isUser)
subtitle = WebInspector.UIString("user stylesheet");
else if (isViaInspector)
subtitle = WebInspector.UIString("via inspector");
else if (this.rule && this.rule.sourceURL)
this.subtitleElement.appendChild(linkifyUncopyable(this.rule.sourceURL, this.rule.sourceLine));

if (isInherited)
this.element.addStyleClass("show-inherited"); 
if (subtitle)
this.subtitle = subtitle;

this.identifier = styleRule.selectorText;
if (this.subtitle)
this.identifier += ":" + this.subtitle;

if (!this.editable)
this.element.addStyleClass("read-only");
}

WebInspector.StylePropertiesSection.prototype = {
collapse: function(dontRememberState)
{

},

isPropertyInherited: function(propertyName)
{
if (this.isInherited) {


return !(propertyName in WebInspector.StylesSidebarPane.InheritedProperties);
}
return false;
},

isPropertyOverloaded: function(propertyName, shorthand)
{
if (!this._usedProperties || this.noAffect)
return false;

if (this.isInherited && !(propertyName in WebInspector.StylesSidebarPane.InheritedProperties)) {

return false;
}

var used = (propertyName in this._usedProperties);
if (used || !shorthand)
return !used;



var longhandProperties = this.styleRule.style.getLonghandProperties(propertyName);
for (var j = 0; j < longhandProperties.length; ++j) {
var individualProperty = longhandProperties[j];
if (individualProperty.name in this._usedProperties)
return false;
}

return true;
},

update: function(full)
{
if (full) {
this.propertiesTreeOutline.removeChildren();
this.populated = false;
} else {
var child = this.propertiesTreeOutline.children[0];
while (child) {
child.overloaded = this.isPropertyOverloaded(child.name, child.shorthand);
child = child.traverseNextTreeElement(false, null, true);
}
}
this.afterUpdate();
},

afterUpdate: function()
{
if (this._afterUpdate) {
this._afterUpdate(this);
delete this._afterUpdate;
}
},

onpopulate: function()
{
var style = this.styleRule.style;

var handledProperties = {};
var shorthandNames = {};

this.uniqueProperties = [];
var allProperties = style.allProperties;
for (var i = 0; i < allProperties.length; ++i)
this.uniqueProperties.push(allProperties[i]);


for (var i = 0; i < this.uniqueProperties.length; ++i) {
var property = this.uniqueProperties[i];
if (property.disabled)
continue;
if (property.shorthand)
shorthandNames[property.shorthand] = true;
}


for (var i = 0; i < this.uniqueProperties.length; ++i) {
var property = this.uniqueProperties[i];
var disabled = property.disabled;
if (!disabled && this.disabledComputedProperties && !(property.name in this.usedProperties) && property.name in this.disabledComputedProperties)
disabled = true;

var shorthand = !disabled ? property.shorthand : null;

if (shorthand && shorthand in handledProperties)
continue;

if (shorthand) {
property = style.getLiveProperty(shorthand);
if (!property)
property = new WebInspector.CSSProperty(style, style.allProperties.length, shorthand, style.getShorthandValue(shorthand), style.getShorthandPriority(shorthand), "style", true, true, "");
}

var isShorthand = !!(property.isLive && (shorthand || shorthandNames[property.name]));
var inherited = this.isPropertyInherited(property.name);
var overloaded = this.isPropertyOverloaded(property.name, isShorthand);

var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, property, isShorthand, inherited, overloaded);
this.propertiesTreeOutline.appendChild(item);
handledProperties[property.name] = property;
}
},

findTreeElementWithName: function(name)
{
var treeElement = this.propertiesTreeOutline.children[0];
while (treeElement) {
if (treeElement.name === name)
return treeElement;
treeElement = treeElement.traverseNextTreeElement(true, null, true);
}
return null;
},

addNewBlankProperty: function(optionalIndex)
{
var style = this.styleRule.style;
var property = style.newBlankProperty();
var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, property, false, false, false);
this.propertiesTreeOutline.appendChild(item);
item.listItemElement.textContent = "";
item._newProperty = true;
return item;
},

_debugShowStyle: function(anchor)
{
var boundHandler;
function removeStyleBox(element, event)
{
if (event.target === element) {
event.stopPropagation();
return;
}
document.body.removeChild(element);
document.getElementById("main").removeEventListener("mousedown", boundHandler, true);
}

if (!event.shiftKey)
return;

var container = document.createElement("div");
var element = document.createElement("span");
container.appendChild(element);
element.style.background = "yellow";
element.style.display = "inline-block";
container.style.cssText = "z-index: 2000000; position: absolute; top: 50px; left: 50px; white-space: pre; overflow: auto; background: white; font-family: monospace; font-size: 12px; border: 1px solid black; opacity: 0.85; -webkit-user-select: text; padding: 2px;";
container.style.width = (document.body.offsetWidth - 100) + "px";
container.style.height = (document.body.offsetHeight - 100) + "px";
document.body.appendChild(container);
if (this.rule)
element.textContent = this.rule.selectorText + " {" + ((this.styleRule.style.cssText !== undefined) ? this.styleRule.style.cssText : "<no cssText>") + "}";
else
element.textContent = this.styleRule.style.cssText;
boundHandler = removeStyleBox.bind(null, container);
document.getElementById("main").addEventListener("mousedown", boundHandler, true);
},

_handleEmptySpaceDoubleClick: function(event)
{
if (event.target.hasStyleClass("header")) {
event.stopPropagation();
return;
}
this.expand();
this.addNewBlankProperty().startEditing();
},

_handleSelectorClick: function(event)
{
event.stopPropagation();
},

_handleSelectorDoubleClick: function(event)
{
this._startEditingOnMouseEvent();
event.stopPropagation();
},

_startEditingOnMouseEvent: function()
{
if (!this.editable)
return;

if (!this.rule && this.propertiesTreeOutline.children.length === 0) {
this.expand();
this.addNewBlankProperty().startEditing();
return;
}

if (!this.rule)
return;

this.startEditingSelector();
},

startEditingSelector: function()
{
var element = this._selectorElement;
if (WebInspector.isBeingEdited(element))
return;

WebInspector.startEditing(this._selectorElement, this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this), null);
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},

editingSelectorCommitted: function(element, newContent, oldContent, context, moveDirection)
{
function moveToNextIfNeeded() {
if (!moveDirection || moveDirection !== "forward")
return;

this.expand();
if (this.propertiesTreeOutline.children.length === 0)
this.addNewBlankProperty().startEditing();
else {
var item = this.propertiesTreeOutline.children[0]
item.startEditing(item.valueElement);
}
}

if (newContent === oldContent)
return moveToNextIfNeeded.call(this);

var self = this;

function successCallback(newRule, doesAffectSelectedNode)
{
if (!doesAffectSelectedNode) {
self.noAffect = true;
self.element.addStyleClass("no-affect");
} else {
delete self.noAffect;
self.element.removeStyleClass("no-affect");
}

self.rule = newRule;
self.styleRule = { section: self, style: newRule.style, selectorText: newRule.selectorText, sourceURL: newRule.sourceURL, rule: newRule };

var oldIdentifier = this.identifier;
self.identifier = newRule.selectorText + ":" + self.subtitleElement.textContent;

self.pane.update();

WebInspector.panels.elements.renameSelector(oldIdentifier, this.identifier, oldContent, newContent);

moveToNextIfNeeded.call(self);
}

var focusedNode = WebInspector.panels.elements.focusedDOMNode;
WebInspector.cssModel.setRuleSelector(this.rule.id, focusedNode ? focusedNode.id : 0, newContent, successCallback, moveToNextIfNeeded.bind(this));
},

editingSelectorCancelled: function()
{

}
}

WebInspector.StylePropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;

WebInspector.ComputedStylePropertiesSection = function(styleRule, usedProperties, disabledComputedProperties)
{
WebInspector.PropertiesSection.call(this, "");
this.headerElement.addStyleClass("hidden");
this.element.className = "styles-section monospace first-styles-section read-only computed-style";
this.styleRule = styleRule;
this._usedProperties = usedProperties;
this._disabledComputedProperties = disabledComputedProperties;
this._alwaysShowComputedProperties = { "display": true, "height": true, "width": true };
this.computedStyle = true;
this._propertyTreeElements = {};
this._expandedPropertyNames = {};
}

WebInspector.ComputedStylePropertiesSection.prototype = {
collapse: function(dontRememberState)
{

},

_isPropertyInherited: function(propertyName)
{
return !(propertyName in this._usedProperties) && !(propertyName in this._alwaysShowComputedProperties) && !(propertyName in this._disabledComputedProperties);
},

update: function()
{
this._expandedPropertyNames = {};
for (var name in this._propertyTreeElements) {
if (this._propertyTreeElements[name].expanded)
this._expandedPropertyNames[name] = true;
}
this._propertyTreeElements = {};
this.propertiesTreeOutline.removeChildren();
this.populated = false;
},

onpopulate: function()
{
function sorter(a, b)
{
return a.name.localeCompare(b.name);
}

var style = this.styleRule.style;
var uniqueProperties = [];
var allProperties = style.allProperties;
for (var i = 0; i < allProperties.length; ++i)
uniqueProperties.push(allProperties[i]);
uniqueProperties.sort(sorter);

this._propertyTreeElements = {};
for (var i = 0; i < uniqueProperties.length; ++i) {
var property = uniqueProperties[i];
var inherited = this._isPropertyInherited(property.name);
var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, property, false, inherited, false);
this.propertiesTreeOutline.appendChild(item);
this._propertyTreeElements[property.name] = item;
}
},

rebuildComputedTrace: function(sections)
{
for (var i = 0; i < sections.length; ++i) {
var section = sections[i];
if (section.computedStyle || section instanceof WebInspector.BlankStylePropertiesSection)
continue;

for (var j = 0; j < section.uniqueProperties.length; ++j) {
var property = section.uniqueProperties[j];
if (property.disabled)
continue;
if (section.isInherited && !(property.name in WebInspector.StylesSidebarPane.InheritedProperties))
continue;

var treeElement = this._propertyTreeElements[property.name];
if (treeElement) {
var selectorText = section.styleRule.selectorText;
var value = property.value;
var title = "<span style='color: gray'>" + selectorText + "</span> - " + value;
var subtitle = " <span style='float:right'>" + section.subtitleElement.innerHTML + "</span>";
var childElement = new TreeElement(null, null, false);
childElement.titleHTML = title + subtitle;
treeElement.appendChild(childElement);
if (section.isPropertyOverloaded(property.name))
childElement.listItemElement.addStyleClass("overloaded");
}
}
}


for (var name in this._expandedPropertyNames) {
if (name in this._propertyTreeElements)
this._propertyTreeElements[name].expand();
}
}
}

WebInspector.ComputedStylePropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;

WebInspector.BlankStylePropertiesSection = function(defaultSelectorText)
{
WebInspector.StylePropertiesSection.call(this, {selectorText: defaultSelectorText, rule: {isViaInspector: true}}, true, false, false);
this.element.addStyleClass("blank-section");
}

WebInspector.BlankStylePropertiesSection.prototype = {
expand: function()
{

},

editingSelectorCommitted: function(element, newContent, oldContent, context)
{
var self = this;
function successCallback(newRule, doesSelectorAffectSelectedNode)
{
var styleRule = { section: self, style: newRule.style, selectorText: newRule.selectorText, sourceURL: newRule.sourceURL, rule: newRule };
self.makeNormal(styleRule);

if (!doesSelectorAffectSelectedNode) {
self.noAffect = true;
self.element.addStyleClass("no-affect");
}

self.subtitleElement.textContent = WebInspector.UIString("via inspector");
self.expand();

self.addNewBlankProperty().startEditing();
}

WebInspector.cssModel.addRule(this.pane.node.id, newContent, successCallback, this.editingSelectorCancelled.bind(this));
},

editingSelectorCancelled: function()
{
this.pane.removeSection(this);
},

makeNormal: function(styleRule)
{
this.element.removeStyleClass("blank-section");
this.styleRule = styleRule;
this.rule = styleRule.rule;
this.identifier = styleRule.selectorText + ":via inspector";
this.__proto__ = WebInspector.StylePropertiesSection.prototype;
}
}

WebInspector.BlankStylePropertiesSection.prototype.__proto__ = WebInspector.StylePropertiesSection.prototype;

WebInspector.StylePropertyTreeElement = function(styleRule, style, property, shorthand, inherited, overloaded)
{
this._styleRule = styleRule;
this.style = style;
this.property = property;
this.shorthand = shorthand;
this._inherited = inherited;
this._overloaded = overloaded;


TreeElement.call(this, "", null, shorthand);
}

WebInspector.StylePropertyTreeElement.prototype = {
get inherited()
{
return this._inherited;
},

set inherited(x)
{
if (x === this._inherited)
return;
this._inherited = x;
this.updateState();
},

get overloaded()
{
return this._overloaded;
},

set overloaded(x)
{
if (x === this._overloaded)
return;
this._overloaded = x;
this.updateState();
},

get disabled()
{
return this.property.disabled;
},

get name()
{
if (!this.disabled || !this.property.text)
return this.property.name;

var text = this.property.text;
var index = text.indexOf(":");
if (index < 1)
return this.property.name;

return text.substring(0, index).trim();
},

get priority()
{
if (this.disabled)
return ""; 
return this.property.priority;
},

get value()
{
if (!this.disabled || !this.property.text)
return this.property.value;

var match = this.property.text.match(/(.*);\s*/);
if (!match || !match[1])
return this.property.value;

var text = match[1];
var index = text.indexOf(":");
if (index < 1)
return this.property.value;

return text.substring(index + 1).trim();
},

get parsedOk()
{
return this.property.parsedOk;
},

onattach: function()
{
this.updateTitle();
},

updateTitle: function()
{
var value = this.value;

this.updateState();

var enabledCheckboxElement;
if (this.parsedOk) {
enabledCheckboxElement = document.createElement("input");
enabledCheckboxElement.className = "enabled-button";
enabledCheckboxElement.type = "checkbox";
enabledCheckboxElement.checked = !this.disabled;
enabledCheckboxElement.addEventListener("change", this.toggleEnabled.bind(this), false);
}

var nameElement = document.createElement("span");
nameElement.className = "webkit-css-property";
nameElement.textContent = this.name;
this.nameElement = nameElement;

var valueElement = document.createElement("span");
valueElement.className = "value";
this.valueElement = valueElement;

if (value) {
var self = this;

function processValue(regex, processor, nextProcessor, valueText)
{
var container = document.createDocumentFragment();

var items = valueText.replace(regex, "\0$1\0").split("\0");
for (var i = 0; i < items.length; ++i) {
if ((i % 2) === 0) {
if (nextProcessor)
container.appendChild(nextProcessor(items[i]));
else
container.appendChild(document.createTextNode(items[i]));
} else {
var processedNode = processor(items[i]);
if (processedNode)
container.appendChild(processedNode);
}
}

return container;
}

function linkifyURL(url)
{
var hrefUrl = url;
var match = hrefUrl.match(/['"]?([^'"]+)/);
if (match)
hrefUrl = match[1];
var container = document.createDocumentFragment();
container.appendChild(document.createTextNode("url("));
if (self._styleRule.sourceURL)
hrefUrl = WebInspector.completeURL(self._styleRule.sourceURL, hrefUrl);
else if (WebInspector.panels.elements.focusedDOMNode)
hrefUrl = WebInspector.resourceURLForRelatedNode(WebInspector.panels.elements.focusedDOMNode, hrefUrl);
var hasResource = !!WebInspector.resourceForURL(hrefUrl);

container.appendChild(WebInspector.linkifyURLAsNode(hrefUrl, url, null, hasResource));
container.appendChild(document.createTextNode(")"));
return container;
}

function processColor(text)
{
try {
var color = new WebInspector.Color(text);
} catch (e) {
return document.createTextNode(text);
}

var swatchElement = document.createElement("span");
swatchElement.title = WebInspector.UIString("Click to change color format");
swatchElement.className = "swatch";
swatchElement.style.setProperty("background-color", text);

swatchElement.addEventListener("click", changeColorDisplay, false);
swatchElement.addEventListener("dblclick", function(event) { event.stopPropagation() }, false);

var format;
if (WebInspector.settings.colorFormat === "original")
format = "original";
else if (Preferences.showColorNicknames && color.nickname)
format = "nickname";
else if (WebInspector.settings.colorFormat === "rgb")
format = (color.simple ? "rgb" : "rgba");
else if (WebInspector.settings.colorFormat === "hsl")
format = (color.simple ? "hsl" : "hsla");
else if (color.simple)
format = (color.hasShortHex() ? "shorthex" : "hex");
else
format = "rgba";

var colorValueElement = document.createElement("span");
colorValueElement.textContent = color.toString(format);

function nextFormat(curFormat)
{








switch (curFormat) {
case "original":
return color.simple ? "rgb" : "rgba";

case "rgb":
case "rgba":
return color.simple ? "hsl" : "hsla";

case "hsl":
case "hsla":
if (color.nickname)
return "nickname";
if (color.simple)
return color.hasShortHex() ? "shorthex" : "hex";
else
return "original";

case "shorthex":
return "hex";

case "hex":
return "original";

case "nickname":
if (color.simple)
return color.hasShortHex() ? "shorthex" : "hex";
else
return "original";

default:
return null;
}
}

function changeColorDisplay(event)
{
do {
format = nextFormat(format);
var currentValue = color.toString(format || "");
} while (format && currentValue === color.value && format !== "original");

if (format)
colorValueElement.textContent = currentValue;
}

var container = document.createDocumentFragment();
container.appendChild(swatchElement);
container.appendChild(colorValueElement);
return container;
}

var colorRegex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\b\w+\b(?!-))/g;
var colorProcessor = processValue.bind(window, colorRegex, processColor, null);

valueElement.appendChild(processValue(/url\(\s*([^)\s]+)\s*\)/g, linkifyURL, colorProcessor, value));
}

this.listItemElement.removeChildren();

if (!this.treeOutline)
return;


if (enabledCheckboxElement && this.treeOutline.section && this.treeOutline.section.editable && this.parent.root)
this.listItemElement.appendChild(enabledCheckboxElement);
this.listItemElement.appendChild(nameElement);
this.listItemElement.appendChild(document.createTextNode(": "));
this.listItemElement.appendChild(valueElement);
this.listItemElement.appendChild(document.createTextNode(";"));

if (!this.parsedOk)
this.listItemElement.addStyleClass("not-parsed-ok");
if (this.property.inactive)
this.listItemElement.addStyleClass("inactive");

this.tooltip = this.property.propertyText;
},

updateAll: function(updateAllRules)
{
if (!this.treeOutline)
return;
if (updateAllRules && this.treeOutline.section && this.treeOutline.section.pane)
this.treeOutline.section.pane.update(null, this.treeOutline.section);
else if (this.treeOutline.section)
this.treeOutline.section.update(true);
else
this.updateTitle(); 
},

toggleEnabled: function(event)
{
var disabled = !event.target.checked;

function callback(newStyle)
{
if (!newStyle)
return;

this.style = newStyle;
this._styleRule.style = newStyle;

if (this.treeOutline.section && this.treeOutline.section.pane)
this.treeOutline.section.pane.dispatchEventToListeners("style property toggled");

this.updateAll(true);
}

this.property.setDisabled(disabled, callback.bind(this));
},

updateState: function()
{
if (!this.listItemElement)
return;

if (this.style.isPropertyImplicit(this.name) || this.value === "initial")
this.listItemElement.addStyleClass("implicit");
else
this.listItemElement.removeStyleClass("implicit");

this.selectable = !this.inherited;
if (this.inherited)
this.listItemElement.addStyleClass("inherited");
else
this.listItemElement.removeStyleClass("inherited");

if (this.overloaded)
this.listItemElement.addStyleClass("overloaded");
else
this.listItemElement.removeStyleClass("overloaded");

if (this.disabled)
this.listItemElement.addStyleClass("disabled");
else
this.listItemElement.removeStyleClass("disabled");
},

onpopulate: function()
{

if (this.children.length || !this.shorthand)
return;

var longhandProperties = this.style.getLonghandProperties(this.name);
for (var i = 0; i < longhandProperties.length; ++i) {
var name = longhandProperties[i].name;


if (this.treeOutline.section) {
var inherited = this.treeOutline.section.isPropertyInherited(name);
var overloaded = this.treeOutline.section.isPropertyOverloaded(name);
}

var liveProperty = this.style.getLiveProperty(name);
var item = new WebInspector.StylePropertyTreeElement(this._styleRule, this.style, liveProperty, false, inherited, overloaded);
this.appendChild(item);
}
},

ondblclick: function(event)
{
this.startEditing(event.target);
event.stopPropagation();
},

restoreNameElement: function()
{

if (this.nameElement === this.listItemElement.querySelector(".webkit-css-property"))
return;

this.nameElement = document.createElement("span");
this.nameElement.className = "webkit-css-property";
this.nameElement.textContent = "";
this.listItemElement.insertBefore(this.nameElement, this.listItemElement.firstChild);
},

startEditing: function(selectElement)
{

if (this.parent.shorthand)
return;

if (WebInspector.isBeingEdited(this.listItemElement) || (this.treeOutline.section && !this.treeOutline.section.editable))
return;

var context = {
expanded: this.expanded,
hasChildren: this.hasChildren,
keyDownListener: this.editingKeyDown.bind(this),
keyPressListener: this.editingKeyPress.bind(this)
};


this.hasChildren = false;

if (!selectElement)
selectElement = this.listItemElement;

this.listItemElement.addEventListener("keydown", context.keyDownListener, false);
this.listItemElement.addEventListener("keypress", context.keyPressListener, false);

WebInspector.startEditing(this.listItemElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
},

editingKeyPress: function(event)
{
var selection = window.getSelection();
var colonIndex = this.listItemElement.textContent.indexOf(":");
var selectionLeftOffset = event.target.selectionLeftOffset;

if (colonIndex < 0 || selectionLeftOffset <= colonIndex) {

var character = event.data.toLowerCase();
if (character && /[a-z-]/.test(character)) {
var prefix = selection.anchorNode.textContent.substring(0, selection.anchorOffset);
var property = WebInspector.CSSCompletions.firstStartsWith(prefix + character);

if (!selection.isCollapsed)
selection.deleteFromDocument();

this.restoreNameElement();

if (property) {
if (property !== this.nameElement.textContent)
this.nameElement.textContent = property;
this.nameElement.firstChild.select(prefix.length + 1);
event.preventDefault();
}
}
} else {

}
},

editingKeyDown: function(event)
{
var arrowKeyPressed = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down");
var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
if (!arrowKeyPressed && !pageKeyPressed)
return;

var selection = window.getSelection();
if (!selection.rangeCount)
return;

var selectionRange = selection.getRangeAt(0);
if (selectionRange.commonAncestorContainer !== this.listItemElement && !selectionRange.commonAncestorContainer.isDescendant(this.listItemElement))
return;


var text = event.target.textContent.trim();
var openQuote;
var wasEscape = false;

for (var i = 0; i < text.length - 1; ++i) {
var ch = text.charAt(i);
if (ch === "\\") {
wasEscape = true;
continue;
}
if (ch === ";" && !openQuote)
return; 
if ((ch === "'" || ch === "\"") && !wasEscape) {
if (!openQuote)
openQuote = ch;
else if (ch === openQuote)
openQuote = null;
}
wasEscape = false;
}

const styleValueDelimeters = " \t\n\"':;,/()";
var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.listItemElement);
var wordString = wordRange.toString();
var replacementString = wordString;

var matches = /(.*?)(-?\d+(?:\.\d+)?)(.*)/.exec(wordString);
if (matches && matches.length) {
var prefix = matches[1];
var number = parseFloat(matches[2]);
var suffix = matches[3];


var numberNearZero = (number < 1 && number > -1);
if (number === 1 && event.keyIdentifier === "Down")
numberNearZero = true;
else if (number === -1 && event.keyIdentifier === "Up")
numberNearZero = true;

if (numberNearZero && event.altKey && arrowKeyPressed) {
if (event.keyIdentifier === "Down")
number = Math.ceil(number - 1);
else
number = Math.floor(number + 1);
} else {


var changeAmount = 1;
if (event.shiftKey && pageKeyPressed)
changeAmount = 100;
else if (event.shiftKey || pageKeyPressed)
changeAmount = 10;
else if (event.altKey || numberNearZero)
changeAmount = 0.1;

if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown")
changeAmount *= -1;



number = Number((number + changeAmount).toFixed(6));
}

replacementString = prefix + number + suffix;
} else if (selection.containsNode(this.nameElement, true)) {
var prefix = selectionRange.startContainer.textContent.substring(0, selectionRange.startOffset);
var property;

if (event.keyIdentifier === "Up")
property = WebInspector.CSSCompletions.previous(wordString, prefix);
else if (event.keyIdentifier === "Down")
property = WebInspector.CSSCompletions.next(wordString, prefix);

var startOffset = selectionRange.startOffset;
if (property) {
this.nameElement.textContent = property;
this.nameElement.firstChild.select(startOffset);
}
event.preventDefault();
return;
} else {

}

var replacementTextNode = document.createTextNode(replacementString);

wordRange.deleteContents();
wordRange.insertNode(replacementTextNode);

var finalSelectionRange = document.createRange();
finalSelectionRange.setStart(replacementTextNode, 0);
finalSelectionRange.setEnd(replacementTextNode, replacementString.length);

selection.removeAllRanges();
selection.addRange(finalSelectionRange);

event.preventDefault();

if (!("originalPropertyText" in this)) {


this.originalPropertyText = this.property.propertyText;
}
this.applyStyleText(this.listItemElement.textContent);
},

editingEnded: function(context)
{
this.hasChildren = context.hasChildren;
if (context.expanded)
this.expand();
this.listItemElement.removeEventListener("keydown", context.keyDownListener, false);
this.listItemElement.removeEventListener("keypress", context.keyPressListener, false);
delete this.originalPropertyText;
},

editingCancelled: function(element, context)
{
if ("originalPropertyText" in this)
this.applyStyleText(this.originalPropertyText, true);
else {
if (this._newProperty)
this.treeOutline.removeChild(this);
else
this.updateTitle();
}
this.editingEnded(context);
},

editingCommitted: function(element, userInput, previousContent, context, moveDirection)
{
this.editingEnded(context);


var newProperty, moveToPropertyName, moveToSelector;
var moveTo = this;
do {
moveTo = (moveDirection === "forward" ? moveTo.nextSibling : moveTo.previousSibling);
} while(moveTo && !moveTo.selectable);

if (moveTo)
moveToPropertyName = moveTo.name;
else if (moveDirection === "forward")
newProperty = true;
else if (moveDirection === "backward" && this.treeOutline.section.rule)
moveToSelector = true;


var blankInput = /^\s*$/.test(userInput);
if (userInput !== previousContent || (this._newProperty && blankInput)) { 
this.treeOutline.section._afterUpdate = moveToNextCallback.bind(this, this._newProperty, !blankInput);
this.applyStyleText(userInput, true);
} else
moveToNextCallback(this._newProperty, false, this.treeOutline.section, false);


function moveToNextCallback(alreadyNew, valueChanged, section)
{
if (!moveDirection)
return;


if (moveTo && moveTo.parent) {
moveTo.startEditing(moveTo.valueElement);
return;
}





if (moveTo && !moveTo.parent) {
var treeElement = section.findTreeElementWithName(moveToPropertyName);
if (treeElement)
treeElement.startEditing(treeElement.valueElement);
return;
}


if (newProperty) {
if (alreadyNew && !valueChanged)
return;

section.addNewBlankProperty().startEditing();
return;
}

if (moveToSelector)
section.startEditingSelector();
}
},

applyStyleText: function(styleText, updateInterface)
{
var section = this.treeOutline.section;
var elementsPanel = WebInspector.panels.elements;
styleText = styleText.replace(/\s/g, " ").trim(); 
var styleTextLength = styleText.length;
if (!styleTextLength && updateInterface) {
if (this._newProperty) {

this.parent.removeChild(this);
section.afterUpdate();
return;
} else
delete section._afterUpdate;
}

function callback(newStyle)
{
if (!newStyle) {



if (this._newProperty) {
this.parent.removeChild(this);
return;
}
if (updateInterface)
this.updateTitle();
return;
}

this.style = newStyle;
this.property = newStyle.propertyAt(this.property.index);
this._styleRule.style = this.style;

if (section && section.pane)
section.pane.dispatchEventToListeners("style edited");

if (updateInterface)
this.updateAll(true);
}



if (styleText.length && !/;\s*$/.test(styleText))
styleText += ";";
this.property.setText(styleText, updateInterface, callback.bind(this));
}
}

WebInspector.StylePropertyTreeElement.prototype.__proto__ = TreeElement.prototype;





WebInspector.PanelEnablerView = function(identifier, headingText, disclaimerText, buttonTitle)
{
WebInspector.View.call(this);

this.element.addStyleClass("panel-enabler-view");
this.element.addStyleClass(identifier);

this.contentElement = document.createElement("div");
this.contentElement.className = "panel-enabler-view-content";
this.element.appendChild(this.contentElement);

this.imageElement = document.createElement("img");
this.contentElement.appendChild(this.imageElement);

this.choicesForm = document.createElement("form");
this.contentElement.appendChild(this.choicesForm);

this.headerElement = document.createElement("h1");
this.headerElement.textContent = headingText;
this.choicesForm.appendChild(this.headerElement);

var self = this;
function enableOption(text, checked) {
var label = document.createElement("label");
var option = document.createElement("input");
option.type = "radio";
option.name = "enable-option";
if (checked)
option.checked = true;
label.appendChild(option);
label.appendChild(document.createTextNode(text));
self.choicesForm.appendChild(label);
return option;
};

this.enabledForSession = enableOption(WebInspector.UIString("Only enable for this session"), true);
this.enabledAlways = enableOption(WebInspector.UIString("Always enable"));

this.disclaimerElement = document.createElement("div");
this.disclaimerElement.className = "panel-enabler-disclaimer";
this.disclaimerElement.textContent = disclaimerText;
this.choicesForm.appendChild(this.disclaimerElement);

this.enableButton = document.createElement("button");
this.enableButton.setAttribute("type", "button");
this.enableButton.textContent = buttonTitle;
this.enableButton.addEventListener("click", this._enableButtonCicked.bind(this), false);
this.choicesForm.appendChild(this.enableButton);
}

WebInspector.PanelEnablerView.prototype = {
_enableButtonCicked: function()
{
this.dispatchEventToListeners("enable clicked");
},

show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);

setTimeout(this.resize.bind(this), 0);
},

resize: function()
{
this.imageElement.removeStyleClass("hidden");

if (this.element.offsetWidth < (this.choicesForm.offsetWidth + this.imageElement.offsetWidth))
this.imageElement.addStyleClass("hidden");
},

get alwaysEnabled() {
return this.enabledAlways.checked;
}
}

WebInspector.PanelEnablerView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.WelcomeView = function(identifier, headingText, instructionsText)
{
WebInspector.View.call(this);

this.element.addStyleClass("panel-enabler-view");
this.element.addStyleClass(identifier);
this.element.addStyleClass("welcome");

this.contentElement = document.createElement("div");
this.contentElement.className = "panel-enabler-view-content";
this.element.appendChild(this.contentElement);

this.alignerElement = document.createElement("div");
this.alignerElement.className = "welcome-instructions-aligner";
this.contentElement.appendChild(this.alignerElement);

this.instructionsElement = document.createElement("div");
this.instructionsElement.className = "instructions";
this.contentElement.appendChild(this.instructionsElement);

this.headerElement = document.createElement("h1");
this.headerElement.textContent = headingText;
this.instructionsElement.appendChild(this.headerElement);

if (instructionsText)
this.addMessage(instructionsText);
}

WebInspector.WelcomeView.prototype = {
addMessage: function(message)
{
var messageElement = document.createElement("div");
messageElement.className = "message";
if (typeof message == "string")


messageElement.innerHTML = message;
else
messageElement.appendChild(message);
this.instructionsElement.appendChild(messageElement);
}
}

WebInspector.WelcomeView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.StatusBarButton = function(title, className, states)
{
this.element = document.createElement("button");
this.element.className = className + " status-bar-item";
this.element.addEventListener("click", this._clicked.bind(this), false);

this.glyph = document.createElement("div");
this.glyph.className = "glyph";
this.element.appendChild(this.glyph);

this.glyphShadow = document.createElement("div");
this.glyphShadow.className = "glyph shadow";
this.element.appendChild(this.glyphShadow);

this.states = states;
if (!states)
this.states = 2;

if (states == 2)
this._state = false;
else
this._state = 0;

this.title = title;
this.disabled = false;
this._visible = true;
}

WebInspector.StatusBarButton.prototype = {
_clicked: function()
{
this.dispatchEventToListeners("click");
},

get disabled()
{
return this._disabled;
},

set disabled(x)
{
if (this._disabled === x)
return;
this._disabled = x;
this.element.disabled = x;
},

get title()
{
return this._title;
},

set title(x)
{
if (this._title === x)
return;
this._title = x;
this.element.title = x;
},

get state()
{
return this._state;
},

set state(x)
{
if (this._state === x)
return;

if (this.states === 2) {
if (x)
this.element.addStyleClass("toggled-on");
else
this.element.removeStyleClass("toggled-on");
} else {
if (x !== 0) {
this.element.removeStyleClass("toggled-" + this._state);
this.element.addStyleClass("toggled-" + x);
} else 
this.element.removeStyleClass("toggled-" + this._state);
}
this._state = x;
},

get toggled()
{
if (this.states !== 2)
throw("Only used toggled when there are 2 states, otherwise, use state");
return this.state;
},

set toggled(x)
{
if (this.states !== 2)
throw("Only used toggled when there are 2 states, otherwise, use state");
this.state = x;
},

get visible()
{
return this._visible;
},

set visible(x)
{
if (this._visible === x)
return;

if (x)
this.element.removeStyleClass("hidden");
else
this.element.addStyleClass("hidden");
this._visible = x;
}
}

WebInspector.StatusBarButton.prototype.__proto__ = WebInspector.Object.prototype;





WebInspector.SummaryBar = function(categories)
{
this.categories = categories;

this.element = document.createElement("div");
this.element.className = "summary-bar";

this.graphElement = document.createElement("canvas");
this.graphElement.setAttribute("width", "450");
this.graphElement.setAttribute("height", "38");
this.graphElement.className = "summary-graph";
this.element.appendChild(this.graphElement);

this.legendElement = document.createElement("div");
this.legendElement.className = "summary-graph-legend";
this.element.appendChild(this.legendElement);
}

WebInspector.SummaryBar.prototype = {

get calculator() {
return this._calculator;
},

set calculator(x) {
this._calculator = x;
},

reset: function()
{
this.legendElement.removeChildren();
this._drawSummaryGraph();
},

update: function(data)
{
var graphInfo = this.calculator.computeSummaryValues(data);

var fillSegments = [];

this.legendElement.removeChildren();

for (var category in this.categories) {
var size = graphInfo.categoryValues[category];
if (!size)
continue;

var colorString = this.categories[category].color;

var fillSegment = {color: colorString, value: size};
fillSegments.push(fillSegment);

var legendLabel = this._makeLegendElement(this.categories[category].title, this.calculator.formatValue(size), colorString);
this.legendElement.appendChild(legendLabel);
}

if (graphInfo.total) {
var totalLegendLabel = this._makeLegendElement(WebInspector.UIString("Total"), this.calculator.formatValue(graphInfo.total));
totalLegendLabel.addStyleClass("total");
this.legendElement.appendChild(totalLegendLabel);
}

this._drawSummaryGraph(fillSegments);
},

_drawSwatch: function(canvas, color)
{
var ctx = canvas.getContext("2d");

function drawSwatchSquare() {
ctx.fillStyle = color;
ctx.fillRect(0, 0, 13, 13);

var gradient = ctx.createLinearGradient(0, 0, 13, 13);
gradient.addColorStop(0.0, "rgba(255, 255, 255, 0.2)");
gradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");

ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 13, 13);

gradient = ctx.createLinearGradient(13, 13, 0, 0);
gradient.addColorStop(0.0, "rgba(0, 0, 0, 0.2)");
gradient.addColorStop(1.0, "rgba(0, 0, 0, 0.0)");

ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 13, 13);

ctx.strokeStyle = "rgba(0, 0, 0, 0.6)";
ctx.strokeRect(0.5, 0.5, 12, 12);
}

ctx.clearRect(0, 0, 13, 24);

drawSwatchSquare();

ctx.save();

ctx.translate(0, 25);
ctx.scale(1, -1);

drawSwatchSquare();

ctx.restore();

this._fadeOutRect(ctx, 0, 13, 13, 13, 0.5, 0.0);
},

_drawSummaryGraph: function(segments)
{
if (!segments || !segments.length) {
segments = [{color: "white", value: 1}];
this._showingEmptySummaryGraph = true;
} else
delete this._showingEmptySummaryGraph;


var total = 0;
for (var i = 0; i < segments.length; ++i)
total += segments[i].value;


var percents = segments.map(function(s) { return Math.max(Math.round(100 * s.value / total), 1) });


var percentTotal = 0;
for (var i = 0; i < percents.length; ++i)
percentTotal += percents[i];



while (percentTotal > 100) {
for (var i = 0; i < percents.length && percentTotal > 100; ++i) {
if (percents[i] > 1) {
--percents[i];
--percentTotal;
}
}
}



while (percentTotal < 100) {
for (var i = 0; i < percents.length && percentTotal < 100; ++i) {
++percents[i];
++percentTotal;
}
}

var ctx = this.graphElement.getContext("2d");

var x = 0;
var y = 0;
var w = 450;
var h = 19;
var r = (h / 2);

function drawPillShadow()
{





ctx.beginPath();
ctx.moveTo(x + 4, y + h - 3 - 0.5);
ctx.lineTo(x + w - 4, y + h - 3 - 0.5);
ctx.closePath();

ctx.save();

ctx.shadowBlur = 2;
ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
ctx.shadowOffsetX = 3;
ctx.shadowOffsetY = 5;

ctx.strokeStyle = "white";
ctx.lineWidth = 1;

ctx.stroke();

ctx.shadowOffsetX = -3;

ctx.stroke();

ctx.restore();

ctx.save();

ctx.globalCompositeOperation = "destination-out";
ctx.strokeStyle = "rgba(0, 0, 0, 1)";
ctx.lineWidth = 1;

ctx.stroke();

ctx.restore();
}

function drawPill()
{

ctx.beginPath();
ctx.moveTo(x, y + r);
ctx.lineTo(x, y + h - r);
ctx.arc(x + r, y + h - r, r, Math.PI, Math.PI / 2, true);
ctx.lineTo(x + w - r, y + h);
ctx.arc(x + w - r, y + h - r, r, Math.PI / 2, 0, true);
ctx.lineTo(x + w, y + r);
ctx.arc(x + w - r, y + r, r, 0, 3 * Math.PI / 2, true);
ctx.lineTo(x + r, y);
ctx.arc(x + r, y + r, r, Math.PI / 2, Math.PI, true);
ctx.closePath();


ctx.save();
ctx.clip();


var previousSegmentsWidth = 0;
for (var i = 0; i < segments.length; ++i) {
var segmentWidth = Math.round(w * percents[i] / 100);
ctx.fillStyle = segments[i].color;
ctx.fillRect(x + previousSegmentsWidth, y, segmentWidth, h);
previousSegmentsWidth += segmentWidth;
}


ctx.lineWidth = 1;
for (var i = 1; i < 20; ++i) {
ctx.beginPath();
ctx.moveTo(x + (i * Math.round(w / 20)) + 0.5, y);
ctx.lineTo(x + (i * Math.round(w / 20)) + 0.5, y + h);
ctx.closePath();

ctx.strokeStyle = "rgba(0, 0, 0, 0.2)";
ctx.stroke();

ctx.beginPath();
ctx.moveTo(x + (i * Math.round(w / 20)) + 1.5, y);
ctx.lineTo(x + (i * Math.round(w / 20)) + 1.5, y + h);
ctx.closePath();

ctx.strokeStyle = "rgba(255, 255, 255, 0.2)";
ctx.stroke();
}


var lightGradient = ctx.createLinearGradient(x, y, x, y + (h / 1.5));
lightGradient.addColorStop(0.0, "rgba(220, 220, 220, 0.6)");
lightGradient.addColorStop(0.4, "rgba(220, 220, 220, 0.2)");
lightGradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");

var darkGradient = ctx.createLinearGradient(x, y + (h / 3), x, y + h);
darkGradient.addColorStop(0.0, "rgba(0, 0, 0, 0.0)");
darkGradient.addColorStop(0.8, "rgba(0, 0, 0, 0.2)");
darkGradient.addColorStop(1.0, "rgba(0, 0, 0, 0.5)");

ctx.fillStyle = darkGradient;
ctx.fillRect(x, y, w, h);

ctx.fillStyle = lightGradient;
ctx.fillRect(x, y, w, h);

ctx.restore();
}

ctx.clearRect(x, y, w, (h * 2));

drawPillShadow();
drawPill();

ctx.save();

ctx.translate(0, (h * 2) + 1);
ctx.scale(1, -1);

drawPill();

ctx.restore();

this._fadeOutRect(ctx, x, y + h + 1, w, h, 0.5, 0.0);
},

_fadeOutRect: function(ctx, x, y, w, h, a1, a2)
{
ctx.save();

var gradient = ctx.createLinearGradient(x, y, x, y + h);
gradient.addColorStop(0.0, "rgba(0, 0, 0, " + (1.0 - a1) + ")");
gradient.addColorStop(0.8, "rgba(0, 0, 0, " + (1.0 - a2) + ")");
gradient.addColorStop(1.0, "rgba(0, 0, 0, 1.0)");

ctx.globalCompositeOperation = "destination-out";

ctx.fillStyle = gradient;
ctx.fillRect(x, y, w, h);

ctx.restore();
},

_makeLegendElement: function(label, value, color)
{
var legendElement = document.createElement("label");
legendElement.className = "summary-graph-legend-item";

if (color) {
var swatch = document.createElement("canvas");
swatch.className = "summary-graph-legend-swatch";
swatch.setAttribute("width", "13");
swatch.setAttribute("height", "24");

legendElement.appendChild(swatch);

this._drawSwatch(swatch, color);
}

var labelElement = document.createElement("div");
labelElement.className = "summary-graph-legend-label";
legendElement.appendChild(labelElement);

var headerElement = document.createElement("div");
headerElement.className = "summary-graph-legend-header";
headerElement.textContent = label;
labelElement.appendChild(headerElement);

var valueElement = document.createElement("div");
valueElement.className = "summary-graph-legend-value";
valueElement.textContent = value;
labelElement.appendChild(valueElement);

return legendElement;
}
}

WebInspector.SummaryBar.prototype.__proto__ = WebInspector.Object.prototype;





WebInspector.ElementsPanel = function()
{
WebInspector.Panel.call(this, "elements");

this.contentElement = document.createElement("div");
this.contentElement.id = "elements-content";
this.contentElement.className = "outline-disclosure source-code";

this.treeOutline = new WebInspector.ElementsTreeOutline();
this.treeOutline.panel = this;
this.treeOutline.includeRootDOMNode = false;
this.treeOutline.selectEnabled = true;

this.treeOutline.focusedNodeChanged = function(forceUpdate)
{
if (this.panel.visible && WebInspector.currentFocusElement !== document.getElementById("search"))
WebInspector.currentFocusElement = this.element;

this.panel.updateBreadcrumb(forceUpdate);

for (var pane in this.panel.sidebarPanes)
this.panel.sidebarPanes[pane].needsUpdate = true;

this.panel.updateStyles(true);
this.panel.updateMetrics();
this.panel.updateProperties();
this.panel.updateEventListeners();

if (this._focusedDOMNode) {
InspectorBackend.addInspectedNode(this._focusedDOMNode.id);
WebInspector.extensionServer.notifyObjectSelected(this.panel.name);
}
};

this.contentElement.appendChild(this.treeOutline.element);

this.crumbsElement = document.createElement("div");
this.crumbsElement.className = "crumbs";
this.crumbsElement.addEventListener("mousemove", this._mouseMovedInCrumbs.bind(this), false);
this.crumbsElement.addEventListener("mouseout", this._mouseMovedOutOfCrumbs.bind(this), false);

this.sidebarPanes = {};
this.sidebarPanes.computedStyle = new WebInspector.ComputedStyleSidebarPane();
this.sidebarPanes.styles = new WebInspector.StylesSidebarPane(this.sidebarPanes.computedStyle);
this.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane();
this.sidebarPanes.properties = new WebInspector.PropertiesSidebarPane();
if (Preferences.nativeInstrumentationEnabled)
this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
this.sidebarPanes.eventListeners = new WebInspector.EventListenersSidebarPane();

this.sidebarPanes.styles.onexpand = this.updateStyles.bind(this);
this.sidebarPanes.metrics.onexpand = this.updateMetrics.bind(this);
this.sidebarPanes.properties.onexpand = this.updateProperties.bind(this);
this.sidebarPanes.eventListeners.onexpand = this.updateEventListeners.bind(this);

this.sidebarPanes.styles.expanded = true;

this.sidebarPanes.styles.addEventListener("style edited", this._stylesPaneEdited, this);
this.sidebarPanes.styles.addEventListener("style property toggled", this._stylesPaneEdited, this);
this.sidebarPanes.metrics.addEventListener("metrics edited", this._metricsPaneEdited, this);

this.sidebarElement = document.createElement("div");
this.sidebarElement.id = "elements-sidebar";

for (var pane in this.sidebarPanes)
this.sidebarElement.appendChild(this.sidebarPanes[pane].element);

this.sidebarResizeElement = document.createElement("div");
this.sidebarResizeElement.className = "sidebar-resizer-vertical";
this.sidebarResizeElement.addEventListener("mousedown", this.rightSidebarResizerDragStart.bind(this), false);

this._nodeSearchButton = new WebInspector.StatusBarButton(WebInspector.UIString("Select an element in the page to inspect it."), "node-search-status-bar-item");
this._nodeSearchButton.addEventListener("click", this.toggleSearchingForNode.bind(this), false);

this.element.appendChild(this.contentElement);
this.element.appendChild(this.sidebarElement);
this.element.appendChild(this.sidebarResizeElement);

this._registerShortcuts();

this.reset();
}

WebInspector.ElementsPanel.prototype = {
get toolbarItemLabel()
{
return WebInspector.UIString("Elements");
},

get statusBarItems()
{
return [this._nodeSearchButton.element, this.crumbsElement];
},

get defaultFocusedElement()
{
return this.treeOutline.element;
},

updateStatusBarItems: function()
{
this.updateBreadcrumbSizes();
},

show: function()
{
WebInspector.Panel.prototype.show.call(this);
this.sidebarResizeElement.style.right = (this.sidebarElement.offsetWidth - 3) + "px";
this.updateBreadcrumb();
this.treeOutline.updateSelection();
if (this.recentlyModifiedNodes.length)
this.updateModifiedNodes();
},

hide: function()
{
WebInspector.Panel.prototype.hide.call(this);

WebInspector.highlightDOMNode(0);
this.setSearchingForNode(false);
},

resize: function()
{
this.treeOutline.updateSelection();
this.updateBreadcrumbSizes();
},

reset: function()
{
if (this.focusedDOMNode)
this._selectedPathOnReset = this.focusedDOMNode.path();

this.rootDOMNode = null;
this.focusedDOMNode = null;

WebInspector.highlightDOMNode(0);

this.recentlyModifiedNodes = [];

delete this.currentQuery;

if (Preferences.nativeInstrumentationEnabled)
this.sidebarPanes.domBreakpoints.reset();
},

setDocument: function(inspectedRootDocument)
{
this.reset();
this.searchCanceled();

if (!inspectedRootDocument)
return;

inspectedRootDocument.addEventListener("DOMNodeInserted", this._nodeInserted.bind(this));
inspectedRootDocument.addEventListener("DOMNodeRemoved", this._nodeRemoved.bind(this));
inspectedRootDocument.addEventListener("DOMAttrModified", this._attributesUpdated.bind(this));
inspectedRootDocument.addEventListener("DOMCharacterDataModified", this._characterDataModified.bind(this));

this.rootDOMNode = inspectedRootDocument;

function selectNode(candidateFocusNode)
{
if (!candidateFocusNode)
candidateFocusNode = inspectedRootDocument.body || inspectedRootDocument.documentElement;

if (!candidateFocusNode)
return;

this.focusedDOMNode = candidateFocusNode;
if (this.treeOutline.selectedTreeElement)
this.treeOutline.selectedTreeElement.expand();
}

function selectLastSelectedNode(nodeId)
{
if (this.focusedDOMNode) {

return;
}
var node = nodeId ? WebInspector.domAgent.nodeForId(nodeId) : 0;
selectNode.call(this, node);
}

if (this._selectedPathOnReset)
InspectorBackend.pushNodeByPathToFrontend(this._selectedPathOnReset, selectLastSelectedNode.bind(this));
else
selectNode.call(this);
delete this._selectedPathOnReset;
},

searchCanceled: function()
{
delete this._searchQuery;
this._hideSearchHighlights();

WebInspector.updateSearchMatchesCount(0, this);

this._currentSearchResultIndex = 0;
this._searchResults = [];
InspectorBackend.searchCanceled();
},

performSearch: function(query)
{

this.searchCanceled();

const whitespaceTrimmedQuery = query.trim();
if (!whitespaceTrimmedQuery.length)
return;

this._updatedMatchCountOnce = false;
this._matchesCountUpdateTimeout = null;
this._searchQuery = query;

InspectorBackend.performSearch(whitespaceTrimmedQuery, false);
},

populateHrefContextMenu: function(contextMenu, event, anchorElement)
{
if (!anchorElement.href)
return false;

var resourceURL = WebInspector.resourceURLForRelatedNode(this.focusedDOMNode, anchorElement.href);
if (!resourceURL)
return false;



contextMenu.appendItem(WebInspector.UIString("Open Link in New Window"), WebInspector.openResource.bind(null, resourceURL, false));
if (WebInspector.resourceForURL(resourceURL))
contextMenu.appendItem(WebInspector.UIString("Open Link in Resources Panel"), WebInspector.openResource.bind(null, resourceURL, true));
return true;
},

_updateMatchesCount: function()
{
WebInspector.updateSearchMatchesCount(this._searchResults.length, this);
this._matchesCountUpdateTimeout = null;
this._updatedMatchCountOnce = true;
},

_updateMatchesCountSoon: function()
{
if (!this._updatedMatchCountOnce)
return this._updateMatchesCount();
if (this._matchesCountUpdateTimeout)
return;

this._matchesCountUpdateTimeout = setTimeout(this._updateMatchesCount.bind(this), 500);
},

addNodesToSearchResult: function(nodeIds)
{
if (!nodeIds.length)
return;

for (var i = 0; i < nodeIds.length; ++i) {
var nodeId = nodeIds[i];
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
continue;

this._currentSearchResultIndex = 0;
this._searchResults.push(node);
}
this._highlightCurrentSearchResult();
this._updateMatchesCountSoon();
},

jumpToNextSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;

if (++this._currentSearchResultIndex >= this._searchResults.length)
this._currentSearchResultIndex = 0;
this._highlightCurrentSearchResult();
},

jumpToPreviousSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;

if (--this._currentSearchResultIndex < 0)
this._currentSearchResultIndex = (this._searchResults.length - 1);
this._highlightCurrentSearchResult();
},

_highlightCurrentSearchResult: function()
{
this._hideSearchHighlights();
var node = this._searchResults[this._currentSearchResultIndex];
var treeElement = this.treeOutline.findTreeElement(node);
if (treeElement) {
treeElement.highlightSearchResults(this._searchQuery);
treeElement.reveal();
}
},

_hideSearchHighlights: function(node)
{
for (var i = 0; this._searchResults && i < this._searchResults.length; ++i) {
var node = this._searchResults[i];
var treeElement = this.treeOutline.findTreeElement(node);
if (treeElement)
treeElement.highlightSearchResults(null);
}
},

renameSelector: function(oldIdentifier, newIdentifier, oldSelector, newSelector)
{

},

get rootDOMNode()
{
return this.treeOutline.rootDOMNode;
},

set rootDOMNode(x)
{
this.treeOutline.rootDOMNode = x;
},

get focusedDOMNode()
{
return this.treeOutline.focusedDOMNode;
},

set focusedDOMNode(x)
{
this.treeOutline.focusedDOMNode = x;
},

_attributesUpdated: function(event)
{
this.recentlyModifiedNodes.push({node: event.target, updated: true});
if (this.visible)
this._updateModifiedNodesSoon();
},

_characterDataModified: function(event)
{
this.recentlyModifiedNodes.push({node: event.target, updated: true});
if (this.visible)
this._updateModifiedNodesSoon();
},

_nodeInserted: function(event)
{
this.recentlyModifiedNodes.push({node: event.target, parent: event.relatedNode, inserted: true});
if (this.visible)
this._updateModifiedNodesSoon();
},

_nodeRemoved: function(event)
{
this.recentlyModifiedNodes.push({node: event.target, parent: event.relatedNode, removed: true});
if (this.visible)
this._updateModifiedNodesSoon();
},

_updateModifiedNodesSoon: function()
{
if ("_updateModifiedNodesTimeout" in this)
return;
this._updateModifiedNodesTimeout = setTimeout(this.updateModifiedNodes.bind(this), 0);
},

updateModifiedNodes: function()
{
if ("_updateModifiedNodesTimeout" in this) {
clearTimeout(this._updateModifiedNodesTimeout);
delete this._updateModifiedNodesTimeout;
}

var updatedParentTreeElements = [];
var updateBreadcrumbs = false;

for (var i = 0; i < this.recentlyModifiedNodes.length; ++i) {
var replaced = this.recentlyModifiedNodes[i].replaced;
var parent = this.recentlyModifiedNodes[i].parent;
var node = this.recentlyModifiedNodes[i].node;

if (this.recentlyModifiedNodes[i].updated) {
var nodeItem = this.treeOutline.findTreeElement(node);
if (nodeItem)
nodeItem.updateTitle();
continue;
}

if (!parent)
continue;

var parentNodeItem = this.treeOutline.findTreeElement(parent);
if (parentNodeItem && !parentNodeItem.alreadyUpdatedChildren) {
parentNodeItem.updateChildren(replaced);
parentNodeItem.alreadyUpdatedChildren = true;
updatedParentTreeElements.push(parentNodeItem);
}

if (!updateBreadcrumbs && (this.focusedDOMNode === parent || isAncestorNode(this.focusedDOMNode, parent)))
updateBreadcrumbs = true;
}

for (var i = 0; i < updatedParentTreeElements.length; ++i)
delete updatedParentTreeElements[i].alreadyUpdatedChildren;

this.recentlyModifiedNodes = [];

if (updateBreadcrumbs)
this.updateBreadcrumb(true);
},

_stylesPaneEdited: function()
{
this.sidebarPanes.metrics.needsUpdate = true;
this.updateMetrics();
},

_metricsPaneEdited: function()
{
this.sidebarPanes.styles.needsUpdate = true;
this.updateStyles(true);
},

_mouseMovedInCrumbs: function(event)
{
var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
var crumbElement = nodeUnderMouse.enclosingNodeOrSelfWithClass("crumb");

WebInspector.highlightDOMNode(crumbElement ? crumbElement.representedObject.id : 0);

if ("_mouseOutOfCrumbsTimeout" in this) {
clearTimeout(this._mouseOutOfCrumbsTimeout);
delete this._mouseOutOfCrumbsTimeout;
}
},

_mouseMovedOutOfCrumbs: function(event)
{
var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
if (nodeUnderMouse && nodeUnderMouse.isDescendant(this.crumbsElement))
return;

WebInspector.highlightDOMNode(0);

this._mouseOutOfCrumbsTimeout = setTimeout(this.updateBreadcrumbSizes.bind(this), 1000);
},

updateBreadcrumb: function(forceUpdate)
{
if (!this.visible)
return;

var crumbs = this.crumbsElement;

var handled = false;
var foundRoot = false;
var crumb = crumbs.firstChild;
while (crumb) {
if (crumb.representedObject === this.rootDOMNode)
foundRoot = true;

if (foundRoot)
crumb.addStyleClass("dimmed");
else
crumb.removeStyleClass("dimmed");

if (crumb.representedObject === this.focusedDOMNode) {
crumb.addStyleClass("selected");
handled = true;
} else {
crumb.removeStyleClass("selected");
}

crumb = crumb.nextSibling;
}

if (handled && !forceUpdate) {


this.updateBreadcrumbSizes();
return;
}

crumbs.removeChildren();

var panel = this;

function selectCrumbFunction(event)
{
var crumb = event.currentTarget;
if (crumb.hasStyleClass("collapsed")) {

if (crumb === panel.crumbsElement.firstChild) {


var currentCrumb = crumb;
while (currentCrumb) {
var hidden = currentCrumb.hasStyleClass("hidden");
var collapsed = currentCrumb.hasStyleClass("collapsed");
if (!hidden && !collapsed)
break;
crumb = currentCrumb;
currentCrumb = currentCrumb.nextSibling;
}
}

panel.updateBreadcrumbSizes(crumb);
} else {


if (event.detail >= 2 || crumb.hasStyleClass("dimmed"))
panel.rootDOMNode = crumb.representedObject.parentNode;
panel.focusedDOMNode = crumb.representedObject;
}

event.preventDefault();
}

foundRoot = false;
for (var current = this.focusedDOMNode; current; current = current.parentNode) {
if (current.nodeType === Node.DOCUMENT_NODE)
continue;

if (current === this.rootDOMNode)
foundRoot = true;

var crumb = document.createElement("span");
crumb.className = "crumb";
crumb.representedObject = current;
crumb.addEventListener("mousedown", selectCrumbFunction, false);

var crumbTitle;
switch (current.nodeType) {
case Node.ELEMENT_NODE:
this.decorateNodeLabel(current, crumb);
break;

case Node.TEXT_NODE:
if (isNodeWhitespace.call(current))
crumbTitle = WebInspector.UIString("(whitespace)");
else
crumbTitle = WebInspector.UIString("(text)");
break

case Node.COMMENT_NODE:
crumbTitle = "<!-->";
break;

case Node.DOCUMENT_TYPE_NODE:
crumbTitle = "<!DOCTYPE>";
break;

default:
crumbTitle = this.treeOutline.nodeNameToCorrectCase(current.nodeName);
}

if (!crumb.childNodes.length) {
var nameElement = document.createElement("span");
nameElement.textContent = crumbTitle;
crumb.appendChild(nameElement);
crumb.title = crumbTitle;
}

if (foundRoot)
crumb.addStyleClass("dimmed");
if (current === this.focusedDOMNode)
crumb.addStyleClass("selected");
if (!crumbs.childNodes.length)
crumb.addStyleClass("end");

crumbs.appendChild(crumb);
}

if (crumbs.hasChildNodes())
crumbs.lastChild.addStyleClass("start");

this.updateBreadcrumbSizes();
},

decorateNodeLabel: function(node, parentElement)
{
var title = this.treeOutline.nodeNameToCorrectCase(node.nodeName);

var nameElement = document.createElement("span");
nameElement.textContent = title;
parentElement.appendChild(nameElement);

var idAttribute = node.getAttribute("id");
if (idAttribute) {
var idElement = document.createElement("span");
parentElement.appendChild(idElement);

var part = "#" + idAttribute;
title += part;
idElement.appendChild(document.createTextNode(part));


nameElement.className = "extra";
}

var classAttribute = node.getAttribute("class");
if (classAttribute) {
var classes = classAttribute.split(/\s+/);
var foundClasses = {};

if (classes.length) {
var classesElement = document.createElement("span");
classesElement.className = "extra";
parentElement.appendChild(classesElement);

for (var i = 0; i < classes.length; ++i) {
var className = classes[i];
if (className && !(className in foundClasses)) {
var part = "." + className;
title += part;
classesElement.appendChild(document.createTextNode(part));
foundClasses[className] = true;
}
}
}
}
parentElement.title = title;
},

linkifyNodeReference: function(node)
{
var link = document.createElement("span");
link.className = "node-link";
this.decorateNodeLabel(node, link);
WebInspector.wireElementWithDOMNode(link, node.id);
return link;
},

linkifyNodeById: function(nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return document.createTextNode(WebInspector.UIString("<node>"));
return this.linkifyNodeReference(node);
},

updateBreadcrumbSizes: function(focusedCrumb)
{
if (!this.visible)
return;

if (document.body.offsetWidth <= 0) {


return;
}

var crumbs = this.crumbsElement;
if (!crumbs.childNodes.length || crumbs.offsetWidth <= 0)
return; 


var selectedIndex = 0;
var focusedIndex = 0;
var selectedCrumb;

var i = 0;
var crumb = crumbs.firstChild;
while (crumb) {

if (!selectedCrumb && crumb.hasStyleClass("selected")) {
selectedCrumb = crumb;
selectedIndex = i;
}


if (crumb === focusedCrumb)
focusedIndex = i;



if (crumb !== crumbs.lastChild)
crumb.removeStyleClass("start");
if (crumb !== crumbs.firstChild)
crumb.removeStyleClass("end");

crumb.removeStyleClass("compact");
crumb.removeStyleClass("collapsed");
crumb.removeStyleClass("hidden");

crumb = crumb.nextSibling;
++i;
}



crumbs.firstChild.addStyleClass("end");
crumbs.lastChild.addStyleClass("start");

function crumbsAreSmallerThanContainer()
{
var rightPadding = 20;
var errorWarningElement = document.getElementById("error-warning-count");
if (!WebInspector.drawer.visible && errorWarningElement)
rightPadding += errorWarningElement.offsetWidth;
return ((crumbs.totalOffsetLeft + crumbs.offsetWidth + rightPadding) < window.innerWidth);
}

if (crumbsAreSmallerThanContainer())
return; 

var BothSides = 0;
var AncestorSide = -1;
var ChildSide = 1;

function makeCrumbsSmaller(shrinkingFunction, direction, significantCrumb)
{
if (!significantCrumb)
significantCrumb = (focusedCrumb || selectedCrumb);

if (significantCrumb === selectedCrumb)
var significantIndex = selectedIndex;
else if (significantCrumb === focusedCrumb)
var significantIndex = focusedIndex;
else {
var significantIndex = 0;
for (var i = 0; i < crumbs.childNodes.length; ++i) {
if (crumbs.childNodes[i] === significantCrumb) {
significantIndex = i;
break;
}
}
}

function shrinkCrumbAtIndex(index)
{
var shrinkCrumb = crumbs.childNodes[index];
if (shrinkCrumb && shrinkCrumb !== significantCrumb)
shrinkingFunction(shrinkCrumb);
if (crumbsAreSmallerThanContainer())
return true; 
return false;
}



if (direction) {

var index = (direction > 0 ? 0 : crumbs.childNodes.length - 1);
while (index !== significantIndex) {
if (shrinkCrumbAtIndex(index))
return true;
index += (direction > 0 ? 1 : -1);
}
} else {


var startIndex = 0;
var endIndex = crumbs.childNodes.length - 1;
while (startIndex != significantIndex || endIndex != significantIndex) {
var startDistance = significantIndex - startIndex;
var endDistance = endIndex - significantIndex;
if (startDistance >= endDistance)
var index = startIndex++;
else
var index = endIndex--;
if (shrinkCrumbAtIndex(index))
return true;
}
}


return false;
}

function coalesceCollapsedCrumbs()
{
var crumb = crumbs.firstChild;
var collapsedRun = false;
var newStartNeeded = false;
var newEndNeeded = false;
while (crumb) {
var hidden = crumb.hasStyleClass("hidden");
if (!hidden) {
var collapsed = crumb.hasStyleClass("collapsed"); 
if (collapsedRun && collapsed) {
crumb.addStyleClass("hidden");
crumb.removeStyleClass("compact");
crumb.removeStyleClass("collapsed");

if (crumb.hasStyleClass("start")) {
crumb.removeStyleClass("start");
newStartNeeded = true;
}

if (crumb.hasStyleClass("end")) {
crumb.removeStyleClass("end");
newEndNeeded = true;
}

continue;
}

collapsedRun = collapsed;

if (newEndNeeded) {
newEndNeeded = false;
crumb.addStyleClass("end");
}
} else
collapsedRun = true;
crumb = crumb.nextSibling;
}

if (newStartNeeded) {
crumb = crumbs.lastChild;
while (crumb) {
if (!crumb.hasStyleClass("hidden")) {
crumb.addStyleClass("start");
break;
}
crumb = crumb.previousSibling;
}
}
}

function compact(crumb)
{
if (crumb.hasStyleClass("hidden"))
return;
crumb.addStyleClass("compact");
}

function collapse(crumb, dontCoalesce)
{
if (crumb.hasStyleClass("hidden"))
return;
crumb.addStyleClass("collapsed");
crumb.removeStyleClass("compact");
if (!dontCoalesce)
coalesceCollapsedCrumbs();
}

function compactDimmed(crumb)
{
if (crumb.hasStyleClass("dimmed"))
compact(crumb);
}

function collapseDimmed(crumb)
{
if (crumb.hasStyleClass("dimmed"))
collapse(crumb);
}

if (!focusedCrumb) {




if (makeCrumbsSmaller(compact, ChildSide))
return;


if (makeCrumbsSmaller(collapse, ChildSide))
return;


if (makeCrumbsSmaller(compactDimmed, AncestorSide))
return;


if (makeCrumbsSmaller(collapseDimmed, AncestorSide))
return;
}


if (makeCrumbsSmaller(compact, (focusedCrumb ? BothSides : AncestorSide)))
return;


if (makeCrumbsSmaller(collapse, (focusedCrumb ? BothSides : AncestorSide)))
return;

if (!selectedCrumb)
return;


compact(selectedCrumb);
if (crumbsAreSmallerThanContainer())
return;


collapse(selectedCrumb, true);
},

updateStyles: function(forceUpdate)
{
var stylesSidebarPane = this.sidebarPanes.styles;
var computedStylePane = this.sidebarPanes.computedStyle;
if ((!stylesSidebarPane.expanded && !computedStylePane.expanded) || !stylesSidebarPane.needsUpdate)
return;

stylesSidebarPane.update(this.focusedDOMNode, null, forceUpdate);
stylesSidebarPane.needsUpdate = false;
},

updateMetrics: function()
{
var metricsSidebarPane = this.sidebarPanes.metrics;
if (!metricsSidebarPane.expanded || !metricsSidebarPane.needsUpdate)
return;

metricsSidebarPane.update(this.focusedDOMNode);
metricsSidebarPane.needsUpdate = false;
},

updateProperties: function()
{
var propertiesSidebarPane = this.sidebarPanes.properties;
if (!propertiesSidebarPane.expanded || !propertiesSidebarPane.needsUpdate)
return;

propertiesSidebarPane.update(this.focusedDOMNode);
propertiesSidebarPane.needsUpdate = false;
},

updateEventListeners: function()
{
var eventListenersSidebarPane = this.sidebarPanes.eventListeners;
if (!eventListenersSidebarPane.expanded || !eventListenersSidebarPane.needsUpdate)
return;

eventListenersSidebarPane.update(this.focusedDOMNode);
eventListenersSidebarPane.needsUpdate = false;
},

_registerShortcuts: function()
{
var shortcut = WebInspector.KeyboardShortcut;
var section = WebInspector.shortcutsHelp.section(WebInspector.UIString("Elements Panel"));
var keys = [
shortcut.shortcutToString(shortcut.Keys.Up),
shortcut.shortcutToString(shortcut.Keys.Down)
];
section.addRelatedKeys(keys, WebInspector.UIString("Navigate elements"));
var keys = [
shortcut.shortcutToString(shortcut.Keys.Right),
shortcut.shortcutToString(shortcut.Keys.Left)
];
section.addRelatedKeys(keys, WebInspector.UIString("Expand/collapse"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Enter), WebInspector.UIString("Edit attribute"));

this.sidebarPanes.styles.registerShortcuts();
},

handleShortcut: function(event)
{


if (event.keyIdentifier === "U+0043") {     
if (WebInspector.isMac())
var isNodeSearchKey = event.metaKey && !event.ctrlKey && !event.altKey && event.shiftKey;
else
var isNodeSearchKey = event.ctrlKey && !event.metaKey && !event.altKey && event.shiftKey;

if (isNodeSearchKey) {
this.toggleSearchingForNode();
event.handled = true;
return;
}
}
},

handleCopyEvent: function(event)
{

if (!window.getSelection().isCollapsed)
return;
event.clipboardData.clearData();
event.preventDefault();
InspectorBackend.copyNode(this.focusedDOMNode.id);
},

rightSidebarResizerDragStart: function(event)
{
WebInspector.elementDragStart(this.sidebarElement, this.rightSidebarResizerDrag.bind(this), this.rightSidebarResizerDragEnd.bind(this), event, "col-resize");
},

rightSidebarResizerDragEnd: function(event)
{
WebInspector.elementDragEnd(event);
this.saveSidebarWidth();
},

rightSidebarResizerDrag: function(event)
{
var x = event.pageX;
var newWidth = Number.constrain(window.innerWidth - x, Preferences.minElementsSidebarWidth, window.innerWidth * 0.66);
this.setSidebarWidth(newWidth);
event.preventDefault();
},

setSidebarWidth: function(newWidth)
{
this.sidebarElement.style.width = newWidth + "px";
this.contentElement.style.right = newWidth + "px";
this.sidebarResizeElement.style.right = (newWidth - 3) + "px";
this.treeOutline.updateSelection();
},

updateFocusedNode: function(nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return;

this.focusedDOMNode = node;
this._nodeSearchButton.toggled = false;
},

_setSearchingForNode: function(enabled)
{
this._nodeSearchButton.toggled = enabled;
},

setSearchingForNode: function(enabled)
{
InspectorBackend.setSearchingForNode(enabled, this._setSearchingForNode.bind(this));
},

toggleSearchingForNode: function()
{
this.setSearchingForNode(!this._nodeSearchButton.toggled);
},

elementsToRestoreScrollPositionsFor: function()
{
return [ this.contentElement, this.sidebarElement ];
}
}

WebInspector.ElementsPanel.prototype.__proto__ = WebInspector.Panel.prototype;





WebInspector.NetworkPanel = function()
{
WebInspector.Panel.call(this, "network");

this.createSidebar();
this.sidebarElement.className = "network-sidebar";

this._resources = [];
this._resourcesById = {};
this._resourcesByURL = {};
this._lastIdentifier = 0;
this._staleResources = [];
this._resourceGridNodes = {};
this._mainResourceLoadTime = -1;
this._mainResourceDOMContentTime = -1;
this._hiddenCategories = {};

this._categories = WebInspector.resourceCategories;

this.containerElement = document.createElement("div");
this.containerElement.id = "network-container";
this.sidebarElement.appendChild(this.containerElement);

this._viewsContainerElement = document.createElement("div");
this._viewsContainerElement.id = "network-views";
this._viewsContainerElement.className = "hidden";
this.element.appendChild(this._viewsContainerElement);

this._closeButtonElement = document.createElement("button");
this._closeButtonElement.id = "network-close-button";
this._closeButtonElement.addEventListener("click", this._toggleGridMode.bind(this), false);
this._viewsContainerElement.appendChild(this._closeButtonElement);

this._createSortingFunctions();
this._createTable();
this._createTimelineGrid();
this._createStatusbarButtons();
this._createFilterStatusBarItems();
this._createSummaryBar();

if (!WebInspector.settings.resourcesLargeRows)
this._setLargerResources(WebInspector.settings.resourcesLargeRows);

this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this), true);

this._popoverHelper.setTimeout(100);

this.calculator = new WebInspector.NetworkTransferTimeCalculator();
this._filter(this._filterAllElement, false);

this._toggleGridMode();
}

WebInspector.NetworkPanel.prototype = {
get toolbarItemLabel()
{
return WebInspector.UIString("Network");
},

get statusBarItems()
{
return [this._largerResourcesButton.element, this._preserveLogToggle.element, this._clearButton.element, this._filterBarElement];
},

isCategoryVisible: function(categoryName)
{
return true;
},

elementsToRestoreScrollPositionsFor: function()
{
return [this.containerElement];
},

resize: function()
{
WebInspector.Panel.prototype.resize.call(this);
this._dataGrid.updateWidths();
this._positionSummaryBar();
},

updateSidebarWidth: function(width)
{
if (!this._viewingResourceMode)
return;
WebInspector.Panel.prototype.updateSidebarWidth.call(this, width);
if (this._summaryBarElement.parentElement === this.element)
this._summaryBarElement.style.width = width + "px";
},

updateMainViewWidth: function(width)
{
this._viewsContainerElement.style.left = width + "px";
},

handleShortcut: function(event)
{
if (this._viewingResourceMode && event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
this._toggleGridMode();
event.handled = true;
}
},

_positionSummaryBar: function()
{


var fillerRow = this._dataGrid.dataTableBody.lastChild;
if (this._summaryBarElement.parentElement !== this.element && fillerRow.offsetHeight > 0) {

if (this._summaryBarRowNode) {
this._dataGrid.removeChild(this._summaryBarRowNode);
delete this._summaryBarRowNode;
}
this._summaryBarElement.addStyleClass("network-summary-bar-bottom");
this._summaryBarElement.style.setProperty("width", this.sidebarElement.offsetWidth + "px");
this.element.appendChild(this._summaryBarElement);
this._dataGrid.element.style.bottom = "20px";
return;
}

if (!this._summaryBarRowNode && !fillerRow.offsetHeight) {

this._summaryBarRowNode = new WebInspector.NetworkTotalGridNode(this._summaryBarElement);
this._summaryBarElement.removeStyleClass("network-summary-bar-bottom");
this._summaryBarElement.style.removeProperty("width");
this._dataGrid.appendChild(this._summaryBarRowNode);
this._dataGrid.element.style.bottom = 0;
this._sortItems();
}
},

_resetSummaryBar: function()
{
delete this._summaryBarRowNode;
this._summaryBarElement.parentElement.removeChild(this._summaryBarElement);
this._updateSummaryBar();
},

_createTimelineGrid: function()
{
this._timelineGrid = new WebInspector.TimelineGrid();
this._timelineGrid.element.addStyleClass("network-timeline-grid");
this._dataGrid.element.appendChild(this._timelineGrid.element);
},

_createTable: function()
{
var columns = {name: {}, method: {}, status: {}, type: {}, size: {}, time: {}, timeline: {}};
columns.name.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Name"), WebInspector.UIString("Path"));
columns.name.sortable = true;
columns.name.width = "20%";
columns.name.disclosure = true;

columns.method.title = WebInspector.UIString("Method");
columns.method.sortable = true;
columns.method.width = "7%";

columns.status.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Status"), WebInspector.UIString("Text"));
columns.status.sortable = true;
columns.status.width = "8%";

columns.type.title = WebInspector.UIString("Type");
columns.type.sortable = true;
columns.type.width = "10%";

columns.size.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Size"), WebInspector.UIString("Transfer"));
columns.size.sortable = true;
columns.size.width = "10%";
columns.size.aligned = "right";

columns.time.titleDOMFragment = this._makeHeaderFragment(WebInspector.UIString("Time"), WebInspector.UIString("Latency"));
columns.time.sortable = true;
columns.time.width = "10%";
columns.time.aligned = "right";

columns.timeline.title = "";
columns.timeline.sortable = false;
columns.timeline.width = "37%";
columns.timeline.sort = "ascending";

this._dataGrid = new WebInspector.DataGrid(columns);
this.containerElement.appendChild(this._dataGrid.element);
this._dataGrid.addEventListener("sorting changed", this._sortItems, this);
this._dataGrid.addEventListener("width changed", this._updateDividersIfNeeded, this);

this._patchTimelineHeader();
},

_makeHeaderFragment: function(title, subtitle)
{
var fragment = document.createDocumentFragment();
fragment.appendChild(document.createTextNode(title));
var subtitleDiv = document.createElement("div");
subtitleDiv.className = "network-header-subtitle";
subtitleDiv.textContent = subtitle;
fragment.appendChild(subtitleDiv);
return fragment;
},

_patchTimelineHeader: function()
{
var timelineSorting = document.createElement("select");

var option = document.createElement("option");
option.value = "startTime";
option.label = WebInspector.UIString("Timeline");
timelineSorting.appendChild(option);

option = document.createElement("option");
option.value = "startTime";
option.label = WebInspector.UIString("Start Time");
timelineSorting.appendChild(option);

option = document.createElement("option");
option.value = "responseTime";
option.label = WebInspector.UIString("Response Time");
timelineSorting.appendChild(option);

option = document.createElement("option");
option.value = "endTime";
option.label = WebInspector.UIString("End Time");
timelineSorting.appendChild(option);

option = document.createElement("option");
option.value = "duration";
option.label = WebInspector.UIString("Duration");
timelineSorting.appendChild(option);

option = document.createElement("option");
option.value = "latency";
option.label = WebInspector.UIString("Latency");
timelineSorting.appendChild(option);

var header = this._dataGrid.headerTableHeader("timeline");
header.replaceChild(timelineSorting, header.firstChild);

timelineSorting.addEventListener("click", function(event) { event.stopPropagation() }, false);
timelineSorting.addEventListener("change", this._sortByTimeline.bind(this), false);
this._timelineSortSelector = timelineSorting;
},

_createSortingFunctions: function()
{
this._sortingFunctions = {};
this._sortingFunctions.name = WebInspector.NetworkDataGridNode.NameComparator;
this._sortingFunctions.method = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "method", false);
this._sortingFunctions.status = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "statusCode", false);
this._sortingFunctions.type = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "mimeType", false);
this._sortingFunctions.size = WebInspector.NetworkDataGridNode.SizeComparator;
this._sortingFunctions.time = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "duration", false);
this._sortingFunctions.timeline = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "startTime", false);
this._sortingFunctions.startTime = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "startTime", false);
this._sortingFunctions.endTime = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "endTime", false);
this._sortingFunctions.responseTime = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "responseReceivedTime", false);
this._sortingFunctions.duration = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "duration", true);
this._sortingFunctions.latency = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "latency", true);

var timeCalculator = new WebInspector.NetworkTransferTimeCalculator();
var durationCalculator = new WebInspector.NetworkTransferDurationCalculator();

this._calculators = {};
this._calculators.timeline = timeCalculator;
this._calculators.startTime = timeCalculator;
this._calculators.endTime = timeCalculator;
this._calculators.responseTime = timeCalculator;
this._calculators.duration = durationCalculator;
this._calculators.latency = durationCalculator;
},

_sortItems: function()
{
var columnIdentifier = this._dataGrid.sortColumnIdentifier;
if (columnIdentifier === "timeline") {
this._sortByTimeline();
return;
}
var sortingFunction = this._sortingFunctions[columnIdentifier];
if (!sortingFunction)
return;

this._dataGrid.sortNodes(sortingFunction, this._dataGrid.sortOrder === "descending");
this._timelineSortSelector.selectedIndex = 0;
},

_sortByTimeline: function()
{
var selectedIndex = this._timelineSortSelector.selectedIndex;
if (!selectedIndex)
selectedIndex = 1; 
var selectedOption = this._timelineSortSelector[selectedIndex];
var value = selectedOption.value;

var sortingFunction = this._sortingFunctions[value];
this._dataGrid.sortNodes(sortingFunction);
this.calculator = this._calculators[value];
if (this.calculator.startAtZero)
this._timelineGrid.hideEventDividers();
else
this._timelineGrid.showEventDividers();
this._dataGrid.markColumnAsSortedBy("timeline", "ascending");
},

_createFilterStatusBarItems: function()
{
var filterBarElement = document.createElement("div");
filterBarElement.className = "scope-bar status-bar-item";
filterBarElement.id = "network-filter";

function createFilterElement(category, label)
{
var categoryElement = document.createElement("li");
categoryElement.category = category;
categoryElement.className = category;
categoryElement.appendChild(document.createTextNode(label));
categoryElement.addEventListener("click", this._updateFilter.bind(this), false);
filterBarElement.appendChild(categoryElement);

return categoryElement;
}

this._filterAllElement = createFilterElement.call(this, "all", WebInspector.UIString("All"));


var dividerElement = document.createElement("div");
dividerElement.addStyleClass("scope-bar-divider");
filterBarElement.appendChild(dividerElement);

for (var category in this._categories)
createFilterElement.call(this, category, this._categories[category].title);
this._filterBarElement = filterBarElement;
},

_createSummaryBar: function()
{
this._summaryBarElement = document.createElement("div");
this._summaryBarElement.className = "network-summary-bar";
this.containerElement.appendChild(this._summaryBarElement);
},

_updateSummaryBar: function()
{
this._positionSummaryBar(); 
var numRequests = this._resources.length;

if (!numRequests) {
if (this._summaryBarElement._isDisplayingWarning)
return;
this._summaryBarElement._isDisplayingWarning = true;

var img = document.createElement("img");
img.src = "Images/warningIcon.png";
this._summaryBarElement.removeChildren();
this._summaryBarElement.appendChild(img);
this._summaryBarElement.appendChild(document.createTextNode(" "));
this._summaryBarElement.appendChild(document.createTextNode(
WebInspector.UIString("No requests captured. Reload the page to see detailed information on the network activity.")));
return;
}
delete this._summaryBarElement._isDisplayingWarning;

var transferSize = 0;
var baseTime = -1;
var maxTime = -1;
for (var i = 0; i < this._resources.length; ++i) {
var resource = this._resources[i];
transferSize += (resource.cached || !resource.transferSize) ? 0 : resource.transferSize;
if (resource.isMainResource)
baseTime = resource.startTime;
if (resource.endTime > maxTime) 
maxTime = resource.endTime;
}
var text = String.sprintf(WebInspector.UIString("%d requests"), numRequests);
text += "  \u2758  " + String.sprintf(WebInspector.UIString("%s transferred"), Number.bytesToString(transferSize));
if (baseTime !== -1 && this._mainResourceLoadTime !== -1 && this._mainResourceDOMContentTime !== -1 && this._mainResourceDOMContentTime > baseTime) {
text += "  \u2758  " + String.sprintf(WebInspector.UIString("%s (onload: %s, DOMContentLoaded: %s)"),
Number.secondsToString(maxTime - baseTime),
Number.secondsToString(this._mainResourceLoadTime - baseTime),
Number.secondsToString(this._mainResourceDOMContentTime - baseTime));
}
this._summaryBarElement.textContent = text;
},

_showCategory: function(category)
{
this._dataGrid.element.addStyleClass("filter-" + category);
delete this._hiddenCategories[category];
},

_hideCategory: function(category)
{
this._dataGrid.element.removeStyleClass("filter-" + category);
this._hiddenCategories[category] = true;
},

_updateFilter: function(e)
{
var isMac = WebInspector.isMac();
var selectMultiple = false;
if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
selectMultiple = true;
if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
selectMultiple = true;

this._filter(e.target, selectMultiple);
this._positionSummaryBar();
},

_filter: function(target, selectMultiple)
{
function unselectAll()
{
for (var i = 0; i < this._filterBarElement.childNodes.length; ++i) {
var child = this._filterBarElement.childNodes[i];
if (!child.category)
continue;

child.removeStyleClass("selected");
this._hideCategory(child.category);
}
}

if (target.category === this._filterAllElement) {
if (target.hasStyleClass("selected")) {

return;
}


unselectAll.call(this);
} else {

if (this._filterAllElement.hasStyleClass("selected")) {
this._filterAllElement.removeStyleClass("selected");
this._hideCategory("all");
}
}

if (!selectMultiple) {


unselectAll.call(this);

target.addStyleClass("selected");
this._showCategory(target.category);
return;
}

if (target.hasStyleClass("selected")) {


target.removeStyleClass("selected");
this._hideCategory(target.category);
} else {


target.addStyleClass("selected");
this._showCategory(target.category);
}
},

_scheduleRefresh: function()
{
if (this._needsRefresh)
return;

this._needsRefresh = true;

if (this.visible && !("_refreshTimeout" in this))
this._refreshTimeout = setTimeout(this.refresh.bind(this), 500);
},

_updateDividersIfNeeded: function(force)
{
var timelineColumn = this._dataGrid.columns.timeline;
for (var i = 0; i < this._dataGrid.resizers.length; ++i) {
if (timelineColumn.ordinal === this._dataGrid.resizers[i].rightNeighboringColumnID) {

this._timelineGrid.element.style.left = this._dataGrid.resizers[i].style.left;
this._timelineGrid.element.style.right = "18px";
}
}

var proceed = true;
if (!this.visible) {
this._scheduleRefresh();
proceed = false;
} else
proceed = this._timelineGrid.updateDividers(force, this.calculator);

if (!proceed)
return;

if (this.calculator.startAtZero || !this.calculator.computePercentageFromEventTime) {






return;
}

this._timelineGrid.removeEventDividers();
if (this._mainResourceLoadTime !== -1) {
var percent = this.calculator.computePercentageFromEventTime(this._mainResourceLoadTime);

var loadDivider = document.createElement("div");
loadDivider.className = "network-event-divider network-red-divider";

var loadDividerPadding = document.createElement("div");
loadDividerPadding.className = "network-event-divider-padding";
loadDividerPadding.title = WebInspector.UIString("Load event fired");
loadDividerPadding.appendChild(loadDivider);
loadDividerPadding.style.left = percent + "%";
this._timelineGrid.addEventDivider(loadDividerPadding);
}

if (this._mainResourceDOMContentTime !== -1) {
var percent = this.calculator.computePercentageFromEventTime(this._mainResourceDOMContentTime);

var domContentDivider = document.createElement("div");
domContentDivider.className = "network-event-divider network-blue-divider";

var domContentDividerPadding = document.createElement("div");
domContentDividerPadding.className = "network-event-divider-padding";
domContentDividerPadding.title = WebInspector.UIString("DOMContent event fired");
domContentDividerPadding.appendChild(domContentDivider);
domContentDividerPadding.style.left = percent + "%";
this._timelineGrid.addEventDivider(domContentDividerPadding);
}
},

_refreshIfNeeded: function()
{
if (this._needsRefresh)
this.refresh();
},

_invalidateAllItems: function()
{
this._staleResources = this._resources.slice();
},

get calculator()
{
return this._calculator;
},

set calculator(x)
{
if (!x || this._calculator === x)
return;

this._calculator = x;
this._calculator.reset();

this._invalidateAllItems();
this.refresh();
},

_resourceGridNode: function(resource)
{
return this._resourceGridNodes[resource.identifier];
},

revealAndSelectItem: function(resource)
{
var node = this._resourceGridNode(resource);
if (node) {
node.reveal();
node.select(true);
}
},

addEventDivider: function(divider)
{
this._timelineGrid.addEventDivider(divider);
},

_createStatusbarButtons: function()
{
this._preserveLogToggle = new WebInspector.StatusBarButton(WebInspector.UIString("Preserve Log upon Navigation"), "record-profile-status-bar-item");
this._preserveLogToggle.addEventListener("click", this._onPreserveLogClicked.bind(this), false);

this._clearButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear"), "clear-status-bar-item");
this._clearButton.addEventListener("click", this._reset.bind(this), false);

this._largerResourcesButton = new WebInspector.StatusBarButton(WebInspector.UIString("Use small resource rows."), "network-larger-resources-status-bar-item");
this._largerResourcesButton.toggled = WebInspector.settings.resourcesLargeRows;
this._largerResourcesButton.addEventListener("click", this._toggleLargerResources.bind(this), false);
},

set mainResourceLoadTime(x)
{
if (this._mainResourceLoadTime === x)
return;

this._mainResourceLoadTime = x || -1;

this._updateDividersIfNeeded(true);
},

set mainResourceDOMContentTime(x)
{
if (this._mainResourceDOMContentTime === x)
return;

this._mainResourceDOMContentTime = x || -1;
this._updateDividersIfNeeded(true);
},

show: function()
{
WebInspector.Panel.prototype.show.call(this);
this._refreshIfNeeded();

if (this.visibleView)
this.visibleView.show(this._viewsContainerElement);

this._dataGrid.updateWidths();
this._positionSummaryBar();
},

hide: function()
{
WebInspector.Panel.prototype.hide.call(this);
this._popoverHelper.hidePopup();
},

get searchableViews()
{
var views = [];
return views;
},

searchMatchFound: function(view, matches)
{
this._resourceGridNode(view.resource).searchMatches = matches;
},

searchCanceled: function(startingNewSearch)
{
WebInspector.Panel.prototype.searchCanceled.call(this, startingNewSearch);

if (startingNewSearch || !this._resources)
return;
},

performSearch: function(query)
{
WebInspector.Panel.prototype.performSearch.call(this, query);
},

refresh: function()
{
this._needsRefresh = false;
if ("_refreshTimeout" in this) {
clearTimeout(this._refreshTimeout);
delete this._refreshTimeout;
}

var wasScrolledToLastRow = this._dataGrid.isScrolledToLastRow();
var staleItemsLength = this._staleResources.length;
var boundariesChanged = false;

for (var i = 0; i < staleItemsLength; ++i) {
var resource = this._staleResources[i];
var node = this._resourceGridNode(resource);
if (!node) {

node = new WebInspector.NetworkDataGridNode(this, resource);
this._resourceGridNodes[resource.identifier] = node;
this._dataGrid.appendChild(node);
}
node.refreshResource();

if (this.calculator.updateBoundaries(resource))
boundariesChanged = true;
}

if (boundariesChanged) {

this._invalidateAllItems();
staleItemsLength = this._staleResources.length;
}

for (var i = 0; i < staleItemsLength; ++i)
this._resourceGridNode(this._staleResources[i]).refreshGraph(this.calculator);

this._staleResources = [];
this._sortItems();
this._updateSummaryBar();
this._dataGrid.updateWidths();

if (wasScrolledToLastRow)
this._dataGrid.scrollToLastRow();
},

_onPreserveLogClicked: function(e)
{
this._preserveLogToggle.toggled = !this._preserveLogToggle.toggled;
},

reset: function()
{
if (!this._preserveLogToggle.toggled)
this._reset();
},

_reset: function()
{
this._popoverHelper.hidePopup();
this._closeVisibleResource();

this._toggleGridMode();


if (this._calculator)
this._calculator.reset();

this._resources = [];
this._resourcesById = {};
this._resourcesByURL = {};
this._staleResources = [];
this._resourceGridNodes = {};

this._dataGrid.removeChildren();
delete this._summaryBarRowNode;
this._updateDividersIfNeeded(true);


this._mainResourceLoadTime = -1;
this._mainResourceDOMContentTime = -1;

this._viewsContainerElement.removeChildren();
this._viewsContainerElement.appendChild(this._closeButtonElement);
this._resetSummaryBar();
},

get resources()
{
return this._resourcesById;
},

refreshResource: function(resource)
{
if (!resource.identifier)
resource.identifier = "network:" + this._lastIdentifier++;

if (!this._resourcesById[resource.identifier]) {
this._resources.push(resource);
this._resourcesById[resource.identifier] = resource;
this._resourcesByURL[resource.url] = resource;


if (resource.redirects) {
for (var i = 0; i < resource.redirects.length; ++i)
this.refreshResource(resource.redirects[i]);
}
}

this._staleResources.push(resource);
this._scheduleRefresh();

if (!resource)
return;

var oldView = WebInspector.ResourceManager.existingResourceViewForResource(resource);
if (!oldView)
return;

if (WebInspector.ResourceManager.resourceViewTypeMatchesResource(resource))
return;

var newView = WebInspector.ResourceManager.recreateResourceView(resource);
if (this.visibleView === oldView)
this.visibleView = newView;
},

canShowSourceLine: function(url, line)
{
return !!this._resourcesByURL[url];
},

showSourceLine: function(url, line)
{
this._showResource(this._resourcesByURL[url], line);
},

_showResource: function(resource, line)
{
if (!resource)
return;

this._popoverHelper.hidePopup();

this._toggleViewingResourceMode();

if (this.visibleView) {
this.visibleView.detach();
delete this.visibleView;
}

var view = new WebInspector.NetworkItemView(resource);
view.show(this._viewsContainerElement);
this.visibleView = view;

this.updateSidebarWidth();
},

_closeVisibleResource: function()
{
this.element.removeStyleClass("viewing-resource");

if (this.visibleView) {
this.visibleView.detach();
delete this.visibleView;
}

if (this._lastSelectedGraphTreeElement)
this._lastSelectedGraphTreeElement.select(true);

this.updateSidebarWidth();
},

_toggleLargerResources: function()
{
WebInspector.settings.resourcesLargeRows = !WebInspector.settings.resourcesLargeRows;
this._setLargerResources(WebInspector.settings.resourcesLargeRows);
},

_setLargerResources: function(enabled)
{
this._largerResourcesButton.toggled = enabled;
if (!enabled) {
this._largerResourcesButton.title = WebInspector.UIString("Use large resource rows.");
this._dataGrid.element.addStyleClass("small");
this._timelineGrid.element.addStyleClass("small");
this._viewsContainerElement.addStyleClass("small");
} else {
this._largerResourcesButton.title = WebInspector.UIString("Use small resource rows.");
this._dataGrid.element.removeStyleClass("small");
this._timelineGrid.element.removeStyleClass("small");
this._viewsContainerElement.removeStyleClass("small");
}
this._positionSummaryBar();
},

_getPopoverAnchor: function(element)
{
var anchor = element.enclosingNodeOrSelfWithClass("network-graph-bar") || element.enclosingNodeOrSelfWithClass("network-graph-label");
if (!anchor)
return null;
var resource = anchor.parentElement.resource;
return resource && resource.timing ? anchor : null;
},

_showPopover: function(anchor)
{
var resource = anchor.parentElement.resource;
var tableElement = WebInspector.ResourceTimingView.createTimingTable(resource);
var popover = new WebInspector.Popover(tableElement);
popover.show(anchor);
return popover;
},

_toggleGridMode: function()
{
if (this._viewingResourceMode) {
this._viewingResourceMode = false;
this.element.removeStyleClass("viewing-resource");
this._dataGrid.element.removeStyleClass("viewing-resource-mode");
this._viewsContainerElement.addStyleClass("hidden");
this.sidebarElement.style.right = 0;
this.sidebarElement.style.removeProperty("width");
this._summaryBarElement.style.removeProperty("width");
if (this._dataGrid.selectedNode)
this._dataGrid.selectedNode.selected = false;
}

if (this._briefGrid) {
this._dataGrid.element.removeStyleClass("full-grid-mode");
this._dataGrid.element.addStyleClass("brief-grid-mode");

this._dataGrid.hideColumn("method");
this._dataGrid.hideColumn("status");
this._dataGrid.hideColumn("type");
this._dataGrid.hideColumn("size");
this._dataGrid.hideColumn("time");

var widths = {};
widths.name = 20;
widths.timeline = 80;
} else {
this._dataGrid.element.addStyleClass("full-grid-mode");
this._dataGrid.element.removeStyleClass("brief-grid-mode");

this._dataGrid.showColumn("method");
this._dataGrid.showColumn("status");
this._dataGrid.showColumn("type");
this._dataGrid.showColumn("size");
this._dataGrid.showColumn("time");

var widths = {};
widths.name = 20;
widths.method = 7;
widths.status = 8;
widths.type = 10;
widths.size = 10;
widths.time = 10;
widths.timeline = 37;
}

this._dataGrid.showColumn("timeline");
this._dataGrid.applyColumnWidthsMap(widths);

},

_toggleViewingResourceMode: function()
{
if (this._viewingResourceMode)
return;
this._viewingResourceMode = true;
this._preservedColumnWidths = this._dataGrid.columnWidthsMap();

this.element.addStyleClass("viewing-resource");
this._dataGrid.element.addStyleClass("viewing-resource-mode");
this._dataGrid.element.removeStyleClass("full-grid-mode");
this._dataGrid.element.removeStyleClass("brief-grid-mode");

this._dataGrid.hideColumn("method");
this._dataGrid.hideColumn("status");
this._dataGrid.hideColumn("type");
this._dataGrid.hideColumn("size");
this._dataGrid.hideColumn("time");
this._dataGrid.hideColumn("timeline");

this._viewsContainerElement.removeStyleClass("hidden");
this.updateSidebarWidth(200);

var widths = {};
widths.name = 100;
this._dataGrid.applyColumnWidthsMap(widths);
}
}

WebInspector.NetworkPanel.prototype.__proto__ = WebInspector.Panel.prototype;

WebInspector.NetworkBaseCalculator = function()
{
}

WebInspector.NetworkBaseCalculator.prototype = {
computeSummaryValues: function(items)
{
var total = 0;
var categoryValues = {};

var itemsLength = items.length;
for (var i = 0; i < itemsLength; ++i) {
var item = items[i];
var value = this._value(item);
if (typeof value === "undefined")
continue;
if (!(item.category.name in categoryValues))
categoryValues[item.category.name] = 0;
categoryValues[item.category.name] += value;
total += value;
}

return {categoryValues: categoryValues, total: total};
},

computeBarGraphPercentages: function(item)
{
return {start: 0, middle: 0, end: (this._value(item) / this.boundarySpan) * 100};
},

computeBarGraphLabels: function(item)
{
const label = this.formatValue(this._value(item));
return {left: label, right: label, tooltip: label};
},

get boundarySpan()
{
return this.maximumBoundary - this.minimumBoundary;
},

updateBoundaries: function(item)
{
this.minimumBoundary = 0;

var value = this._value(item);
if (typeof this.maximumBoundary === "undefined" || value > this.maximumBoundary) {
this.maximumBoundary = value;
return true;
}
return false;
},

reset: function()
{
delete this.minimumBoundary;
delete this.maximumBoundary;
},

_value: function(item)
{
return 0;
},

formatValue: function(value)
{
return value.toString();
}
}

WebInspector.NetworkTimeCalculator = function(startAtZero)
{
WebInspector.NetworkBaseCalculator.call(this);
this.startAtZero = startAtZero;
}

WebInspector.NetworkTimeCalculator.prototype = {
computeSummaryValues: function(resources)
{
var resourcesByCategory = {};
var resourcesLength = resources.length;
for (var i = 0; i < resourcesLength; ++i) {
var resource = resources[i];
if (!(resource.category.name in resourcesByCategory))
resourcesByCategory[resource.category.name] = [];
resourcesByCategory[resource.category.name].push(resource);
}

var earliestStart;
var latestEnd;
var categoryValues = {};
for (var category in resourcesByCategory) {
resourcesByCategory[category].sort(WebInspector.Resource.CompareByTime);
categoryValues[category] = 0;

var segment = {start: -1, end: -1};

var categoryResources = resourcesByCategory[category];
var resourcesLength = categoryResources.length;
for (var i = 0; i < resourcesLength; ++i) {
var resource = categoryResources[i];
if (resource.startTime === -1 || resource.endTime === -1)
continue;

if (typeof earliestStart === "undefined")
earliestStart = resource.startTime;
else
earliestStart = Math.min(earliestStart, resource.startTime);

if (typeof latestEnd === "undefined")
latestEnd = resource.endTime;
else
latestEnd = Math.max(latestEnd, resource.endTime);

if (resource.startTime <= segment.end) {
segment.end = Math.max(segment.end, resource.endTime);
continue;
}

categoryValues[category] += segment.end - segment.start;

segment.start = resource.startTime;
segment.end = resource.endTime;
}


categoryValues[category] += segment.end - segment.start;
}

return {categoryValues: categoryValues, total: latestEnd - earliestStart};
},

computeBarGraphPercentages: function(resource)
{
if (resource.startTime !== -1)
var start = ((resource.startTime - this.minimumBoundary) / this.boundarySpan) * 100;
else
var start = 0;

if (resource.responseReceivedTime !== -1)
var middle = ((resource.responseReceivedTime - this.minimumBoundary) / this.boundarySpan) * 100;
else
var middle = (this.startAtZero ? start : 100);

if (resource.endTime !== -1)
var end = ((resource.endTime - this.minimumBoundary) / this.boundarySpan) * 100;
else
var end = (this.startAtZero ? middle : 100);

if (this.startAtZero) {
end -= start;
middle -= start;
start = 0;
}

return {start: start, middle: middle, end: end};
},

computePercentageFromEventTime: function(eventTime)
{



if (eventTime !== -1 && !this.startAtZero)
return ((eventTime - this.minimumBoundary) / this.boundarySpan) * 100;

return 0;
},

computeBarGraphLabels: function(resource)
{
var rightLabel = "";
if (resource.responseReceivedTime !== -1 && resource.endTime !== -1)
rightLabel = this.formatValue(resource.endTime - resource.responseReceivedTime);

var hasLatency = resource.latency > 0;
if (hasLatency)
var leftLabel = this.formatValue(resource.latency);
else
var leftLabel = rightLabel;

if (resource.timing)
return {left: leftLabel, right: rightLabel};

if (hasLatency && rightLabel) {
var total = this.formatValue(resource.duration);
var tooltip = WebInspector.UIString("%s latency, %s download (%s total)", leftLabel, rightLabel, total);
} else if (hasLatency)
var tooltip = WebInspector.UIString("%s latency", leftLabel);
else if (rightLabel)
var tooltip = WebInspector.UIString("%s download", rightLabel);

if (resource.cached)
tooltip = WebInspector.UIString("%s (from cache)", tooltip);
return {left: leftLabel, right: rightLabel, tooltip: tooltip};
},

updateBoundaries: function(resource)
{
var didChange = false;

var lowerBound;
if (this.startAtZero)
lowerBound = 0;
else
lowerBound = this._lowerBound(resource);

if (lowerBound !== -1 && (typeof this.minimumBoundary === "undefined" || lowerBound < this.minimumBoundary)) {
this.minimumBoundary = lowerBound;
didChange = true;
}

var upperBound = this._upperBound(resource);
if (upperBound !== -1 && (typeof this.maximumBoundary === "undefined" || upperBound > this.maximumBoundary)) {
this.maximumBoundary = upperBound;
didChange = true;
}

return didChange;
},

formatValue: function(value)
{
return Number.secondsToString(value, WebInspector.UIString);
},

_lowerBound: function(resource)
{
return 0;
},

_upperBound: function(resource)
{
return 0;
}
}

WebInspector.NetworkTimeCalculator.prototype.__proto__ = WebInspector.NetworkBaseCalculator.prototype;

WebInspector.NetworkTransferTimeCalculator = function()
{
WebInspector.NetworkTimeCalculator.call(this, false);
}

WebInspector.NetworkTransferTimeCalculator.prototype = {
formatValue: function(value)
{
return Number.secondsToString(value, WebInspector.UIString);
},

_lowerBound: function(resource)
{
return resource.startTime;
},

_upperBound: function(resource)
{
return resource.endTime;
}
}

WebInspector.NetworkTransferTimeCalculator.prototype.__proto__ = WebInspector.NetworkTimeCalculator.prototype;

WebInspector.NetworkTransferDurationCalculator = function()
{
WebInspector.NetworkTimeCalculator.call(this, true);
}

WebInspector.NetworkTransferDurationCalculator.prototype = {
formatValue: function(value)
{
return Number.secondsToString(value, WebInspector.UIString);
},

_upperBound: function(resource)
{
return resource.duration;
}
}

WebInspector.NetworkTransferDurationCalculator.prototype.__proto__ = WebInspector.NetworkTimeCalculator.prototype;

WebInspector.NetworkDataGridNode = function(panel, resource)
{
WebInspector.DataGridNode.call(this, {});
this._panel = panel;
this._resource = resource;
}

WebInspector.NetworkDataGridNode.prototype = {
createCells: function()
{
this._nameCell = this._createDivInTD("name");
this._methodCell = this._createDivInTD("method");
this._statusCell = this._createDivInTD("status");
this._typeCell = this._createDivInTD("type");
this._sizeCell = this._createDivInTD("size");
this._timeCell = this._createDivInTD("time");
this._createTimelineCell();
this._nameCell.addEventListener("click", this.select.bind(this), false);
},

select: function()
{
this._panel._showResource(this._resource);
WebInspector.DataGridNode.prototype.select.apply(this, arguments);
},

get selectable()
{
if (!this._panel._viewingResourceMode)
return false;
if (!this._panel._hiddenCategories.all)
return true;
if (this._panel._hiddenCategories[this._resource.category.name])
return false;
return true;
},

_createDivInTD: function(columnIdentifier)
{
var td = document.createElement("td");
td.className = columnIdentifier + "-column";
var div = document.createElement("div");
td.appendChild(div);
this._element.appendChild(td);
return div;
},

_createTimelineCell: function()
{
this._graphElement = document.createElement("div");
this._graphElement.className = "network-graph-side";

this._barAreaElement = document.createElement("div");

this._barAreaElement.className = "network-graph-bar-area";
this._barAreaElement.resource = this._resource;
this._graphElement.appendChild(this._barAreaElement);

this._barLeftElement = document.createElement("div");
this._barLeftElement.className = "network-graph-bar waiting";
this._barAreaElement.appendChild(this._barLeftElement);

this._barRightElement = document.createElement("div");
this._barRightElement.className = "network-graph-bar";
this._barAreaElement.appendChild(this._barRightElement);


this._labelLeftElement = document.createElement("div");
this._labelLeftElement.className = "network-graph-label waiting";
this._barAreaElement.appendChild(this._labelLeftElement);

this._labelRightElement = document.createElement("div");
this._labelRightElement.className = "network-graph-label";
this._barAreaElement.appendChild(this._labelRightElement);

this._graphElement.addEventListener("mouseover", this._refreshLabelPositions.bind(this), false);

this._timelineCell = document.createElement("td");
this._timelineCell.className = "timeline-column";
this._element.appendChild(this._timelineCell);
this._timelineCell.appendChild(this._graphElement);
},

refreshResource: function()
{
this._refreshNameCell();

this._methodCell.textContent = this._resource.requestMethod;

this._refreshStatusCell();

if (this._resource.mimeType) {
this._typeCell.removeStyleClass("network-dim-cell");
this._typeCell.textContent = this._resource.mimeType;
} else {
this._typeCell.addStyleClass("network-dim-cell");
this._typeCell.textContent = WebInspector.UIString("Pending");
}

this._refreshSizeCell();
this._refreshTimeCell();

if (this._resource.cached)
this._graphElement.addStyleClass("resource-cached");

if (!this._element.hasStyleClass("network-category-" + this._resource.category.name)) {
this._element.removeMatchingStyleClasses("network-category-\\w+");
this._element.addStyleClass("network-category-" + this._resource.category.name);
}
},

_refreshNameCell: function()
{
this._nameCell.removeChildren();

if (this._resource.category === WebInspector.resourceCategories.images) {
var previewImage = document.createElement("img");
previewImage.className = "image-network-icon-preview";

function onResourceContent()
{
previewImage.src = this._resource.contentURL;
}
if (Preferences.useDataURLForResourceImageIcons)
this._resource.requestContent(onResourceContent.bind(this));
else
previewImage.src = this._resource.url;

var iconElement = document.createElement("div");
iconElement.className = "icon";
iconElement.appendChild(previewImage);
} else {
var iconElement = document.createElement("img");
iconElement.className = "icon";
}
this._nameCell.appendChild(iconElement);
this._nameCell.appendChild(document.createTextNode(this._fileName()));


var subtitle = this._resource.displayDomain;

if (this._resource.path && this._resource.lastPathComponent) {
var lastPathComponentIndex = this._resource.path.lastIndexOf("/" + this._resource.lastPathComponent);
if (lastPathComponentIndex != -1)
subtitle += this._resource.path.substring(0, lastPathComponentIndex);
}

this._appendSubtitle(this._nameCell, subtitle);
this._nameCell.title = this._resource.url;
},

_fileName: function()
{
var fileName = this._resource.displayName;
if (this._resource.queryString)
fileName += "?" + this._resource.queryString;
return fileName;
},

_refreshStatusCell: function()
{
this._statusCell.removeChildren();

var fromCache = this._resource.cached;
if (fromCache) {
this._statusCell.textContent = WebInspector.UIString("(from cache)");
this._statusCell.addStyleClass("network-dim-cell");
return;
}

this._statusCell.removeStyleClass("network-dim-cell");
if (this._resource.statusCode) {
this._statusCell.appendChild(document.createTextNode(this._resource.statusCode));
this._statusCell.removeStyleClass("network-dim-cell");
this._appendSubtitle(this._statusCell, this._resource.statusText);
this._statusCell.title = this._resource.statusCode + " " + this._resource.statusText;
} else {
this._statusCell.addStyleClass("network-dim-cell");
this._statusCell.textContent = WebInspector.UIString("Pending");
}
},

_refreshSizeCell: function()
{
var resourceSize = typeof this._resource.resourceSize === "number" ? Number.bytesToString(this._resource.resourceSize) : "?";
var transferSize = typeof this._resource.transferSize === "number" ? Number.bytesToString(this._resource.transferSize) : "?";
var fromCache = this._resource.cached;
this._sizeCell.textContent = !fromCache ? resourceSize : WebInspector.UIString("(from cache)");
if (fromCache)
this._sizeCell.addStyleClass("network-dim-cell");
else
this._sizeCell.removeStyleClass("network-dim-cell");
if (!fromCache)
this._appendSubtitle(this._sizeCell, transferSize);
},

_refreshTimeCell: function()
{
if (this._resource.duration > 0) {
this._timeCell.removeStyleClass("network-dim-cell");
this._timeCell.textContent = Number.secondsToString(this._resource.duration);
this._appendSubtitle(this._timeCell, Number.secondsToString(this._resource.latency));
} else {
this._timeCell.addStyleClass("network-dim-cell");
this._timeCell.textContent = WebInspector.UIString("Pending");
}
},

_appendSubtitle: function(cellElement, subtitleText)
{
var subtitleElement = document.createElement("div");
subtitleElement.className = "network-cell-subtitle";
subtitleElement.textContent = subtitleText;
cellElement.appendChild(subtitleElement);
},

refreshGraph: function(calculator)
{
var percentages = calculator.computeBarGraphPercentages(this._resource);
this._percentages = percentages;

this._barAreaElement.removeStyleClass("hidden");

if (!this._graphElement.hasStyleClass("network-category-" + this._resource.category.name)) {
this._graphElement.removeMatchingStyleClasses("network-category-\\w+");
this._graphElement.addStyleClass("network-category-" + this._resource.category.name);
}

this._barLeftElement.style.setProperty("left", percentages.start + "%");
this._barRightElement.style.setProperty("right", (100 - percentages.end) + "%");

this._barLeftElement.style.setProperty("right", (100 - percentages.end) + "%");
this._barRightElement.style.setProperty("left", percentages.middle + "%");

var labels = calculator.computeBarGraphLabels(this._resource);
this._labelLeftElement.textContent = labels.left;
this._labelRightElement.textContent = labels.right;

var tooltip = (labels.tooltip || "");
this._barLeftElement.title = tooltip;
this._labelLeftElement.title = tooltip;
this._labelRightElement.title = tooltip;
this._barRightElement.title = tooltip;
},

_refreshLabelPositions: function()
{
if (!this._percentages)
return;
this._labelLeftElement.style.removeProperty("left");
this._labelLeftElement.style.removeProperty("right");
this._labelLeftElement.removeStyleClass("before");
this._labelLeftElement.removeStyleClass("hidden");

this._labelRightElement.style.removeProperty("left");
this._labelRightElement.style.removeProperty("right");
this._labelRightElement.removeStyleClass("after");
this._labelRightElement.removeStyleClass("hidden");

const labelPadding = 10;
const barRightElementOffsetWidth = this._barRightElement.offsetWidth;
const barLeftElementOffsetWidth = this._barLeftElement.offsetWidth;

if (this._barLeftElement) {
var leftBarWidth = barLeftElementOffsetWidth - labelPadding;
var rightBarWidth = (barRightElementOffsetWidth - barLeftElementOffsetWidth) - labelPadding;
} else {
var leftBarWidth = (barLeftElementOffsetWidth - barRightElementOffsetWidth) - labelPadding;
var rightBarWidth = barRightElementOffsetWidth - labelPadding;
}

const labelLeftElementOffsetWidth = this._labelLeftElement.offsetWidth;
const labelRightElementOffsetWidth = this._labelRightElement.offsetWidth;

const labelBefore = (labelLeftElementOffsetWidth > leftBarWidth);
const labelAfter = (labelRightElementOffsetWidth > rightBarWidth);
const graphElementOffsetWidth = this._graphElement.offsetWidth;

if (labelBefore && (graphElementOffsetWidth * (this._percentages.start / 100)) < (labelLeftElementOffsetWidth + 10))
var leftHidden = true;

if (labelAfter && (graphElementOffsetWidth * ((100 - this._percentages.end) / 100)) < (labelRightElementOffsetWidth + 10))
var rightHidden = true;

if (barLeftElementOffsetWidth == barRightElementOffsetWidth) {

if (labelBefore && !labelAfter)
leftHidden = true;
else if (labelAfter && !labelBefore)
rightHidden = true;
}

if (labelBefore) {
if (leftHidden)
this._labelLeftElement.addStyleClass("hidden");
this._labelLeftElement.style.setProperty("right", (100 - this._percentages.start) + "%");
this._labelLeftElement.addStyleClass("before");
} else {
this._labelLeftElement.style.setProperty("left", this._percentages.start + "%");
this._labelLeftElement.style.setProperty("right", (100 - this._percentages.middle) + "%");
}

if (labelAfter) {
if (rightHidden)
this._labelRightElement.addStyleClass("hidden");
this._labelRightElement.style.setProperty("left", this._percentages.end + "%");
this._labelRightElement.addStyleClass("after");
} else {
this._labelRightElement.style.setProperty("left", this._percentages.middle + "%");
this._labelRightElement.style.setProperty("right", (100 - this._percentages.end) + "%");
}
}
}

WebInspector.NetworkDataGridNode.NameComparator = function(a, b)
{
var aFileName = a._resource.displayName + (a._resource.queryString ? a._resource.queryString : "");
var bFileName = b._resource.displayName + (b._resource.queryString ? b._resource.queryString : "");
if (aFileName > bFileName)
return 1;
if (bFileName > aFileName)
return -1;
return 0;
}

WebInspector.NetworkDataGridNode.SizeComparator = function(a, b)
{
if (b._resource.cached && !a._resource.cached)
return 1;
if (a._resource.cached && !b._resource.cached)
return -1;

if (a._resource.resourceSize === b._resource.resourceSize)
return 0;

return a._resource.resourceSize - b._resource.resourceSize;
}

WebInspector.NetworkDataGridNode.ResourcePropertyComparator = function(propertyName, revert, a, b)
{
var aValue = a._resource[propertyName];
var bValue = b._resource[propertyName];
if (aValue > bValue)
return revert ? -1 : 1;
if (bValue > aValue)
return revert ? 1 : -1;
return 0;
}

WebInspector.NetworkDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;

WebInspector.NetworkTotalGridNode = function(element)
{
this._summaryBarElement = element;
WebInspector.DataGridNode.call(this, {summaryRow: true});
}

WebInspector.NetworkTotalGridNode.prototype = {
createCells: function()
{
var td = document.createElement("td");
td.setAttribute("colspan", 7);
td.className = "network-summary";
td.appendChild(this._summaryBarElement);
this._element.appendChild(td);
}
}

WebInspector.NetworkTotalGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;





var InjectedFakeWorker = function(InjectedScriptHost, inspectedWindow, injectedScriptId)
{

Worker = function(url)
{
var impl = new FakeWorker(this, url);
if (impl === null)
return null;

this.isFake = true;
this.postMessage = bind(impl.postMessage, impl);
this.terminate = bind(impl.terminate, impl);

function onmessageGetter()
{
return impl.channel.port1.onmessage;
}
function onmessageSetter(callback)
{
impl.channel.port1.onmessage = callback;
}
this.__defineGetter__("onmessage", onmessageGetter);
this.__defineSetter__("onmessage", onmessageSetter);
this.addEventListener = bind(impl.channel.port1.addEventListener, impl.channel.port1);
this.removeEventListener = bind(impl.channel.port1.removeEventListener, impl.channel.port1);
this.dispatchEvent = bind(impl.channel.port1.dispatchEvent, impl.channel.port1);
}

function FakeWorker(worker, url)
{
var scriptURL = this._expandURLAndCheckOrigin(document.baseURI, location.href, url);

this._worker = worker;
this._id = InjectedScriptHost.nextWorkerId();
this.channel = new MessageChannel();
this._listeners = [];
this._buildWorker(scriptURL);

InjectedScriptHost.didCreateWorker(this._id, scriptURL.url, false);
}

FakeWorker.prototype = {
postMessage: function(msg, opt_ports)
{
if (this._frame != null)
this.channel.port1.postMessage.apply(this.channel.port1, arguments);
else if (this._pendingMessages)
this._pendingMessages.push(arguments)
else
this._pendingMessages = [ arguments ];
},

terminate: function()
{
InjectedScriptHost.didDestroyWorker(this._id);

this.channel.port1.close();
this.channel.port2.close();
if (this._frame != null)
this._frame.frameElement.parentNode.removeChild(this._frame.frameElement);
this._frame = null;
this._worker = null; 
},

_buildWorker: function(url)
{
var code = this._loadScript(url.url);
var iframeElement = document.createElement("iframe");
iframeElement.style.display = "none";

this._document = document;
iframeElement.onload = bind(this._onWorkerFrameLoaded, this, iframeElement, url, code);

if (document.body)
this._attachWorkerFrameToDocument(iframeElement, url, code);
else
window.addEventListener("load", bind(this._attachWorkerFrameToDocument, this, iframeElement), false);
},

_attachWorkerFrameToDocument: function(iframeElement)
{
document.body.appendChild(iframeElement);
},

_onWorkerFrameLoaded: function(iframeElement, url, code)
{
var frame = iframeElement.contentWindow;
this._frame = frame;
this._setupWorkerContext(frame, url);

var frameContents = '(function() { var location = __devtools.location; var window; ' + code + '})();\n' + '//@ sourceURL=' + url.url;

frame.eval(frameContents);
if (this._pendingMessages) {
for (var msg = 0; msg < this._pendingMessages.length; ++msg)
this.postMessage.apply(this, this._pendingMessages[msg]);
delete this._pendingMessages;
}
},

_setupWorkerContext: function(workerFrame, url)
{
workerFrame.__devtools = {
handleException: bind(this._handleException, this),
location: url.mockLocation()
};

var self = this;

function onmessageGetter()
{
return self.channel.port2.onmessage ? self.channel.port2.onmessage.originalCallback : null;
}

function onmessageSetter(callback)
{
var wrappedCallback = bind(self._callbackWrapper, self, callback);
wrappedCallback.originalCallback = callback;
self.channel.port2.onmessage = wrappedCallback;
}

workerFrame.__defineGetter__("onmessage", onmessageGetter);
workerFrame.__defineSetter__("onmessage", onmessageSetter);
workerFrame.addEventListener = bind(this._addEventListener, this);
workerFrame.removeEventListener = bind(this._removeEventListener, this);
workerFrame.dispatchEvent = bind(this.channel.port2.dispatchEvent, this.channel.port2);
workerFrame.postMessage = bind(this.channel.port2.postMessage, this.channel.port2);
workerFrame.importScripts = bind(this._importScripts, this, workerFrame);
workerFrame.close = bind(this.terminate, this);
},

_addEventListener: function(type, callback, useCapture)
{
var wrappedCallback = bind(this._callbackWrapper, this, callback);
wrappedCallback.originalCallback = callback;
wrappedCallback.type = type;
wrappedCallback.useCapture = Boolean(useCapture);

this.channel.port2.addEventListener(type, wrappedCallback, useCapture);
this._listeners.push(wrappedCallback);
},

_removeEventListener: function(type, callback, useCapture)
{
var listeners = this._listeners;
for (var i = 0; i < listeners.length; ++i) {
if (listeners[i].originalCallback === callback &&
listeners[i].type === type && 
listeners[i].useCapture === Boolean(useCapture)) {
this.channel.port2.removeEventListener(type, listeners[i], useCapture);
listeners[i] = listeners[listeners.length - 1];
listeners.pop();
break;
}
}
},

_callbackWrapper: function(callback, msg)
{

if (!this._frame.onerror && !this._worker.onerror) {
callback(msg);
return;
}

try {
callback(msg);
} catch (e) {
this._handleException(e, this._frame.onerror, this._worker.onerror);
}
},

_handleException: function(e)
{


var errorEvent = this._document.createEvent("Event");
errorEvent.initEvent("Event", false, false);
errorEvent.message = "Uncaught exception";

for (var i = 1; i < arguments.length; ++i) {
if (arguments[i] && arguments[i](errorEvent))
return;
}

throw e;
},

_importScripts: function(targetFrame)
{
for (var i = 1; i < arguments.length; ++i) {
var workerOrigin = targetFrame.__devtools.location.href;
var url = this._expandURLAndCheckOrigin(workerOrigin, workerOrigin, arguments[i]);
targetFrame.eval(this._loadScript(url.url) + "\n//@ sourceURL= " + url.url);
}
},

_loadScript: function(url)
{
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.send(null);

var text = xhr.responseText;
if (xhr.status != 0 && xhr.status/100 !== 2) { 
console.error("Failed to load worker: " + url + "[" + xhr.status + "]");
text = ""; 
}
return text;
},

_expandURLAndCheckOrigin: function(baseURL, origin, url)
{
var scriptURL = new URL(baseURL).completeWith(url);

if (!scriptURL.sameOrigin(origin))
throw new DOMCoreException("SECURITY_ERR",18);
return scriptURL;
}
};

function URL(url)
{
this.url = url;
this.split();
}

URL.prototype = {
urlRegEx: (/^(http[s]?|file):\/\/([^\/:]*)(:[\d]+)?(?:(\/[^#?]*)(\?[^#]*)?(?:#(.*))?)?$/i),

split: function()
{
function emptyIfNull(str)
{
return str == null ? "" : str;
}
var parts = this.urlRegEx.exec(this.url);

this.schema = parts[1];
this.host = parts[2];
this.port = emptyIfNull(parts[3]);
this.path = emptyIfNull(parts[4]);
this.query = emptyIfNull(parts[5]);
this.fragment = emptyIfNull(parts[6]);
},

mockLocation: function()
{
var host = this.host.replace(/^[^@]*@/, "");

return {
href:     this.url,
protocol: this.schema + ":",
host:     host,
hostname: host,
port:     this.port,
pathname: this.path,
search:   this.query,
hash:     this.fragment
};
},

completeWith: function(url)
{
if (url === "" || /^[^/]*:/.exec(url)) // If given absolute url, return as is now.
return new URL(url);

var relParts = /^([^#?]*)(.*)$/.exec(url); 

var path = (relParts[1].slice(0, 1) === "/" ? "" : this.path.replace(/[^/]*$/, "")) + relParts[1];
path = path.replace(/(\/\.)+(\/|$)/g, "/").replace(/[^/]*\/\.\.(\/|$)/g, "");

return new URL(this.schema + "://" + this.host + this.port + path + relParts[2]);
},

sameOrigin: function(url)
{
function normalizePort(schema, port)
{
var portNo = port.slice(1);
return (schema === "https" && portNo == 443 || schema === "http" && portNo == 80) ? "" : port;
}

var other = new URL(url);

return this.schema === other.schema &&
this.host === other.host &&
normalizePort(this.schema, this.port) === normalizePort(other.schema, other.port);
}
};

function DOMCoreException(name, code)
{
function formatError()
{
return "Error: " + this.message;
}

this.name = name;
this.message = name + ": DOM Exception " + code;
this.code = code;
this.toString = bind(formatError, this);
}

function bind(func, thisObject)
{
var args = Array.prototype.slice.call(arguments, 2);
return function() { return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0))); };
}

function noop()
{
}

}





WebInspector.ScriptsPanel = function()
{
WebInspector.Panel.call(this, "scripts");

this.topStatusBar = document.createElement("div");
this.topStatusBar.className = "status-bar";
this.topStatusBar.id = "scripts-status-bar";
this.element.appendChild(this.topStatusBar);

this.backButton = document.createElement("button");
this.backButton.className = "status-bar-item";
this.backButton.id = "scripts-back";
this.backButton.title = WebInspector.UIString("Show the previous script resource.");
this.backButton.disabled = true;
this.backButton.appendChild(document.createElement("img"));
this.backButton.addEventListener("click", this._goBack.bind(this), false);
this.topStatusBar.appendChild(this.backButton);

this.forwardButton = document.createElement("button");
this.forwardButton.className = "status-bar-item";
this.forwardButton.id = "scripts-forward";
this.forwardButton.title = WebInspector.UIString("Show the next script resource.");
this.forwardButton.disabled = true;
this.forwardButton.appendChild(document.createElement("img"));
this.forwardButton.addEventListener("click", this._goForward.bind(this), false);
this.topStatusBar.appendChild(this.forwardButton);

this.filesSelectElement = document.createElement("select");
this.filesSelectElement.className = "status-bar-item";
this.filesSelectElement.id = "scripts-files";
this.filesSelectElement.addEventListener("change", this._changeVisibleFile.bind(this), false);
this.topStatusBar.appendChild(this.filesSelectElement);

this.functionsSelectElement = document.createElement("select");
this.functionsSelectElement.className = "status-bar-item";
this.functionsSelectElement.id = "scripts-functions";




this.sidebarButtonsElement = document.createElement("div");
this.sidebarButtonsElement.id = "scripts-sidebar-buttons";
this.topStatusBar.appendChild(this.sidebarButtonsElement);

this.pauseButton = document.createElement("button");
this.pauseButton.className = "status-bar-item";
this.pauseButton.id = "scripts-pause";
this.pauseButton.title = WebInspector.UIString("Pause script execution.");
this.pauseButton.disabled = true;
this.pauseButton.appendChild(document.createElement("img"));
this.pauseButton.addEventListener("click", this._togglePause.bind(this), false);
this.sidebarButtonsElement.appendChild(this.pauseButton);

this.stepOverButton = document.createElement("button");
this.stepOverButton.className = "status-bar-item";
this.stepOverButton.id = "scripts-step-over";
this.stepOverButton.title = WebInspector.UIString("Step over next function call.");
this.stepOverButton.disabled = true;
this.stepOverButton.addEventListener("click", this._stepOverClicked.bind(this), false);
this.stepOverButton.appendChild(document.createElement("img"));
this.sidebarButtonsElement.appendChild(this.stepOverButton);

this.stepIntoButton = document.createElement("button");
this.stepIntoButton.className = "status-bar-item";
this.stepIntoButton.id = "scripts-step-into";
this.stepIntoButton.title = WebInspector.UIString("Step into next function call.");
this.stepIntoButton.disabled = true;
this.stepIntoButton.addEventListener("click", this._stepIntoClicked.bind(this), false);
this.stepIntoButton.appendChild(document.createElement("img"));
this.sidebarButtonsElement.appendChild(this.stepIntoButton);

this.stepOutButton = document.createElement("button");
this.stepOutButton.className = "status-bar-item";
this.stepOutButton.id = "scripts-step-out";
this.stepOutButton.title = WebInspector.UIString("Step out of current function.");
this.stepOutButton.disabled = true;
this.stepOutButton.addEventListener("click", this._stepOutClicked.bind(this), false);
this.stepOutButton.appendChild(document.createElement("img"));
this.sidebarButtonsElement.appendChild(this.stepOutButton);

this.toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate all breakpoints."), "toggle-breakpoints");
this.toggleBreakpointsButton.toggled = true;
this.toggleBreakpointsButton.addEventListener("click", this.toggleBreakpointsClicked.bind(this), false);
this.sidebarButtonsElement.appendChild(this.toggleBreakpointsButton.element);

this.debuggerStatusElement = document.createElement("div");
this.debuggerStatusElement.id = "scripts-debugger-status";
this.sidebarButtonsElement.appendChild(this.debuggerStatusElement);

this.viewsContainerElement = document.createElement("div");
this.viewsContainerElement.id = "script-resource-views";

this.sidebarElement = document.createElement("div");
this.sidebarElement.id = "scripts-sidebar";

this.sidebarResizeElement = document.createElement("div");
this.sidebarResizeElement.className = "sidebar-resizer-vertical";
this.sidebarResizeElement.addEventListener("mousedown", this._startSidebarResizeDrag.bind(this), false);

this.sidebarResizeWidgetElement = document.createElement("div");
this.sidebarResizeWidgetElement.id = "scripts-sidebar-resizer-widget";
this.sidebarResizeWidgetElement.addEventListener("mousedown", this._startSidebarResizeDrag.bind(this), false);
this.topStatusBar.appendChild(this.sidebarResizeWidgetElement);

this.sidebarPanes = {};
this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
this.sidebarPanes.jsBreakpoints = WebInspector.createJSBreakpointsSidebarPane();
if (Preferences.nativeInstrumentationEnabled) {
this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
this.sidebarPanes.xhrBreakpoints = WebInspector.createXHRBreakpointsSidebarPane();
this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane();
}

this.sidebarPanes.workers = new WebInspector.WorkersSidebarPane();

for (var pane in this.sidebarPanes)
this.sidebarElement.appendChild(this.sidebarPanes[pane].element);

this.sidebarPanes.callstack.expanded = true;
this.sidebarPanes.callstack.addEventListener("call frame selected", this._callFrameSelected, this);

this.sidebarPanes.scopechain.expanded = true;
this.sidebarPanes.jsBreakpoints.expanded = true;

var panelEnablerHeading = WebInspector.UIString("You need to enable debugging before you can use the Scripts panel.");
var panelEnablerDisclaimer = WebInspector.UIString("Enabling debugging will make scripts run slower.");
var panelEnablerButton = WebInspector.UIString("Enable Debugging");

this.panelEnablerView = new WebInspector.PanelEnablerView("scripts", panelEnablerHeading, panelEnablerDisclaimer, panelEnablerButton);
this.panelEnablerView.addEventListener("enable clicked", this._enableDebugging, this);

this.element.appendChild(this.panelEnablerView.element);
this.element.appendChild(this.viewsContainerElement);
this.element.appendChild(this.sidebarElement);
this.element.appendChild(this.sidebarResizeElement);

this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggle-status-bar-item");
this.enableToggleButton.addEventListener("click", this._toggleDebugging.bind(this), false);
if (Preferences.debuggerAlwaysEnabled)
this.enableToggleButton.element.addStyleClass("hidden");

this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item", 3);
this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions.bind(this), false);
this._pauseOnExceptionButton.state = WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions;
this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");

this._registerShortcuts();

this._debuggerEnabled = Preferences.debuggerAlwaysEnabled;

WebInspector.breakpointManager.addEventListener("breakpoint-added", this._breakpointAdded, this);

this.reset();
}


WebInspector.ScriptsPanel.PauseOnExceptionsState = {
DontPauseOnExceptions : 0,
PauseOnAllExceptions : 1,
PauseOnUncaughtExceptions: 2
};

WebInspector.ScriptsPanel.prototype = {
get toolbarItemLabel()
{
return WebInspector.UIString("Scripts");
},

get statusBarItems()
{
return [this.enableToggleButton.element, this._pauseOnExceptionButton.element];
},

get defaultFocusedElement()
{
return this.filesSelectElement;
},

get paused()
{
return this._paused;
},

show: function()
{
WebInspector.Panel.prototype.show.call(this);
this.sidebarResizeElement.style.right = (this.sidebarElement.offsetWidth - 3) + "px";

if (this.visibleView)
this.visibleView.show(this.viewsContainerElement);

if (this._attachDebuggerWhenShown) {
InspectorBackend.enableDebugger(false);
delete this._attachDebuggerWhenShown;
}
},

hide: function()
{
if (this.visibleView)
this.visibleView.hide();
WebInspector.Panel.prototype.hide.call(this);
},

get breakpointsActivated()
{
return this.toggleBreakpointsButton.toggled;
},

addScript: function(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, scriptWorldType)
{
var script = new WebInspector.Script(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, scriptWorldType);
this._sourceIDMap[sourceID] = script;

var resource = WebInspector.resourceForURL(sourceURL);
if (resource) {
if (resource.finished) {

resource.addScript(script);
this._sourceIDMap[sourceID] = resource;
var view = WebInspector.ResourceManager.existingResourceViewForResource(resource);
if (view && view.sourceFrame)
view.sourceFrame.addScript(script);
} else {

if (!resource._scriptsPendingResourceLoad) {
resource._scriptsPendingResourceLoad = [];
resource.addEventListener("finished", this._resourceLoadingFinished, this);
}
resource._scriptsPendingResourceLoad.push(script);
}
}
this._addScriptToFilesMenu(script);
},

continueToLine: function(sourceID, line)
{
WebInspector.breakpointManager.setOneTimeBreakpoint(sourceID, line);
if (this.paused)
this._togglePause();
},

_resourceLoadingFinished: function(e)
{
var resource = e.target;
for (var i = 0; i < resource._scriptsPendingResourceLoad.length; ++i) {

var script = resource._scriptsPendingResourceLoad[i];
resource.addScript(script);
this._sourceIDMap[script.sourceID] = resource;


script.filesSelectOption.parentElement.removeChild(script.filesSelectOption);
}

this._addScriptToFilesMenu(resource._scriptsPendingResourceLoad[0]);
delete resource._scriptsPendingResourceLoad;
},

_breakpointAdded: function(event)
{
var breakpoint = event.data;

var sourceFrame;
if (breakpoint.url) {
var resource = WebInspector.resourceForURL(breakpoint.url);
if (resource && resource.finished)
sourceFrame = this._sourceFrameForScriptOrResource(resource);
}

if (breakpoint.sourceID && !sourceFrame) {
var object = this._sourceIDMap[breakpoint.sourceID]
sourceFrame = this._sourceFrameForScriptOrResource(object);
}

if (sourceFrame)
sourceFrame.addBreakpoint(breakpoint);
},

canEditScripts: function()
{
return Preferences.canEditScriptSource;
},

editScriptSource: function(editData, commitEditingCallback, cancelEditingCallback)
{
if (!this.canEditScripts())
return;


var breakpoints = WebInspector.breakpointManager.breakpointsForSourceID(sourceID);
for (var i = 0; i < breakpoints.length; ++i)
breakpoints[i].remove();

function mycallback(success, newBodyOrErrorMessage, callFrames)
{
if (success) {
commitEditingCallback(newBodyOrErrorMessage);
if (callFrames && callFrames.length)
this.debuggerPaused(callFrames);
} else {
if (cancelEditingCallback)
cancelEditingCallback();
WebInspector.log(newBodyOrErrorMessage, WebInspector.ConsoleMessage.MessageLevel.Warning);
}
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
var newLine = breakpoint.line;
if (success && breakpoint.line >= editData.line)
newLine += editData.linesCountToShift;
WebInspector.breakpointManager.setBreakpoint(editData.sourceID, breakpoint.url, newLine, breakpoint.enabled, breakpoint.condition);
}
};
InspectorBackend.editScriptSource(editData.sourceID, editData.content, mycallback.bind(this));
},

selectedCallFrameId: function()
{
var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame;
if (!selectedCallFrame)
return null;
return selectedCallFrame.id;
},

evaluateInSelectedCallFrame: function(code, updateInterface, objectGroup, callback)
{
var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame;
if (!this._paused || !selectedCallFrame)
return;

if (typeof updateInterface === "undefined")
updateInterface = true;

var self = this;
function updatingCallbackWrapper(result)
{
callback(result);
if (updateInterface)
self.sidebarPanes.scopechain.update(selectedCallFrame);
}
this.doEvalInCallFrame(selectedCallFrame, code, objectGroup, updatingCallbackWrapper);
},

doEvalInCallFrame: function(callFrame, code, objectGroup, callback)
{
function evalCallback(result)
{
if (result)
callback(WebInspector.RemoteObject.fromPayload(result));
}
InjectedScriptAccess.get(callFrame.worldId).evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback);
},

debuggerPaused: function(callFrames)
{
WebInspector.breakpointManager.removeOneTimeBreakpoint();
this._paused = true;
this._waitingToPause = false;
this._stepping = false;

this._updateDebuggerButtons();

WebInspector.currentPanel = this;

this.sidebarPanes.callstack.update(callFrames, this._sourceIDMap);
this.sidebarPanes.callstack.selectedCallFrame = callFrames[0];

window.focus();
},

debuggerResumed: function()
{
this._paused = false;
this._waitingToPause = false;
this._stepping = false;

this._clearInterface();
},

attachDebuggerWhenShown: function()
{
if (this.element.parentElement) {
InspectorBackend.enableDebugger(false);
} else {
this._attachDebuggerWhenShown = true;
}
},

debuggerWasEnabled: function()
{
if (this._debuggerEnabled)
return;

this._debuggerEnabled = true;
this.reset(true);
},

debuggerWasDisabled: function()
{
if (!this._debuggerEnabled)
return;

this._debuggerEnabled = false;
this.reset(true);
},

reset: function(preserveItems)
{
this.visibleView = null;

delete this.currentQuery;
this.searchCanceled();

this.debuggerResumed();

this._backForwardList = [];
this._currentBackForwardIndex = -1;
this._updateBackAndForwardButtons();

this._resourceForURLInFilesSelect = {};
this.filesSelectElement.removeChildren();
this.functionsSelectElement.removeChildren();
this.viewsContainerElement.removeChildren();

if (this._sourceIDMap) {
for (var sourceID in this._sourceIDMap) {
var object = this._sourceIDMap[sourceID];
if (object instanceof WebInspector.Resource)
object.removeAllScripts();
}
}

this._sourceIDMap = {};

this.sidebarPanes.watchExpressions.refreshExpressions();
if (!preserveItems) {
this.sidebarPanes.jsBreakpoints.reset();
if (Preferences.nativeInstrumentationEnabled) {
this.sidebarPanes.domBreakpoints.reset();
this.sidebarPanes.xhrBreakpoints.reset();
this.sidebarPanes.eventListenerBreakpoints.reset();
}
this.sidebarPanes.workers.reset();
}
},

get visibleView()
{
return this._visibleView;
},

set visibleView(x)
{
if (this._visibleView === x)
return;

if (this._visibleView)
this._visibleView.hide();

this._visibleView = x;

if (x)
x.show(this.viewsContainerElement);
},

viewRecreated: function(oldView, newView)
{
if (this._visibleView === oldView)
this._visibleView = newView;
},

canShowSourceLine: function(url, line)
{
if (!this._debuggerEnabled)
return false;
return !!this._scriptOrResourceForURLAndLine(url, line);
},

showSourceLine: function(url, line)
{
var scriptOrResource = this._scriptOrResourceForURLAndLine(url, line);
this._showScriptOrResource(scriptOrResource, {line: line, shouldHighlightLine: true});
},

_scriptOrResourceForURLAndLine: function(url, line)
{
var scriptWithMatchingUrl = null;
for (var sourceID in this._sourceIDMap) {
var scriptOrResource = this._sourceIDMap[sourceID];
if (scriptOrResource instanceof WebInspector.Script) {
if (scriptOrResource.sourceURL !== url)
continue;
scriptWithMatchingUrl = scriptOrResource;
if (scriptWithMatchingUrl.startingLine <= line && scriptWithMatchingUrl.startingLine + scriptWithMatchingUrl.linesCount > line)
return scriptWithMatchingUrl;
} else {
var resource = scriptOrResource;
if (resource.url === url)
return resource;
}
}
return scriptWithMatchingUrl;
},

showView: function(view)
{
if (!view)
return;
this._showScriptOrResource(view.resource || view.script);
},

handleShortcut: function(event)
{
var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcut];
if (handler) {
handler(event);
event.handled = true;
} else
this.sidebarPanes.callstack.handleShortcut(event);
},

scriptViewForScript: function(script)
{
if (!script)
return null;
if (!script._scriptView)
script._scriptView = new WebInspector.ScriptView(script);
return script._scriptView;
},

sourceFrameForScript: function(script)
{
var view = this.scriptViewForScript(script);
if (!view)
return null;


if (!this.element.parentNode)
this.attach();

view.setupSourceFrameIfNeeded();
return view.sourceFrame;
},

_sourceFrameForScriptOrResource: function(scriptOrResource)
{
if (scriptOrResource instanceof WebInspector.Resource)
return this._sourceFrameForResource(scriptOrResource);
if (scriptOrResource instanceof WebInspector.Script)
return this.sourceFrameForScript(scriptOrResource);
},

_sourceFrameForResource: function(resource)
{
var view = WebInspector.ResourceManager.resourceViewForResource(resource);
if (!view)
return null;

if (!view.setupSourceFrameIfNeeded)
return null;

view.setupSourceFrameIfNeeded();
return view.sourceFrame;
},

_showScriptOrResource: function(scriptOrResource, options)
{

options = options || {};

if (!scriptOrResource)
return;

var view;
if (scriptOrResource instanceof WebInspector.Resource)
view = WebInspector.ResourceManager.resourceViewForResource(scriptOrResource);
else if (scriptOrResource instanceof WebInspector.Script)
view = this.scriptViewForScript(scriptOrResource);

if (!view)
return;

var url = scriptOrResource.url || scriptOrResource.sourceURL;
if (url && !options.initialLoad)
WebInspector.settings.lastViewedScriptFile = url;

if (!options.fromBackForwardAction) {
var oldIndex = this._currentBackForwardIndex;
if (oldIndex >= 0)
this._backForwardList.splice(oldIndex + 1, this._backForwardList.length - oldIndex);



var previousEntryIndex = this._backForwardList.indexOf(scriptOrResource);
if (previousEntryIndex !== -1) {
this._backForwardList.splice(previousEntryIndex, 1);
--this._currentBackForwardIndex;
}

this._backForwardList.push(scriptOrResource);
++this._currentBackForwardIndex;

this._updateBackAndForwardButtons();
}

this.visibleView = view;

if (options.line) {
if (view.revealLine)
view.revealLine(options.line);
if (view.highlightLine && options.shouldHighlightLine)
view.highlightLine(options.line);
}

var option;
if (scriptOrResource instanceof WebInspector.Script) {
option = scriptOrResource.filesSelectOption;



if (!option) {
this._addScriptToFilesMenu(scriptOrResource, true);
option = scriptOrResource.filesSelectOption;
}

console.assert(option);
} else
option = scriptOrResource.filesSelectOption;

if (option)
this.filesSelectElement.selectedIndex = option.index;
},

_addScriptToFilesMenu: function(script, force)
{
if (!script.sourceURL && !force)
return;

if (script.resource) {
if (this._resourceForURLInFilesSelect[script.resource.url])
return;
this._resourceForURLInFilesSelect[script.resource.url] = script.resource;
}

var displayName = script.sourceURL ? WebInspector.displayNameForURL(script.sourceURL) : WebInspector.UIString("(program)");

var select = this.filesSelectElement;
var option = document.createElement("option");
option.representedObject = script.resource || script;
option.url = displayName;
option.startingLine = script.startingLine;
option.text = script.resource || script.startingLine === 1 ? displayName : String.sprintf("%s:%d", displayName, script.startingLine);

function optionCompare(a, b)
{
if (a.url < b.url)
return -1;
else if (a.url > b.url)
return 1;

if (typeof a.startingLine !== "number")
return -1;
if (typeof b.startingLine !== "number")
return -1;
return a.startingLine - b.startingLine;
}

var insertionIndex = insertionIndexForObjectInListSortedByFunction(option, select.childNodes, optionCompare);
if (insertionIndex < 0)
select.appendChild(option);
else
select.insertBefore(option, select.childNodes.item(insertionIndex));

if (script.resource)
script.resource.filesSelectOption = option;
else
script.filesSelectOption = option;

if (select.options[select.selectedIndex] === option) {


this._showScriptOrResource(option.representedObject, {initialLoad: true});
} else {

var url = option.representedObject.url || option.representedObject.sourceURL;
var lastURL = WebInspector.settings.lastViewedScriptFile;
if (url && url === lastURL) {



var isResource = !!option.representedObject.url;
if (isResource || !this.visibleView || !this.visibleView.script || this.visibleView.script.sourceURL !== url)
this._showScriptOrResource(option.representedObject, {initialLoad: true});
}
}

if (script.worldType === WebInspector.Script.WorldType.EXTENSIONS_WORLD)
script.filesSelectOption.addStyleClass("extension-script");
},

_clearCurrentExecutionLine: function()
{
if (this._executionSourceFrame)
this._executionSourceFrame.executionLine = 0;
delete this._executionSourceFrame;
},

_callFrameSelected: function()
{
this._clearCurrentExecutionLine();

var callStackPane = this.sidebarPanes.callstack;
var currentFrame = callStackPane.selectedCallFrame;
if (!currentFrame)
return;

this.sidebarPanes.scopechain.update(currentFrame);
this.sidebarPanes.watchExpressions.refreshExpressions();

var scriptOrResource = this._sourceIDMap[currentFrame.sourceID];
this._showScriptOrResource(scriptOrResource, {line: currentFrame.line});

this._executionSourceFrame = this._sourceFrameForScriptOrResource(scriptOrResource);
if (this._executionSourceFrame)
this._executionSourceFrame.executionLine = currentFrame.line;
},

_changeVisibleFile: function(event)
{
var select = this.filesSelectElement;
this._showScriptOrResource(select.options[select.selectedIndex].representedObject);
},

_startSidebarResizeDrag: function(event)
{
WebInspector.elementDragStart(this.sidebarElement, this._sidebarResizeDrag.bind(this), this._endSidebarResizeDrag.bind(this), event, "col-resize");

if (event.target === this.sidebarResizeWidgetElement)
this._dragOffset = (event.target.offsetWidth - (event.pageX - event.target.totalOffsetLeft));
else
this._dragOffset = 0;
},

_endSidebarResizeDrag: function(event)
{
WebInspector.elementDragEnd(event);
delete this._dragOffset;
this.saveSidebarWidth();
},

_sidebarResizeDrag: function(event)
{
var x = event.pageX + this._dragOffset;
var newWidth = Number.constrain(window.innerWidth - x, Preferences.minScriptsSidebarWidth, window.innerWidth * 0.66);
this.setSidebarWidth(newWidth);
event.preventDefault();
},

setSidebarWidth: function(newWidth)
{
this.sidebarElement.style.width = newWidth + "px";
this.sidebarButtonsElement.style.width = newWidth + "px";
this.viewsContainerElement.style.right = newWidth + "px";
this.sidebarResizeWidgetElement.style.right = newWidth + "px";
this.sidebarResizeElement.style.right = (newWidth - 3) + "px";

this.resize();
},

updatePauseOnExceptionsState: function(pauseOnExceptionsState)
{
if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions)
this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnAllExceptions)
this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions.");
else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions)
this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");

this._pauseOnExceptionButton.state = pauseOnExceptionsState;
},

_updateDebuggerButtons: function()
{
if (this._debuggerEnabled) {
this.enableToggleButton.title = WebInspector.UIString("Debugging enabled. Click to disable.");
this.enableToggleButton.toggled = true;
this._pauseOnExceptionButton.visible = true;
this.panelEnablerView.visible = false;
} else {
this.enableToggleButton.title = WebInspector.UIString("Debugging disabled. Click to enable.");
this.enableToggleButton.toggled = false;
this._pauseOnExceptionButton.visible = false;
this.panelEnablerView.visible = true;
}

if (this._paused) {
this.pauseButton.addStyleClass("paused");

this.pauseButton.disabled = false;
this.stepOverButton.disabled = false;
this.stepIntoButton.disabled = false;
this.stepOutButton.disabled = false;

this.debuggerStatusElement.textContent = WebInspector.UIString("Paused");
} else {
this.pauseButton.removeStyleClass("paused");

this.pauseButton.disabled = this._waitingToPause;
this.stepOverButton.disabled = true;
this.stepIntoButton.disabled = true;
this.stepOutButton.disabled = true;

if (this._waitingToPause)
this.debuggerStatusElement.textContent = WebInspector.UIString("Pausing");
else if (this._stepping)
this.debuggerStatusElement.textContent = WebInspector.UIString("Stepping");
else
this.debuggerStatusElement.textContent = "";
}
},

_updateBackAndForwardButtons: function()
{
this.backButton.disabled = this._currentBackForwardIndex <= 0;
this.forwardButton.disabled = this._currentBackForwardIndex >= (this._backForwardList.length - 1);
},

_clearInterface: function()
{
this.sidebarPanes.callstack.update(null);
this.sidebarPanes.scopechain.update(null);

this._clearCurrentExecutionLine();
this._updateDebuggerButtons();
},

_goBack: function()
{
if (this._currentBackForwardIndex <= 0) {
console.error("Can't go back from index " + this._currentBackForwardIndex);
return;
}

this._showScriptOrResource(this._backForwardList[--this._currentBackForwardIndex], {fromBackForwardAction: true});
this._updateBackAndForwardButtons();
},

_goForward: function()
{
if (this._currentBackForwardIndex >= this._backForwardList.length - 1) {
console.error("Can't go forward from index " + this._currentBackForwardIndex);
return;
}

this._showScriptOrResource(this._backForwardList[++this._currentBackForwardIndex], {fromBackForwardAction: true});
this._updateBackAndForwardButtons();
},

_enableDebugging: function()
{
if (this._debuggerEnabled)
return;
this._toggleDebugging(this.panelEnablerView.alwaysEnabled);
},

_toggleDebugging: function(optionalAlways)
{
this._paused = false;
this._waitingToPause = false;
this._stepping = false;

if (this._debuggerEnabled)
InspectorBackend.disableDebugger(true);
else
InspectorBackend.enableDebugger(!!optionalAlways);
},

_togglePauseOnExceptions: function()
{
InspectorBackend.setPauseOnExceptionsState((this._pauseOnExceptionButton.state + 1) % this._pauseOnExceptionButton.states, this.updatePauseOnExceptionsState.bind(this));
},

_togglePause: function()
{
if (this._paused) {
this._paused = false;
this._waitingToPause = false;
InspectorBackend.resume();
} else {
this._stepping = false;
this._waitingToPause = true;
InspectorBackend.pause();
}

this._clearInterface();
},

_stepOverClicked: function()
{
this._paused = false;
this._stepping = true;

this._clearInterface();

InspectorBackend.stepOverStatement();
},

_stepIntoClicked: function()
{
this._paused = false;
this._stepping = true;

this._clearInterface();

InspectorBackend.stepIntoStatement();
},

_stepOutClicked: function()
{
this._paused = false;
this._stepping = true;

this._clearInterface();

InspectorBackend.stepOutOfFunction();
},

toggleBreakpointsClicked: function()
{
this.toggleBreakpointsButton.toggled = !this.toggleBreakpointsButton.toggled;
if (this.toggleBreakpointsButton.toggled) {
InspectorBackend.activateBreakpoints();
this.toggleBreakpointsButton.title = WebInspector.UIString("Deactivate all breakpoints.");
document.getElementById("main-panels").removeStyleClass("breakpoints-deactivated");
} else {
InspectorBackend.deactivateBreakpoints();
this.toggleBreakpointsButton.title = WebInspector.UIString("Activate all breakpoints.");
document.getElementById("main-panels").addStyleClass("breakpoints-deactivated");
}
},

elementsToRestoreScrollPositionsFor: function()
{
return [ this.sidebarElement ];
},

_registerShortcuts: function()
{
var section = WebInspector.shortcutsHelp.section(WebInspector.UIString("Scripts Panel"));
var handler, shortcut1, shortcut2;
var platformSpecificModifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta;

this._shortcuts = {};


handler = this.pauseButton.click.bind(this.pauseButton);
shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F8);
this._shortcuts[shortcut1.key] = handler;
shortcut2 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Slash, platformSpecificModifier);
this._shortcuts[shortcut2.key] = handler;
section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Continue"));


handler = this.stepOverButton.click.bind(this.stepOverButton);
shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F10);
this._shortcuts[shortcut1.key] = handler;
shortcut2 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.SingleQuote, platformSpecificModifier);
this._shortcuts[shortcut2.key] = handler;
section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Step over"));


handler = this.stepIntoButton.click.bind(this.stepIntoButton);
shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11);
this._shortcuts[shortcut1.key] = handler;
shortcut2 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, platformSpecificModifier);
this._shortcuts[shortcut2.key] = handler;
section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Step into"));


handler = this.stepOutButton.click.bind(this.stepOutButton);
shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11, WebInspector.KeyboardShortcut.Modifiers.Shift);
this._shortcuts[shortcut1.key] = handler;
shortcut2 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, WebInspector.KeyboardShortcut.Modifiers.Shift, platformSpecificModifier);
this._shortcuts[shortcut2.key] = handler;
section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Step out"));

var isMac = WebInspector.isMac();
if (isMac)
shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Meta);
else
shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
this._shortcuts[shortcut1.key] = this.showGoToLineDialog.bind(this);
section.addAlternateKeys([ shortcut1.name ], WebInspector.UIString("Go to Line"));
this.sidebarPanes.callstack.registerShortcuts(section);
},

searchCanceled: function()
{
WebInspector.updateSearchMatchesCount(0, this);

if (this._searchView)
this._searchView.searchCanceled();

delete this._searchView;
delete this._searchQuery;
},

performSearch: function(query)
{
if (!this.visibleView)
return;


this.searchCanceled();

this._searchView = this.visibleView;
this._searchQuery = query;

function finishedCallback(view, searchMatches)
{
if (!searchMatches)
return;

WebInspector.updateSearchMatchesCount(searchMatches, this);
view.jumpToFirstSearchResult();
}

this._searchView.performSearch(query, finishedCallback.bind(this));
},

jumpToNextSearchResult: function()
{
if (!this._searchView)
return;

if (this._searchView !== this.visibleView) {
this.performSearch(this._searchQuery);
return;
}

if (this._searchView.showingLastSearchResult())
this._searchView.jumpToFirstSearchResult();
else
this._searchView.jumpToNextSearchResult();
},

jumpToPreviousSearchResult: function()
{
if (!this._searchView)
return;

if (this._searchView !== this.visibleView) {
this.performSearch(this._searchQuery);
if (this._searchView)
this._searchView.jumpToLastSearchResult();
return;
}

if (this._searchView.showingFirstSearchResult())
this._searchView.jumpToLastSearchResult();
else
this._searchView.jumpToPreviousSearchResult();
},

showGoToLineDialog: function(e)
{
var view = this.visibleView;
if (view)
WebInspector.GoToLineDialog.show(view);
}
}

WebInspector.ScriptsPanel.prototype.__proto__ = WebInspector.Panel.prototype;






WebInspector.ResourcesPanel = function(database)
{
WebInspector.Panel.call(this, "resources");

WebInspector.settings.installApplicationSetting("resourcesLastSelectedItem", {});

this.createSidebar();
this.sidebarElement.addStyleClass("outline-disclosure filter-all children small");
this.sidebarTreeElement.removeStyleClass("sidebar-tree");

this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "Frames", "frame-storage-tree-item");
this.sidebarTree.appendChild(this.resourcesListTreeElement);
this._treeElementForFrameId = {};

this.databasesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Databases"), "Databases", "database-storage-tree-item");
this.sidebarTree.appendChild(this.databasesListTreeElement);

this.localStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Local Storage"), "LocalStorage", "domstorage-storage-tree-item local-storage");
this.sidebarTree.appendChild(this.localStorageListTreeElement);

this.sessionStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Session Storage"), "SessionStorage", "domstorage-storage-tree-item session-storage");
this.sidebarTree.appendChild(this.sessionStorageListTreeElement);

this.cookieListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Cookies"), "Cookies", "cookie-storage-tree-item");
this.sidebarTree.appendChild(this.cookieListTreeElement);

this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "ApplicationCache", "application-cache-storage-tree-item");
this.sidebarTree.appendChild(this.applicationCacheListTreeElement);

if (Preferences.fileSystemEnabled) {
this.fileSystemListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("File System"), "FileSystem", "file-system-storage-tree-item");
this.sidebarTree.appendChild(this.fileSystemListTreeElement);
this.fileSystemListTreeElement.expand();
}

this.storageViews = document.createElement("div");
this.storageViews.id = "storage-views";
this.storageViews.className = "diff-container";
this.element.appendChild(this.storageViews);

this.storageViewStatusBarItemsContainer = document.createElement("div");
this.storageViewStatusBarItemsContainer.className = "status-bar-items";

this._databases = [];
this._domStorage = [];
this._cookieViews = {};
this._origins = {};
this._domains = {};

this.sidebarElement.addEventListener("mousemove", this._onmousemove.bind(this), false);
this.sidebarElement.addEventListener("mouseout", this._onmouseout.bind(this), false);
}

WebInspector.ResourcesPanel.prototype = {
get toolbarItemLabel()
{
return WebInspector.UIString("Resources");
},

get statusBarItems()
{
return [this.storageViewStatusBarItemsContainer];
},

elementsToRestoreScrollPositionsFor: function()
{
return [this.sidebarElement];
},

show: function()
{
WebInspector.Panel.prototype.show.call(this);

if (this.visibleView instanceof WebInspector.ResourceView)
this._showResourceView(this.visibleView.resource);

if (this._initializedDefaultSelection)
return;

this._initializedDefaultSelection = true;
var itemURL = WebInspector.settings.resourcesLastSelectedItem;
if (itemURL) {
for (var treeElement = this.sidebarTree.children[0]; treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.sidebarTree, true)) {
if (treeElement.itemURL === itemURL) {
treeElement.select();
treeElement.reveal();
return;
}
}
}
this._initDefaultSelection();
},

_initDefaultSelection: function()
{
if (WebInspector.mainResource && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded)
this.showResource(WebInspector.mainResource);
},

reset: function()
{
this._origins = {};
this._domains = {};
for (var i = 0; i < this._databases.length; ++i) {
var database = this._databases[i];
delete database._tableViews;
delete database._queryView;
}
this._databases = [];

var domStorageLength = this._domStorage.length;
for (var i = 0; i < this._domStorage.length; ++i) {
var domStorage = this._domStorage[i];
delete domStorage._domStorageView;
}
this._domStorage = [];

this._cookieViews = {};
this._fileSystemView = null;

this._applicationCacheView = null;
delete this._cachedApplicationCacheViewStatus;

this.databasesListTreeElement.removeChildren();
this.localStorageListTreeElement.removeChildren();
this.sessionStorageListTreeElement.removeChildren();
this.cookieListTreeElement.removeChildren();
this.applicationCacheListTreeElement.removeChildren();
if (Preferences.fileSystemEnabled)
this.fileSystemListTreeElement.removeChildren();
this.storageViews.removeChildren();

this.storageViewStatusBarItemsContainer.removeChildren();

if (this.sidebarTree.selectedTreeElement)
this.sidebarTree.selectedTreeElement.deselect();
},

addOrUpdateFrame: function(parentFrameId, frameId, title, subtitle)
{
var frameTreeElement = this._treeElementForFrameId[frameId];
if (frameTreeElement) {
frameTreeElement.setTitles(title, subtitle);
return;
}

var parentTreeElement = parentFrameId ? this._treeElementForFrameId[parentFrameId] : this.resourcesListTreeElement;
if (!parentTreeElement) {
console.warning("No frame with id:" + parentFrameId + " to route " + displayName + " to.")
return;
}

var frameTreeElement = new WebInspector.FrameTreeElement(this, frameId, title, subtitle);
this._treeElementForFrameId[frameId] = frameTreeElement;


var children = parentTreeElement.children;
for (var i = 0; i < children.length; ++i) {
var child = children[i];
if (!(child instanceof WebInspector.FrameTreeElement)) {
parentTreeElement.insertChild(frameTreeElement, i);
return;
}
if (child.displayName.localeCompare(frameTreeElement.displayName) > 0) {
parentTreeElement.insertChild(frameTreeElement, i);
return;
}
}
parentTreeElement.appendChild(frameTreeElement);
},

removeFrame: function(frameId)
{
var frameTreeElement = this._treeElementForFrameId[frameId];
if (!frameTreeElement)
return;
delete this._treeElementForFrameId[frameId];
if (frameTreeElement.parent)
frameTreeElement.parent.removeChild(frameTreeElement);
},

addResourceToFrame: function(frameId, resource)
{
this.addDocumentURL(resource.documentURL);

if (resource.statusCode >= 301 && resource.statusCode <= 303)
return;

var frameTreeElement = this._treeElementForFrameId[frameId];
if (!frameTreeElement) {


return;
}

var resourceTreeElement = new WebInspector.FrameResourceTreeElement(this, resource);


var children = frameTreeElement.children;
for (var i = 0; i < children.length; ++i) {
var child = children[i];
if (!(child instanceof WebInspector.FrameResourceTreeElement))
continue;

if (resource.type === WebInspector.Resource.Type.Document ||
(child._resource.type !== WebInspector.Resource.Type.Document && child._resource.displayName.localeCompare(resource.displayName) > 0)) {
frameTreeElement.insertChild(resourceTreeElement, i);
return;
}
}
frameTreeElement.appendChild(resourceTreeElement);
},

removeResourcesFromFrame: function(frameId)
{
var frameTreeElement = this._treeElementForFrameId[frameId];
if (frameTreeElement)
frameTreeElement.removeChildren();
},

refreshResource: function(resource)
{

if (resource.type === WebInspector.Resource.Type.XHR) {
var resourceTreeElement = this._findTreeElementForResource(resource);
if (resourceTreeElement)
resourceTreeElement.parent.removeChild(resourceTreeElement);
}
},

addDatabase: function(database)
{
this._databases.push(database);

var databaseTreeElement = new WebInspector.DatabaseTreeElement(this, database);
database._databasesTreeElement = databaseTreeElement;
this.databasesListTreeElement.appendChild(databaseTreeElement);
},

addDocumentURL: function(url)
{
var parsedURL = url.asParsedURL();
if (!parsedURL)
return;

var domain = parsedURL.host;
if (!this._domains[domain]) {
this._domains[domain] = true;

var cookieDomainTreeElement = new WebInspector.CookieTreeElement(this, domain);
this.cookieListTreeElement.appendChild(cookieDomainTreeElement);

var applicationCacheTreeElement = new WebInspector.ApplicationCacheTreeElement(this, domain);
this.applicationCacheListTreeElement.appendChild(applicationCacheTreeElement);
}

if (Preferences.fileSystemEnabled) {

var securityOrigin = parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "");
if (!this._origins[securityOrigin]) {
this._origins[securityOrigin] = true;
var fileSystemTreeElement = new WebInspector.FileSystemTreeElement(this, securityOrigin);
this.fileSystemListTreeElement.appendChild(fileSystemTreeElement);
}
}
},

addDOMStorage: function(domStorage)
{
this._domStorage.push(domStorage);
var domStorageTreeElement = new WebInspector.DOMStorageTreeElement(this, domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage"));
domStorage._domStorageTreeElement = domStorageTreeElement;
if (domStorage.isLocalStorage)
this.localStorageListTreeElement.appendChild(domStorageTreeElement);
else
this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
},

selectDatabase: function(databaseId)
{
var database;
for (var i = 0, len = this._databases.length; i < len; ++i) {
database = this._databases[i];
if (database.id === databaseId) {
this.showDatabase(database);
database._databasesTreeElement.select();
return;
}
}
},

selectDOMStorage: function(storageId)
{
var domStorage = this._domStorageForId(storageId);
if (domStorage) {
this.showDOMStorage(domStorage);
domStorage._domStorageTreeElement.select();
}
},

canShowSourceLine: function(url, line)
{
return !!WebInspector.resourceManager.resourceForURL(url);
},

showSourceLine: function(url, line)
{
var resource = WebInspector.resourceManager.resourceForURL(url);
if (resource.type === WebInspector.Resource.Type.XHR) {

if (WebInspector.panels.network && WebInspector.panels.network.canShowSourceLine(url, line)) {
WebInspector.currentPanel = WebInspector.panels.network;
WebInspector.panels.network.showSourceLine(url, line);
}
return;
}
this.showResource(WebInspector.resourceManager.resourceForURL(url), line);
},

showResource: function(resource, line)
{
var resourceTreeElement = this._findTreeElementForResource(resource);
if (resourceTreeElement) {
resourceTreeElement.reveal();
resourceTreeElement.select();
}

if (line) {
var view = WebInspector.ResourceManager.resourceViewForResource(resource);
if (view.revealLine)
view.revealLine(line);
if (view.highlightLine)
view.highlightLine(line);
}
return true;
},

_showResourceView: function(resource)
{
var view = WebInspector.ResourceManager.resourceViewForResource(resource);


if (resource.baseRevision && view instanceof WebInspector.SourceView) {
function callback(baseContent)
{
if (baseContent)
this._applyDiffMarkup(view, baseContent, resource.content);
}
resource.baseRevision.requestContent(callback.bind(this));
}
this._innerShowView(view);
},

_applyDiffMarkup: function(view, baseContent, newContent) {
var oldLines = baseContent.split("\n");
var newLines = newContent.split("\n");

var diff = Array.diff(oldLines, newLines);

var diffData = {};
diffData.added = [];
diffData.removed = [];
diffData.changed = [];

var offset = 0;
var right = diff.right;
for (var i = 0; i < right.length; ++i) {
if (typeof right[i] === "string") {
if (right.length > i + 1 && right[i + 1].row === i + 1 - offset)
diffData.changed.push(i);
else {
diffData.added.push(i);
offset++;
}
} else
offset = i - right[i].row;
}
view.sourceFrame.markDiff(diffData);
},

showDatabase: function(database, tableName)
{
if (!database)
return;

var view;
if (tableName) {
if (!("_tableViews" in database))
database._tableViews = {};
view = database._tableViews[tableName];
if (!view) {
view = new WebInspector.DatabaseTableView(database, tableName);
database._tableViews[tableName] = view;
}
} else {
view = database._queryView;
if (!view) {
view = new WebInspector.DatabaseQueryView(database);
database._queryView = view;
}
}

this._innerShowView(view);
},

showDOMStorage: function(domStorage)
{
if (!domStorage)
return;

var view;
view = domStorage._domStorageView;
if (!view) {
view = new WebInspector.DOMStorageItemsView(domStorage);
domStorage._domStorageView = view;
}

this._innerShowView(view);
},

showCookies: function(treeElement, cookieDomain)
{
var view = this._cookieViews[cookieDomain];
if (!view) {
view = new WebInspector.CookieItemsView(treeElement, cookieDomain);
this._cookieViews[cookieDomain] = view;
}

this._innerShowView(view);
},

showApplicationCache: function(treeElement, appcacheDomain)
{
var view = this._applicationCacheView;
if (!view) {
view = new WebInspector.ApplicationCacheItemsView(treeElement, appcacheDomain);
this._applicationCacheView = view;
}

this._innerShowView(view);

if ("_cachedApplicationCacheViewStatus" in this)
this._applicationCacheView.updateStatus(this._cachedApplicationCacheViewStatus);
},

showFileSystem: function(treeElement, origin)
{
this._fileSystemView = new WebInspector.FileSystemView(treeElement, origin);
this._innerShowView(this._fileSystemView);
},

showCategoryView: function(categoryName)
{
if (!this._categoryView)
this._categoryView = new WebInspector.StorageCategoryView();
this._categoryView.setText(categoryName);
this._innerShowView(this._categoryView);
},

_innerShowView: function(view)
{
if (this.visibleView)
this.visibleView.hide();

view.show(this.storageViews);
this.visibleView = view;

this.storageViewStatusBarItemsContainer.removeChildren();
var statusBarItems = view.statusBarItems || [];
for (var i = 0; i < statusBarItems.length; ++i)
this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
},

closeVisibleView: function()
{
if (this.visibleView)
this.visibleView.hide();
delete this.visibleView;
},

updateDatabaseTables: function(database)
{
if (!database || !database._databasesTreeElement)
return;

database._databasesTreeElement.shouldRefreshChildren = true;

if (!("_tableViews" in database))
return;

var tableNamesHash = {};
var self = this;
function tableNamesCallback(tableNames)
{
var tableNamesLength = tableNames.length;
for (var i = 0; i < tableNamesLength; ++i)
tableNamesHash[tableNames[i]] = true;

for (var tableName in database._tableViews) {
if (!(tableName in tableNamesHash)) {
if (self.visibleView === database._tableViews[tableName])
self.closeVisibleView();
delete database._tableViews[tableName];
}
}
}
database.getTableNames(tableNamesCallback);
},

dataGridForResult: function(columnNames, values)
{
var numColumns = columnNames.length;
if (!numColumns)
return null;

var columns = {};

for (var i = 0; i < columnNames.length; ++i) {
var column = {};
column.width = columnNames[i].length;
column.title = columnNames[i];
column.sortable = true;

columns[columnNames[i]] = column;
}

var nodes = [];
for (var i = 0; i < values.length / numColumns; ++i) {
var data = {};
for (var j = 0; j < columnNames.length; ++j)
data[columnNames[j]] = values[numColumns * i + j];

var node = new WebInspector.DataGridNode(data, false);
node.selectable = false;
nodes.push(node);
}

var dataGrid = new WebInspector.DataGrid(columns);
var length = nodes.length;
for (var i = 0; i < length; ++i)
dataGrid.appendChild(nodes[i]);

dataGrid.addEventListener("sorting changed", this._sortDataGrid.bind(this, dataGrid), this);
return dataGrid;
},

_sortDataGrid: function(dataGrid)
{
var nodes = dataGrid.children.slice();
var sortColumnIdentifier = dataGrid.sortColumnIdentifier;
var sortDirection = dataGrid.sortOrder === "ascending" ? 1 : -1;
var columnIsNumeric = true;

for (var i = 0; i < nodes.length; i++) {
if (isNaN(Number(nodes[i].data[sortColumnIdentifier])))
columnIsNumeric = false;
}

function comparator(dataGridNode1, dataGridNode2)
{
var item1 = dataGridNode1.data[sortColumnIdentifier];
var item2 = dataGridNode2.data[sortColumnIdentifier];

var comparison;
if (columnIsNumeric) {

var number1 = parseFloat(item1);
var number2 = parseFloat(item2);
comparison = number1 < number2 ? -1 : (number1 > number2 ? 1 : 0);
} else
comparison = item1 < item2 ? -1 : (item1 > item2 ? 1 : 0);

return sortDirection * comparison;
}

nodes.sort(comparator);
dataGrid.removeChildren();
for (var i = 0; i < nodes.length; i++)
dataGrid.appendChild(nodes[i]);
},

updateDOMStorage: function(storageId)
{
var domStorage = this._domStorageForId(storageId);
if (!domStorage)
return;

var view = domStorage._domStorageView;
if (this.visibleView && view === this.visibleView)
domStorage._domStorageView.update();
},

updateApplicationCacheStatus: function(status)
{
this._cachedApplicationCacheViewStatus = status;
if (this._applicationCacheView && this._applicationCacheView === this.visibleView)
this._applicationCacheView.updateStatus(status);
},

updateFileSystemPath: function(root, type, origin)
{
if (this._fileSystemView && this._fileSystemView === this.visibleView)
this._fileSystemView.updateFileSystemPath(root, type, origin);  
},

updateFileSystemError: function(type, origin)
{
if (this._fileSystemView && this._fileSystemView === this.visibleView)
this._fileSystemView.updateFileSystemError(type, origin);  
},

setFileSystemDisabled: function()
{
if (this._fileSystemView && this._fileSystemView === this.visibleView)
this._fileSystemView.setFileSystemDisabled();  
},

updateNetworkState: function(isNowOnline)
{
if (this._applicationCacheView && this._applicationCacheView === this.visibleView)
this._applicationCacheView.updateNetworkState(isNowOnline);
},

updateManifest: function(manifest)
{
if (this._applicationCacheView && this._applicationCacheView === this.visibleView)
this._applicationCacheView.updateManifest(manifest);
},

_domStorageForId: function(storageId)
{
if (!this._domStorage)
return null;
var domStorageLength = this._domStorage.length;
for (var i = 0; i < domStorageLength; ++i) {
var domStorage = this._domStorage[i];
if (domStorage.id == storageId)
return domStorage;
}
return null;
},

updateMainViewWidth: function(width)
{
this.storageViews.style.left = width + "px";
this.storageViewStatusBarItemsContainer.style.left = width + "px";
this.resize();
},

get searchableViews()
{
var views = [];

const visibleView = this.visibleView;
if (visibleView instanceof WebInspector.ResourceView && visibleView.performSearch)
views.push(visibleView);

function callback(resourceTreeElement)
{
var resource = resourceTreeElement._resource;
var resourceView = WebInspector.ResourceManager.resourceViewForResource(resource);
if (resourceView.performSearch && resourceView !== visibleView)
views.push(resourceView);
}
this._forAllResourceTreeElements(callback);
return views;
},

_forAllResourceTreeElements: function(callback)
{
var stop = false;
for (var treeElement = this.resourcesListTreeElement; !stop && treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.resourcesListTreeElement, true)) {
if (treeElement instanceof WebInspector.FrameResourceTreeElement)
stop = callback(treeElement);
}
},

searchMatchFound: function(view, matches)
{
if (!view.resource)
return;
var treeElement = this._findTreeElementForResource(view.resource);
if (treeElement)
treeElement.searchMatchFound(matches);
},

_findTreeElementForResource: function(resource)
{
function isAncestor(ancestor, object)
{

return false;
}

function getParent(object)
{

return null;
}

return this.sidebarTree.findTreeElement(resource, isAncestor, getParent);
},

searchCanceled: function(startingNewSearch)
{
WebInspector.Panel.prototype.searchCanceled.call(this, startingNewSearch);

if (startingNewSearch)
return;

function callback(resourceTreeElement)
{
resourceTreeElement._errorsWarningsUpdated();
}
this._forAllResourceTreeElements(callback);
},

performSearch: function(query)
{
function callback(resourceTreeElement)
{
resourceTreeElement._resetBubble();
}
this._forAllResourceTreeElements(callback);
WebInspector.Panel.prototype.performSearch.call(this, query);
},

showView: function(view)
{
if (view)
this.showResource(view.resource);
},

_onmousemove: function(event)
{
var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
if (!nodeUnderMouse)
return;

var listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName("li");
if (!listNode)
return;

var element = listNode.treeElement;
if (this._previousHoveredElement === element)
return;

if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}

if (element instanceof WebInspector.FrameTreeElement) {
this._previousHoveredElement = element;
element.hovered = true;
}
},

_onmouseout: function(event)
{
if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}
}
}

WebInspector.ResourcesPanel.prototype.__proto__ = WebInspector.Panel.prototype;

WebInspector.BaseStorageTreeElement = function(storagePanel, representedObject, title, iconClass, hasChildren)
{
TreeElement.call(this, "", representedObject, hasChildren);
this._storagePanel = storagePanel;
this._titleText = title;
this._iconClass = iconClass;
}

WebInspector.BaseStorageTreeElement.prototype = {
onattach: function()
{
this.listItemElement.removeChildren();
this.listItemElement.addStyleClass(this._iconClass);

var selectionElement = document.createElement("div");
selectionElement.className = "selection";
this.listItemElement.appendChild(selectionElement);

this.imageElement = document.createElement("img");
this.imageElement.className = "icon";
this.listItemElement.appendChild(this.imageElement);

this.titleElement = document.createElement("div");
this.titleElement.className = "base-storage-tree-element-title";
this.titleElement.textContent = this._titleText;
this.listItemElement.appendChild(this.titleElement);
},

onselect: function()
{
var itemURL = this.itemURL;
if (itemURL)
WebInspector.settings.resourcesLastSelectedItem = itemURL;
},

onreveal: function()
{
if (this.listItemElement)
this.listItemElement.scrollIntoViewIfNeeded(false);
},

get titleText()
{
return this._titleText;
},

set titleText(titleText)
{
this._titleText = titleText;
if (this.titleElement)
this.titleElement.textContent = this._titleText;
},

isEventWithinDisclosureTriangle: function()
{



const paddingLeft = 14;
var left = this.listItemElement.totalOffsetLeft + paddingLeft;
return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
}
}

WebInspector.BaseStorageTreeElement.prototype.__proto__ = TreeElement.prototype;

WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClass)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, categoryName, iconClass, true);
this._expandedSettingKey = "resources" + settingsKey + "Expanded";
WebInspector.settings.installApplicationSetting(this._expandedSettingKey, settingsKey === "Frames");
this._categoryName = categoryName;
}

WebInspector.StorageCategoryTreeElement.prototype = {
get itemURL()
{
return "category://" + this._categoryName;
},

onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
this._storagePanel.showCategoryView(this._categoryName);
},

onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
if (WebInspector.settings[this._expandedSettingKey])
this.expand();
},

onexpand: function()
{
WebInspector.settings[this._expandedSettingKey] = true;
},

oncollapse: function()
{
WebInspector.settings[this._expandedSettingKey] = false;
}
}
WebInspector.StorageCategoryTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;

WebInspector.FrameTreeElement = function(storagePanel, frameId, title, subtitle)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", "frame-storage-tree-item");
this._frameId = frameId;
this.setTitles(title, subtitle);
}

WebInspector.FrameTreeElement.prototype = {
get itemURL()
{
return "frame://" + encodeURI(this._displayName);
},

onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
if (this._titleToSetOnAttach || this._subtitleToSetOnAttach) {
this.setTitles(this._titleToSetOnAttach, this._subtitleToSetOnAttach);
delete this._titleToSetOnAttach;
delete this._subtitleToSetOnAttach;
}
},

onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
this._storagePanel.showCategoryView(this._displayName);

this.listItemElement.removeStyleClass("hovered");
InspectorBackend.hideFrameHighlight();
},

get displayName()
{
return this._displayName;
},

setTitles: function(title, subtitle)
{
this._displayName = "";
if (this.parent) {
if (title) {
this.titleElement.textContent = title;
this._displayName = title;
}
if (subtitle) {
var subtitleElement = document.createElement("span");
subtitleElement.className = "base-storage-tree-element-subtitle";
subtitleElement.textContent = "(" + subtitle + ")";
this._displayName += " (" + subtitle + ")";
this.titleElement.appendChild(subtitleElement);
}
} else {
this._titleToSetOnAttach = title;
this._subtitleToSetOnAttach = subtitle;
}
},

set hovered(hovered)
{
if (hovered) {
this.listItemElement.addStyleClass("hovered");
InspectorBackend.highlightFrame(this._frameId);
} else {
this.listItemElement.removeStyleClass("hovered");
InspectorBackend.hideFrameHighlight();
}
}
}
WebInspector.FrameTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;

WebInspector.FrameResourceTreeElement = function(storagePanel, resource)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, resource, resource.displayName, "resource-sidebar-tree-item resources-category-" + resource.category.name);
this._resource = resource;
this._resource.addEventListener("errors-warnings-updated", this._errorsWarningsUpdated, this);
this._resource.addEventListener("content-changed", this._contentChanged, this);
this.tooltip = resource.url;
}

WebInspector.FrameResourceTreeElement.prototype = {
get itemURL()
{
return this._resource.url;
},

onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
this._storagePanel._showResourceView(this._resource);
},

ondblclick: function(event)
{
InspectorBackend.openInInspectedWindow(this._resource.url);
},

onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);

if (this._resource.category === WebInspector.resourceCategories.images) {
var previewImage = document.createElement("img");
previewImage.className = "image-resource-icon-preview";
previewImage.src = this._resource.url;

var iconElement = document.createElement("div");
iconElement.className = "icon";
iconElement.appendChild(previewImage);
this.listItemElement.replaceChild(iconElement, this.imageElement);
}

this._statusElement = document.createElement("div");
this._statusElement.className = "status";
this.listItemElement.insertBefore(this._statusElement, this.titleElement);

this.listItemElement.draggable = true;
this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false);
},

_ondragstart: function(event)
{
event.dataTransfer.setData("text/plain", this._resource.content);
event.dataTransfer.effectAllowed = "copy";
return true;
},

_setBubbleText: function(x)
{
if (!this._bubbleElement) {
this._bubbleElement = document.createElement("div");
this._bubbleElement.className = "bubble";
this._statusElement.appendChild(this._bubbleElement);
}

this._bubbleElement.textContent = x;
},

_resetBubble: function()
{
if (this._bubbleElement) {
this._bubbleElement.textContent = "";
this._bubbleElement.removeStyleClass("search-matches");
this._bubbleElement.removeStyleClass("warning");
this._bubbleElement.removeStyleClass("error");
}
},

searchMatchFound: function(matches)
{
this._resetBubble();

this._setBubbleText(matches);
this._bubbleElement.addStyleClass("search-matches");


var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded)
currentAncestor.expand();
currentAncestor = currentAncestor.parent;
}
},

_errorsWarningsUpdated: function()
{

if (!this._resource.warnings && !this._resource.errors) {
var view = WebInspector.ResourceManager.existingResourceViewForResource(this._resource);
if (view && view.clearMessages)
view.clearMessages();
}

if (this._storagePanel.currentQuery)
return;

this._resetBubble();

if (this._resource.warnings || this._resource.errors)
this._setBubbleText(this._resource.warnings + this._resource.errors);

if (this._resource.warnings)
this._bubbleElement.addStyleClass("warning");

if (this._resource.errors)
this._bubbleElement.addStyleClass("error");
},

_contentChanged: function(event)
{
this.insertChild(new WebInspector.ResourceRevisionTreeElement(this._storagePanel, event.data.revision), 0);
var oldView = WebInspector.ResourceManager.existingResourceViewForResource(this._resource);
if (oldView) {
var newView = WebInspector.ResourceManager.recreateResourceView(this._resource);
if (oldView === this._storagePanel.visibleView)
this._storagePanel.visibleView = newView;
}
}
}

WebInspector.FrameResourceTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;

WebInspector.DatabaseTreeElement = function(storagePanel, database)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, database.name, "database-storage-tree-item", true);
this._database = database;
}

WebInspector.DatabaseTreeElement.prototype = {
get itemURL()
{
return "database://" + encodeURI(this._database.name);
},

onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
this._storagePanel.showDatabase(this._database);
},

oncollapse: function()
{


this.shouldRefreshChildren = true;
},

onpopulate: function()
{
this.removeChildren();

function tableNamesCallback(tableNames)
{
var tableNamesLength = tableNames.length;
for (var i = 0; i < tableNamesLength; ++i)
this.appendChild(new WebInspector.DatabaseTableTreeElement(this._storagePanel, this._database, tableNames[i]));
}
this._database.getTableNames(tableNamesCallback.bind(this));
}

}
WebInspector.DatabaseTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;

WebInspector.DatabaseTableTreeElement = function(storagePanel, database, tableName)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, tableName, "database-storage-tree-item");
this._database = database;
this._tableName = tableName;
}

WebInspector.DatabaseTableTreeElement.prototype = {
get itemURL()
{
return "database://" + encodeURI(this._database.name) + "/" + encodeURI(this._tableName);
},

onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
this._storagePanel.showDatabase(this._database, this._tableName);
}
}
WebInspector.DatabaseTableTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;

WebInspector.DOMStorageTreeElement = function(storagePanel, domStorage, className)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, domStorage.domain ? domStorage.domain : WebInspector.UIString("Local Files"), "domstorage-storage-tree-item " + className);
this._domStorage = domStorage;
}

WebInspector.DOMStorageTreeElement.prototype = {
get itemURL()
{
return "storage://" + this._domStorage.domain + "/" + (this._domStorage.isLocalStorage ? "local" : "session");
},

onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
this._storagePanel.showDOMStorage(this._domStorage);
}
}
WebInspector.DOMStorageTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;

WebInspector.CookieTreeElement = function(storagePanel, cookieDomain)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, cookieDomain ? cookieDomain : WebInspector.UIString("Local Files"), "cookie-storage-tree-item");
this._cookieDomain = cookieDomain;
}

WebInspector.CookieTreeElement.prototype = {
get itemURL()
{
return "cookies://" + this._cookieDomain;
},

onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
this._storagePanel.showCookies(this, this._cookieDomain);
}
}
WebInspector.CookieTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;

WebInspector.ApplicationCacheTreeElement = function(storagePanel, appcacheDomain)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, appcacheDomain ? appcacheDomain : WebInspector.UIString("Local Files"), "application-cache-storage-tree-item");
this._appcacheDomain = appcacheDomain;
}

WebInspector.ApplicationCacheTreeElement.prototype = {
get itemURL()
{
return "appcache://" + this._appcacheDomain;
},

onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
this._storagePanel.showApplicationCache(this, this._appcacheDomain);
}
}
WebInspector.ApplicationCacheTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;

WebInspector.ResourceRevisionTreeElement = function(storagePanel, revision)
{
var title = revision.timestamp ? revision.timestamp.toLocaleTimeString() : "(original)";
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, title, "resource-sidebar-tree-item resources-category-" + revision.category.name);
if (revision.timestamp)
this.tooltip = revision.timestamp.toLocaleString();
this._resource = revision;
}

WebInspector.ResourceRevisionTreeElement.prototype = {
onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
this.listItemElement.draggable = true;
this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false);
this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
},

onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
this._storagePanel._showResourceView(this._resource);
},

_ondragstart: function(event)
{
event.dataTransfer.setData("text/plain", this._resource.content);
event.dataTransfer.effectAllowed = "copy";
return true;
},

_handleContextMenuEvent: function(event)
{
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString("Revert to this revision"), this._resource.revertToThis.bind(this._resource));
contextMenu.show(event);
}
}

WebInspector.ResourceRevisionTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;

WebInspector.FileSystemTreeElement = function(storagePanel, origin)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, origin, "file-system-storage-tree-item");
this._origin = origin;
}

WebInspector.FileSystemTreeElement.prototype = {
get itemURL()
{
return "file-system://" + encodeURI(this._origin);
},

onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
this._storagePanel.showFileSystem(this, this._origin);
}
}

WebInspector.FileSystemTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;

WebInspector.StorageCategoryView = function()
{
WebInspector.View.call(this);

this.element.addStyleClass("storage-view");

this._emptyMsgElement = document.createElement("div");
this._emptyMsgElement.className = "storage-empty-view";
this.element.appendChild(this._emptyMsgElement);
}

WebInspector.StorageCategoryView.prototype = {
setText: function(text)
{
this._emptyMsgElement.textContent = text;
}
}

WebInspector.StorageCategoryView.prototype.__proto__ = WebInspector.View.prototype;





const UserInitiatedProfileName = "org.webkit.profiles.user-initiated";

WebInspector.ProfileType = function(id, name)
{
this._id = id;
this._name = name;
}

WebInspector.ProfileType.URLRegExp = /webkit-profile:\/\/(.+)\/(.+)#([0-9]+)/;

WebInspector.ProfileType.prototype = {
get buttonTooltip()
{
return "";
},

get buttonStyle()
{
return undefined;
},

get buttonCaption()
{
return this.name;
},

get id()
{
return this._id;
},

get name()
{
return this._name;
},

buttonClicked: function()
{
},

viewForProfile: function(profile)
{
if (!profile._profileView)
profile._profileView = this.createView(profile);
return profile._profileView;
},

get welcomeMessage()
{
return "";
},


createView: function(profile)
{
throw new Error("Needs implemented.");
},


createSidebarTreeElementForProfile: function(profile)
{
throw new Error("Needs implemented.");
}
}

WebInspector.ProfilesPanel = function()
{
WebInspector.Panel.call(this, "profiles");

this.createSidebar();

this._profileTypesByIdMap = {};
this._profileTypeButtonsByIdMap = {};

var panelEnablerHeading = WebInspector.UIString("You need to enable profiling before you can use the Profiles panel.");
var panelEnablerDisclaimer = WebInspector.UIString("Enabling profiling will make scripts run slower.");
var panelEnablerButton = WebInspector.UIString("Enable Profiling");
this.panelEnablerView = new WebInspector.PanelEnablerView("profiles", panelEnablerHeading, panelEnablerDisclaimer, panelEnablerButton);
this.panelEnablerView.addEventListener("enable clicked", this._enableProfiling, this);

this.element.appendChild(this.panelEnablerView.element);

this.profileViews = document.createElement("div");
this.profileViews.id = "profile-views";
this.element.appendChild(this.profileViews);

this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggle-status-bar-item");
this.enableToggleButton.addEventListener("click", this._toggleProfiling.bind(this), false);

this.clearResultsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear CPU profiles."), "clear-status-bar-item");
this.clearResultsButton.addEventListener("click", this._clearProfiles.bind(this), false);

this.profileViewStatusBarItemsContainer = document.createElement("div");
this.profileViewStatusBarItemsContainer.className = "status-bar-items";

this.welcomeView = new WebInspector.WelcomeView("profiles", WebInspector.UIString("Welcome to the Profiles panel"));
this.element.appendChild(this.welcomeView.element);

this._profiles = [];
this._profilerEnabled = Preferences.profilerAlwaysEnabled;
this._reset();
}

WebInspector.ProfilesPanel.prototype = {
get toolbarItemLabel()
{
return WebInspector.UIString("Profiles");
},

get statusBarItems()
{
function clickHandler(profileType, buttonElement)
{
profileType.buttonClicked.call(profileType);
this.updateProfileTypeButtons();
}

var items = [this.enableToggleButton.element];

for (var typeId in this._profileTypesByIdMap) {
var profileType = this.getProfileType(typeId);
if (profileType.buttonStyle) {
var button = new WebInspector.StatusBarButton(profileType.buttonTooltip, profileType.buttonStyle, profileType.buttonCaption);
this._profileTypeButtonsByIdMap[typeId] = button.element;
button.element.addEventListener("click", clickHandler.bind(this, profileType, button.element), false);
items.push(button.element);
}
}
items.push(this.clearResultsButton.element, this.profileViewStatusBarItemsContainer);
return items;
},

show: function()
{
WebInspector.Panel.prototype.show.call(this);
this._populateProfiles();
},

profilerWasEnabled: function()
{
if (this._profilerEnabled)
return;

this._profilerEnabled = true;

this._reset();
if (this.visible)
this._populateProfiles();
},

profilerWasDisabled: function()
{
if (!this._profilerEnabled)
return;

this._profilerEnabled = false;
this._reset();
},

resetProfiles: function()
{
this._reset();
},

_reset: function()
{
for (var i = 0; i < this._profiles.length; ++i)
delete this._profiles[i]._profileView;
delete this.visibleView;

delete this.currentQuery;
this.searchCanceled();

this._profiles = [];
this._profilesIdMap = {};
this._profileGroups = {};
this._profileGroupsForLinks = {}
this._profilesWereRequested = false;

this.sidebarTreeElement.removeStyleClass("some-expandable");

for (var typeId in this._profileTypesByIdMap)
this.getProfileType(typeId).treeElement.removeChildren();

this.profileViews.removeChildren();

this.profileViewStatusBarItemsContainer.removeChildren();

this._updateInterface();
this.welcomeView.show();
},

_clearProfiles: function()
{
InspectorBackend.clearProfiles();
this._reset();
},

registerProfileType: function(profileType)
{
this._profileTypesByIdMap[profileType.id] = profileType;
profileType.treeElement = new WebInspector.SidebarSectionTreeElement(profileType.name, null, true);
this.sidebarTree.appendChild(profileType.treeElement);
profileType.treeElement.expand();
this._addWelcomeMessage(profileType);
},

_addWelcomeMessage: function(profileType)
{
var message = profileType.welcomeMessage;



var buttonPos = message.indexOf("%s");
if (buttonPos > -1) {
var container = document.createDocumentFragment();
var part1 = document.createElement("span");
part1.innerHTML = message.substr(0, buttonPos);
container.appendChild(part1);

var button = new WebInspector.StatusBarButton(profileType.buttonTooltip, profileType.buttonStyle, profileType.buttonCaption);
container.appendChild(button.element);

var part2 = document.createElement("span");
part2.innerHTML = message.substr(buttonPos + 2);
container.appendChild(part2);
this.welcomeView.addMessage(container);
} else
this.welcomeView.addMessage(message);
},

_makeKey: function(text, profileTypeId)
{
return escape(text) + '/' + escape(profileTypeId);
},

addProfileHeader: function(profile)
{
var typeId = profile.typeId;
var profileType = this.getProfileType(typeId);
var sidebarParent = profileType.treeElement;
var small = false;
var alternateTitle;

profile.__profilesPanelProfileType = profileType;
this._profiles.push(profile);
this._profilesIdMap[this._makeKey(profile.uid, typeId)] = profile;

if (profile.title.indexOf(UserInitiatedProfileName) !== 0) {
var profileTitleKey = this._makeKey(profile.title, typeId);
if (!(profileTitleKey in this._profileGroups))
this._profileGroups[profileTitleKey] = [];

var group = this._profileGroups[profileTitleKey];
group.push(profile);

if (group.length === 2) {

group._profilesTreeElement = new WebInspector.ProfileGroupSidebarTreeElement(profile.title);


var index = sidebarParent.children.indexOf(group[0]._profilesTreeElement);
sidebarParent.insertChild(group._profilesTreeElement, index);


var selected = group[0]._profilesTreeElement.selected;
sidebarParent.removeChild(group[0]._profilesTreeElement);
group._profilesTreeElement.appendChild(group[0]._profilesTreeElement);
if (selected) {
group[0]._profilesTreeElement.select();
group[0]._profilesTreeElement.reveal();
}

group[0]._profilesTreeElement.small = true;
group[0]._profilesTreeElement.mainTitle = WebInspector.UIString("Run %d", 1);

this.sidebarTreeElement.addStyleClass("some-expandable");
}

if (group.length >= 2) {
sidebarParent = group._profilesTreeElement;
alternateTitle = WebInspector.UIString("Run %d", group.length);
small = true;
}
}

var profileTreeElement = profileType.createSidebarTreeElementForProfile(profile);
profileTreeElement.small = small;
if (alternateTitle)
profileTreeElement.mainTitle = alternateTitle;
profile._profilesTreeElement = profileTreeElement;

sidebarParent.appendChild(profileTreeElement);
if (!profile.isTemporary) {
this.welcomeView.hide();
if (!this.visibleView)
this.showProfile(profile);
this.dispatchEventToListeners("profile added");
}
},

removeProfileHeader: function(profile)
{
var typeId = profile.typeId;
var profileType = this.getProfileType(typeId);
var sidebarParent = profileType.treeElement;

for (var i = 0; i < this._profiles.length; ++i) {
if (this._profiles[i].uid === profile.uid) {
profile = this._profiles[i];
this._profiles.splice(i, 1);
break;
}
}
delete this._profilesIdMap[this._makeKey(profile.uid, typeId)];

var profileTitleKey = this._makeKey(profile.title, typeId);
delete this._profileGroups[profileTitleKey];

sidebarParent.removeChild(profile._profilesTreeElement);

if (!profile.isTemporary)
InspectorBackend.removeProfile(profile.typeId, profile.uid);



if (!this._profiles.length)
this.closeVisibleView();
},

showProfile: function(profile)
{
if (!profile || profile.isTemporary)
return;

this.closeVisibleView();

var view = profile.__profilesPanelProfileType.viewForProfile(profile);

view.show(this.profileViews);

profile._profilesTreeElement.select(true);
profile._profilesTreeElement.reveal();

this.visibleView = view;

this.profileViewStatusBarItemsContainer.removeChildren();

var statusBarItems = view.statusBarItems;
for (var i = 0; i < statusBarItems.length; ++i)
this.profileViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
},

getProfiles: function(typeId)
{
var result = [];
var profilesCount = this._profiles.length;
for (var i = 0; i < profilesCount; ++i)
if (this._profiles[i].typeId === typeId)
result.push(this._profiles[i]);
return result;
},

hasTemporaryProfile: function(typeId)
{
var profilesCount = this._profiles.length;
for (var i = 0; i < profilesCount; ++i)
if (this._profiles[i].typeId === typeId && this._profiles[i].isTemporary)
return true;
return false;
},

hasProfile: function(profile)
{
return !!this._profilesIdMap[this._makeKey(profile.uid, profile.typeId)];
},

updateProfile: function(profile)
{
var profilesCount = this._profiles.length;
for (var i = 0; i < profilesCount; ++i)
if (this._profiles[i].typeId === profile.typeId
&& this._profiles[i].uid === profile.uid) {
this._profiles[i] = profile;
break;
}
},

showView: function(view)
{
this.showProfile(view.profile);
},

getProfileType: function(typeId)
{
return this._profileTypesByIdMap[typeId];
},

showProfileForURL: function(url)
{
var match = url.match(WebInspector.ProfileType.URLRegExp);
if (!match)
return;
this.showProfile(this._profilesIdMap[this._makeKey(match[3], match[1])]);
},

updateProfileTypeButtons: function()
{
for (var typeId in this._profileTypeButtonsByIdMap) {
var buttonElement = this._profileTypeButtonsByIdMap[typeId];
var profileType = this.getProfileType(typeId);
buttonElement.className = profileType.buttonStyle;
buttonElement.title = profileType.buttonTooltip;

}
},

closeVisibleView: function()
{
if (this.visibleView)
this.visibleView.hide();
delete this.visibleView;
},

displayTitleForProfileLink: function(title, typeId)
{
title = unescape(title);
if (title.indexOf(UserInitiatedProfileName) === 0) {
title = WebInspector.UIString("Profile %d", title.substring(UserInitiatedProfileName.length + 1));
} else {
var titleKey = this._makeKey(title, typeId);
if (!(titleKey in this._profileGroupsForLinks))
this._profileGroupsForLinks[titleKey] = 0;

var groupNumber = ++this._profileGroupsForLinks[titleKey];

if (groupNumber > 2)


title += " " + WebInspector.UIString("Run %d", (groupNumber + 1) / 2);
}

return title;
},

get searchableViews()
{
var views = [];

const visibleView = this.visibleView;
if (visibleView && visibleView.performSearch)
views.push(visibleView);

var profilesLength = this._profiles.length;
for (var i = 0; i < profilesLength; ++i) {
var profile = this._profiles[i];
var view = profile.__profilesPanelProfileType.viewForProfile(profile);
if (!view.performSearch || view === visibleView)
continue;
views.push(view);
}

return views;
},

searchMatchFound: function(view, matches)
{
view.profile._profilesTreeElement.searchMatches = matches;
},

searchCanceled: function(startingNewSearch)
{
WebInspector.Panel.prototype.searchCanceled.call(this, startingNewSearch);

if (!this._profiles)
return;

for (var i = 0; i < this._profiles.length; ++i) {
var profile = this._profiles[i];
profile._profilesTreeElement.searchMatches = 0;
}
},

_updateInterface: function()
{

if (this._profilerEnabled) {
this.enableToggleButton.title = WebInspector.UIString("Profiling enabled. Click to disable.");
this.enableToggleButton.toggled = true;
for (var typeId in this._profileTypeButtonsByIdMap)
this._profileTypeButtonsByIdMap[typeId].removeStyleClass("hidden");
this.profileViewStatusBarItemsContainer.removeStyleClass("hidden");
this.clearResultsButton.element.removeStyleClass("hidden");
this.panelEnablerView.visible = false;
} else {
this.enableToggleButton.title = WebInspector.UIString("Profiling disabled. Click to enable.");
this.enableToggleButton.toggled = false;
for (var typeId in this._profileTypeButtonsByIdMap)
this._profileTypeButtonsByIdMap[typeId].addStyleClass("hidden");
this.profileViewStatusBarItemsContainer.addStyleClass("hidden");
this.clearResultsButton.element.addStyleClass("hidden");
this.panelEnablerView.visible = true;
}
},

_enableProfiling: function()
{
if (this._profilerEnabled)
return;
this._toggleProfiling(this.panelEnablerView.alwaysEnabled);
},

_toggleProfiling: function(optionalAlways)
{
if (this._profilerEnabled)
InspectorBackend.disableProfiler(true);
else
InspectorBackend.enableProfiler(!!optionalAlways);
},

_populateProfiles: function()
{
if (!this._profilerEnabled || this._profilesWereRequested)
return;

function populateCallback(profileHeaders) {
profileHeaders.sort(function(a, b) { return a.uid - b.uid; });
var profileHeadersLength = profileHeaders.length;
for (var i = 0; i < profileHeadersLength; ++i)
if (!this.hasProfile(profileHeaders[i]))
WebInspector.addProfileHeader(profileHeaders[i]);
}

InspectorBackend.getProfileHeaders(populateCallback.bind(this));

this._profilesWereRequested = true;
},

updateMainViewWidth: function(width)
{
this.welcomeView.element.style.left = width + "px";
this.profileViews.style.left = width + "px";
this.profileViewStatusBarItemsContainer.style.left = Math.max(155, width) + "px";
this.resize();
}
}

WebInspector.ProfilesPanel.prototype.__proto__ = WebInspector.Panel.prototype;

WebInspector.ProfileSidebarTreeElement = function(profile, titleFormat, className)
{
this.profile = profile;
this._titleFormat = titleFormat;

if (this.profile.title.indexOf(UserInitiatedProfileName) === 0)
this._profileNumber = this.profile.title.substring(UserInitiatedProfileName.length + 1);

WebInspector.SidebarTreeElement.call(this, className, "", "", profile, false);

this.refreshTitles();
}

WebInspector.ProfileSidebarTreeElement.prototype = {
onselect: function()
{
this.treeOutline.panel.showProfile(this.profile);
},

ondelete: function()
{
this.treeOutline.panel.removeProfileHeader(this.profile);
return true;
},

get mainTitle()
{
if (this._mainTitle)
return this._mainTitle;
if (this.profile.title.indexOf(UserInitiatedProfileName) === 0)
return WebInspector.UIString(this._titleFormat, this._profileNumber);
return this.profile.title;
},

set mainTitle(x)
{
this._mainTitle = x;
this.refreshTitles();
},

get subtitle()
{

},

set subtitle(x)
{

},

set searchMatches(matches)
{
if (!matches) {
if (!this.bubbleElement)
return;
this.bubbleElement.removeStyleClass("search-matches");
this.bubbleText = "";
return;
}

this.bubbleText = matches;
this.bubbleElement.addStyleClass("search-matches");
}
}

WebInspector.ProfileSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;

WebInspector.ProfileGroupSidebarTreeElement = function(title, subtitle)
{
WebInspector.SidebarTreeElement.call(this, "profile-group-sidebar-tree-item", title, subtitle, null, true);
}

WebInspector.ProfileGroupSidebarTreeElement.prototype = {
onselect: function()
{
if (this.children.length > 0)
WebInspector.panels.profiles.showProfile(this.children[this.children.length - 1].profile);
}
}

WebInspector.ProfileGroupSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;






WebInspector.ConsolePanel = function()
{
WebInspector.Panel.call(this, "console");
}

WebInspector.ConsolePanel.prototype = {
get toolbarItemLabel()
{
return WebInspector.UIString("Console");
},

show: function()
{
WebInspector.Panel.prototype.show.call(this);

this._previousConsoleState = WebInspector.drawer.state;
WebInspector.drawer.enterPanelMode();
WebInspector.showConsole();


var scopeBar = document.getElementById("console-filter");
var consoleMessages = document.getElementById("console-messages");

scopeBar.parentNode.removeChild(scopeBar);
document.getElementById("console-view").insertBefore(scopeBar, consoleMessages);


scopeBar.addStyleClass("console-filter-top");
scopeBar.removeStyleClass("status-bar-item");

consoleMessages.addStyleClass("console-filter-top");
},

hide: function()
{
WebInspector.Panel.prototype.hide.call(this);

if (this._previousConsoleState === WebInspector.Drawer.State.Hidden)
WebInspector.drawer.immediatelyExitPanelMode();
else
WebInspector.drawer.exitPanelMode();
delete this._previousConsoleState;


var scopeBar = document.getElementById("console-filter");

scopeBar.parentNode.removeChild(scopeBar);
document.getElementById("other-drawer-status-bar-items").appendChild(scopeBar);


scopeBar.removeStyleClass("console-filter-top");
scopeBar.addStyleClass("status-bar-item");

document.getElementById("console-messages").removeStyleClass("console-filter-top");
}
}

WebInspector.ConsolePanel.prototype.__proto__ = WebInspector.Panel.prototype;





WebInspector.injectedExtensionAPI = function(InjectedScriptHost, inspectedWindow, injectedScriptId)
{







function EventSinkImpl(type, customDispatch)
{
this._type = type;
this._listeners = [];
this._customDispatch = customDispatch;
}

EventSinkImpl.prototype = {
addListener: function(callback)
{
if (typeof callback != "function")
throw new "addListener: callback is not a function";
if (this._listeners.length === 0)
extensionServer.sendRequest({ command: "subscribe", type: this._type });
this._listeners.push(callback);
extensionServer.registerHandler("notify-" + this._type, bind(this._dispatch, this));
},

removeListener: function(callback)
{
var listeners = this._listeners;

for (var i = 0; i < listeners.length; ++i) {
if (listeners[i] === callback) {
listeners.splice(i, 1);
break;
}
}
if (this._listeners.length === 0)
extensionServer.sendRequest({ command: "unsubscribe", type: this._type });
},

_fire: function()
{
var listeners = this._listeners.slice();
for (var i = 0; i < listeners.length; ++i)
listeners[i].apply(null, arguments);
},

_dispatch: function(request)
{
if (this._customDispatch)
this._customDispatch.call(this, request);
else
this._fire.apply(this, request.arguments);
}
}

function InspectorExtensionAPI()
{
this.audits = new Audits();
this.inspectedWindow = new InspectedWindow();
this.panels = new Panels();
this.resources = new Resources();

this.onReset = new EventSink("reset");
}

InspectorExtensionAPI.prototype = {
log: function(message)
{
extensionServer.sendRequest({ command: "log", message: message });
}
}

function Resources()
{
function resourceDispatch(request)
{
var resource = request.arguments[1];
resource.__proto__ = new Resource(request.arguments[0]);
this._fire(resource);
}
this.onFinished = new EventSink("resource-finished", resourceDispatch);
}

Resources.prototype = {
getHAR: function(callback)
{
function callbackWrapper(result)
{
var entries = (result && result.entries) || [];
for (var i = 0; i < entries.length; ++i) {
entries[i].__proto__ = new Resource(entries[i]._resourceId);
delete entries[i]._resourceId;
}
callback(result);
}
return extensionServer.sendRequest({ command: "getHAR" }, callback && callbackWrapper);
}
}

function ResourceImpl(id)
{
this._id = id;
}

ResourceImpl.prototype = {
getContent: function(callback)
{
function callbackWrapper(response)
{
callback(response.content, response.encoding);
}
extensionServer.sendRequest({ command: "getResourceContent", id: this._id }, callback && callbackWrapper);
}
};

function Panels()
{
var panels = {
elements: new ElementsPanel()
};

function panelGetter(name)
{
return panels[name];
}
for (var panel in panels)
this.__defineGetter__(panel, bind(panelGetter, null, panel));
}

Panels.prototype = {
create: function(title, iconURL, pageURL, callback)
{
var id = "extension-panel-" + extensionServer.nextObjectId();
var request = {
command: "createPanel",
id: id,
title: title,
icon: expandURL(iconURL),
url: expandURL(pageURL)
};
extensionServer.sendRequest(request, callback && bind(callback, this, new ExtensionPanel(id)));
}
}

function PanelImpl(id)
{
this._id = id;
}

function PanelWithSidebarImpl(id)
{
PanelImpl.call(this, id);
}

PanelWithSidebarImpl.prototype = {
createSidebarPane: function(title, url, callback)
{
var id = "extension-sidebar-" + extensionServer.nextObjectId();
var request = {
command: "createSidebarPane",
panel: this._id,
id: id,
title: title,
url: expandURL(url)
};
function callbackWrapper()
{
callback(new ExtensionSidebarPane(id));
}
extensionServer.sendRequest(request, callback && callbackWrapper);
},

createWatchExpressionSidebarPane: function(title, callback)
{
var id = "watch-sidebar-" + extensionServer.nextObjectId();
var request = {
command: "createWatchExpressionSidebarPane",
panel: this._id,
id: id,
title: title
};
function callbackWrapper()
{
callback(new WatchExpressionSidebarPane(id));
}
extensionServer.sendRequest(request, callback && callbackWrapper);
}
}

PanelWithSidebarImpl.prototype.__proto__ = PanelImpl.prototype;

function ElementsPanel()
{
var id = "elements";
PanelWithSidebar.call(this, id);
this.onSelectionChanged = new EventSink("panel-objectSelected-" + id);
}

function ExtensionPanel(id)
{
Panel.call(this, id);
this.onSearch = new EventSink("panel-search-" + id);
}

function ExtensionSidebarPaneImpl(id)
{
this._id = id;
}

ExtensionSidebarPaneImpl.prototype = {
setHeight: function(height)
{
extensionServer.sendRequest({ command: "setSidebarHeight", id: this._id, height: height });
}
}

function WatchExpressionSidebarPaneImpl(id)
{
ExtensionSidebarPaneImpl.call(this, id);
this.onUpdated = new EventSink("watch-sidebar-updated-" + id);
}

WatchExpressionSidebarPaneImpl.prototype = {
setExpression: function(expression, rootTitle)
{
extensionServer.sendRequest({ command: "setWatchSidebarContent", id: this._id, expression: expression, rootTitle: rootTitle, evaluateOnPage: true });
},

setObject: function(jsonObject, rootTitle)
{
extensionServer.sendRequest({ command: "setWatchSidebarContent", id: this._id, expression: jsonObject, rootTitle: rootTitle });
}
}

WatchExpressionSidebarPaneImpl.prototype.__proto__ = ExtensionSidebarPaneImpl.prototype;

function WatchExpressionSidebarPane(id)
{
var impl = new WatchExpressionSidebarPaneImpl(id);
ExtensionSidebarPane.call(this, id, impl);
}

function Audits()
{
}

Audits.prototype = {
addCategory: function(displayName, resultCount)
{
var id = "extension-audit-category-" + extensionServer.nextObjectId();
extensionServer.sendRequest({ command: "addAuditCategory", id: id, displayName: displayName, resultCount: resultCount });
return new AuditCategory(id);
}
}

function AuditCategoryImpl(id)
{
function auditResultDispatch(request)
{
var auditResult = new AuditResult(request.arguments[0]);
try {
this._fire(auditResult);
} catch (e) {
console.error("Uncaught exception in extension audit event handler: " + e);
auditResult.done();
}
}
this._id = id;
this.onAuditStarted = new EventSink("audit-started-" + id, auditResultDispatch);
}

function AuditResultImpl(id)
{
this._id = id;

var formatterTypes = [
"url",
"snippet",
"text"
];
for (var i = 0; i < formatterTypes.length; ++i)
this[formatterTypes[i]] = bind(this._nodeFactory, null, formatterTypes[i]);
}

AuditResultImpl.prototype = {
addResult: function(displayName, description, severity, details)
{

if (details && !(details instanceof AuditResultNode))
details = details instanceof Array ? this.createNode.apply(this, details) : this.createNode(details);

var request = {
command: "addAuditResult",
resultId: this._id,
displayName: displayName,
description: description,
severity: severity,
details: details
};
extensionServer.sendRequest(request);
},

createResult: function()
{
var node = new AuditResultNode();
node.contents = Array.prototype.slice.call(arguments);
return node;
},

done: function()
{
extensionServer.sendRequest({ command: "stopAuditCategoryRun", resultId: this._id });
},

get Severity()
{
return apiPrivate.audits.Severity;
},

_nodeFactory: function(type)
{
return {
type: type,
arguments: Array.prototype.slice.call(arguments, 1)
};
}
}

function AuditResultNode(contents)
{
this.contents = contents;
this.children = [];
this.expanded = false;
}

AuditResultNode.prototype = {
addChild: function()
{
var node = AuditResultImpl.prototype.createResult.apply(null, arguments);
this.children.push(node);
return node;
}
};

function InspectedWindow()
{
this.onDOMContentLoaded = new EventSink("inspectedPageDOMContentLoaded");
this.onLoaded = new EventSink("inspectedPageLoaded");
this.onNavigated = new EventSink("inspectedURLChanged");
}

InspectedWindow.prototype = {
reload: function()
{
return extensionServer.sendRequest({ command: "reload" });
},

eval: function(expression, callback)
{
function callbackWrapper(result)
{
var value = result.value;
if (!result.isException)
value = value === "undefined" ? undefined : JSON.parse(value);
callback(value, result.isException);
}
return extensionServer.sendRequest({ command: "evaluateOnInspectedPage", expression: expression }, callback && callbackWrapper);
}
}

function ExtensionServerClient()
{
this._callbacks = {};
this._handlers = {};
this._lastRequestId = 0;
this._lastObjectId = 0;

this.registerHandler("callback", bind(this._onCallback, this));

var channel = new MessageChannel();
this._port = channel.port1;
this._port.addEventListener("message", bind(this._onMessage, this), false);
this._port.start();

top.postMessage("registerExtension", [ channel.port2 ], "*");
}

ExtensionServerClient.prototype = {
sendRequest: function(message, callback)
{
if (typeof callback === "function")
message.requestId = this._registerCallback(callback);
return this._port.postMessage(message);
},

registerHandler: function(command, handler)
{
this._handlers[command] = handler;
},

nextObjectId: function()
{
return injectedScriptId + "_" + ++this._lastObjectId;
},

_registerCallback: function(callback)
{
var id = ++this._lastRequestId;
this._callbacks[id] = callback;
return id;
},

_onCallback: function(request)
{
if (request.requestId in this._callbacks) {
this._callbacks[request.requestId](request.result);
delete this._callbacks[request.requestId];
}
},

_onMessage: function(event)
{
var request = event.data;
var handler = this._handlers[request.command];
if (handler)
handler.call(this, request);
}
}

function expandURL(url)
{
if (!url)
return url;
if (/^[^/]+:/.exec(url)) // See if url has schema.
return url;
var baseURL = location.protocol + "//" + location.hostname + location.port;
if (/^\//.exec(url))
return baseURL + url;
return baseURL + location.pathname.replace(/\/[^/]*$/,"/") + url;
}

function bind(func, thisObject)
{
var args = Array.prototype.slice.call(arguments, 2);
return function() { return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0))); };
}

function populateInterfaceClass(interface, implementation)
{
for (var member in implementation) {
if (member.charAt(0) === "_")
continue;
var value = implementation[member];
interface[member] = typeof value === "function" ? bind(value, implementation)
: interface[member] = implementation[member];
}
}

function declareInterfaceClass(implConstructor)
{
return function()
{
var impl = { __proto__: implConstructor.prototype };
implConstructor.apply(impl, arguments);
populateInterfaceClass(this, impl);
}
}

var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
var AuditResult = declareInterfaceClass(AuditResultImpl);
var EventSink = declareInterfaceClass(EventSinkImpl);
var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
var Panel = declareInterfaceClass(PanelImpl);
var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
var Resource = declareInterfaceClass(ResourceImpl);
var WatchExpressionSidebarPane = declareInterfaceClass(WatchExpressionSidebarPaneImpl);

var extensionServer = new ExtensionServerClient();

webInspector = new InspectorExtensionAPI();

}





WebInspector.ExtensionAuditCategory = function(id, displayName, ruleCount)
{
this._id = id;
this._displayName = displayName;
this._ruleCount  = ruleCount;
}

WebInspector.ExtensionAuditCategory.prototype = {

get id()
{
return this._id;
},

get displayName()
{
return this._displayName;
},

get ruleCount()
{
return this._ruleCount;
},

run: function(resources, callback)
{
new WebInspector.ExtensionAuditCategoryResults(this, callback);
}
}

WebInspector.ExtensionAuditCategoryResults = function(category, callback)
{
this._category = category;
this._pendingRules = category.ruleCount;
this._ruleCompletionCallback = callback;

this.id = category.id + "-" + ++WebInspector.ExtensionAuditCategoryResults._lastId;
WebInspector.extensionServer.startAuditRun(category, this);
}

WebInspector.ExtensionAuditCategoryResults.prototype = {
get complete()
{
return !this._pendingRules;
},

cancel: function()
{
while (!this.complete)
this._addResult(null);
},

addResult: function(displayName, description, severity, details)
{
var result = new WebInspector.AuditRuleResult(displayName);
result.addChild(description);
result.severity = severity;
if (details)
this._addNode(result, details);
this._addResult(result);
},

_addNode: function(parent, node)
{
var addedNode = parent.addChild(node.contents, node.expanded);
if (node.children) {
for (var i = 0; i < node.children.length; ++i)
this._addNode(addedNode, node.children[i]);
}
},

_addResult: function(result)
{
this._ruleCompletionCallback(result);
this._pendingRules--;
if (!this._pendingRules)
WebInspector.extensionServer.stopAuditRun(this);
}
}

WebInspector.ExtensionAuditCategoryResults._lastId = 0;





WebInspector.commonExtensionSymbols = function(apiPrivate)
{

if (!apiPrivate.audits)
apiPrivate.audits = {};

apiPrivate.audits.Severity = {
Info: "info",
Warning: "warning",
Severe: "severe"
};
}

WebInspector.extensionAPI = {};

WebInspector.commonExtensionSymbols(WebInspector.extensionAPI);





WebInspector.ExtensionServer = function()
{
this._clientObjects = {};
this._handlers = {};
this._subscribers = {};
this._status = new WebInspector.ExtensionStatus();

this._registerHandler("addAuditCategory", this._onAddAuditCategory.bind(this));
this._registerHandler("addAuditResult", this._onAddAuditResult.bind(this));
this._registerHandler("createPanel", this._onCreatePanel.bind(this));
this._registerHandler("createSidebarPane", this._onCreateSidebar.bind(this));
this._registerHandler("createWatchExpressionSidebarPane", this._onCreateWatchExpressionSidebarPane.bind(this));
this._registerHandler("evaluateOnInspectedPage", this._onEvaluateOnInspectedPage.bind(this));
this._registerHandler("getHAR", this._onGetHAR.bind(this));
this._registerHandler("getResourceContent", this._onGetResourceContent.bind(this));
this._registerHandler("log", this._onLog.bind(this));
this._registerHandler("reload", this._onReload.bind(this));
this._registerHandler("setSidebarHeight", this._onSetSidebarHeight.bind(this));
this._registerHandler("setWatchSidebarContent", this._onSetWatchSidebarContent.bind(this));
this._registerHandler("stopAuditCategoryRun", this._onStopAuditCategoryRun.bind(this));
this._registerHandler("subscribe", this._onSubscribe.bind(this));
this._registerHandler("unsubscribe", this._onUnsubscribe.bind(this));


window.addEventListener("message", this._onWindowMessage.bind(this), false);
}

WebInspector.ExtensionServer.prototype = {
notifyPanelShown: function(panelName)
{
this._postNotification("panel-shown-" + panelName);
},

notifyObjectSelected: function(panelId, objectId)
{
this._postNotification("panel-objectSelected-" + panelId, objectId);
},

notifyResourceFinished: function(resource)
{
this._postNotification("resource-finished", resource.identifier, (new WebInspector.HAREntry(resource)).build());
},

notifySearchAction: function(panelId, action, searchString)
{
this._postNotification("panel-search-" + panelId, action, searchString);
},

notifyPageLoaded: function(milliseconds)
{
this._postNotification("inspectedPageLoaded", milliseconds);
},

notifyPageDOMContentLoaded: function(milliseconds)
{
this._postNotification("inspectedPageDOMContentLoaded", milliseconds);
},

notifyInspectedURLChanged: function()
{
this._postNotification("inspectedURLChanged");
},

notifyInspectorReset: function()
{
this._postNotification("reset");
},

notifyExtensionWatchSidebarUpdated: function(id)
{
this._postNotification("watch-sidebar-updated-" + id);
},

startAuditRun: function(category, auditRun)
{
this._clientObjects[auditRun.id] = auditRun;
this._postNotification("audit-started-" + category.id, auditRun.id);
},

stopAuditRun: function(auditRun)
{
delete this._clientObjects[auditRun.id];
},

_postNotification: function(type, details)
{
var subscribers = this._subscribers[type];
if (!subscribers)
return;
var message = {
command: "notify-" + type,
arguments: Array.prototype.slice.call(arguments, 1)
};
for (var i = 0; i < subscribers.length; ++i)
subscribers[i].postMessage(message);
},

_onSubscribe: function(message, port)
{
var subscribers = this._subscribers[message.type];
if (subscribers)
subscribers.push(port);
else
this._subscribers[message.type] = [ port ];
},

_onUnsubscribe: function(message, port)
{
var subscribers = this._subscribers[message.type];
if (!subscribers)
return;
subscribers.remove(port);
if (!subscribers.length)
delete this._subscribers[message.type];
},

_onCreatePanel: function(message, port)
{
var id = message.id;


if (id in this._clientObjects || id in WebInspector.panels)
return this._status.E_EXISTS(id);
var panel = new WebInspector.ExtensionPanel(id, message.title, message.icon);
this._clientObjects[id] = panel;

var toolbarElement = document.getElementById("toolbar");
var lastToolbarItem = WebInspector.panelOrder[WebInspector.panelOrder.length - 1].toolbarItem;
WebInspector.addPanelToolbarIcon(toolbarElement, panel, lastToolbarItem);
WebInspector.panels[id] = panel;
var iframe = this._createClientIframe(panel.element, message.url);
iframe.style.height = "100%";
return this._status.OK();
},

_onCreateSidebar: function(message)
{
var sidebar = this._createSidebar(message, WebInspector.SidebarPane);
if (sidebar.isError)
return sidebar;
this._createClientIframe(sidebar.bodyElement, message.url);
return this._status.OK();
},

_onCreateWatchExpressionSidebarPane: function(message)
{
var sidebar = this._createSidebar(message, WebInspector.ExtensionWatchSidebarPane);
return sidebar.isError ? sidebar : this._status.OK();
},

_createSidebar: function(message, constructor)
{
var panel = WebInspector.panels[message.panel];
if (!panel)
return this._status.E_NOTFOUND(message.panel);
if (!panel.sidebarElement || !panel.sidebarPanes)
return this._status.E_NOTSUPPORTED();
var id = message.id;
var sidebar = new constructor(message.title, message.id);
this._clientObjects[id] = sidebar;
panel.sidebarPanes[id] = sidebar;
panel.sidebarElement.appendChild(sidebar.element);

return sidebar;
},

_createClientIframe: function(parent, url, requestId, port)
{
var iframe = document.createElement("iframe");
iframe.src = url;
iframe.style.width = "100%";
parent.appendChild(iframe);
return iframe;
},

_onSetSidebarHeight: function(message)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
sidebar.bodyElement.firstChild.style.height = message.height;
},

_onSetWatchSidebarContent: function(message)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
if (message.evaluateOnPage)
sidebar.setExpression(message.expression, message.rootTitle);
else
sidebar.setObject(message.expression, message.rootTitle);
},

_onLog: function(message)
{
WebInspector.log(message.message);
},

_onReload: function()
{
InspectorBackend.reloadPage();
return this._status.OK();
},

_onEvaluateOnInspectedPage: function(message, port)
{
function callback(resultPayload)
{
var resultObject = WebInspector.RemoteObject.fromPayload(resultPayload);
var result = {};
if (resultObject.isError())
result.isException = true;
result.value = resultObject.description;
this._dispatchCallback(message.requestId, port, result);
}
var evalExpression = "JSON.stringify(eval('" +
"with (window.console._commandLineAPI) with (window) {' + unescape('" + escape(message.expression) +
"') + '}'));";
InjectedScriptAccess.getDefault().evaluate(evalExpression, callback.bind(this));
},

_onRevealAndSelect: function(message)
{
if (message.panelId === "resources" && type === "resource")
return this._onRevealAndSelectResource(message);
else
return this._status.E_NOTSUPPORTED(message.panelId, message.type);
},

_onRevealAndSelectResource: function(message)
{
var id = message.id;
var resource = null;

resource = WebInspector.networkResources[id] || WebInspector.resourceForURL(id);
if (!resource)
return this._status.E_NOTFOUND(typeof id + ": " + id);

WebInspector.panels.resources.showResource(resource, message.line);
WebInspector.showPanel("resources");
},

_dispatchCallback: function(requestId, port, result)
{
port.postMessage({ command: "callback", requestId: requestId, result: result });
},

_onGetHAR: function(request)
{
var harLog = new WebInspector.HARLog();
harLog.includeResourceIds = true;
return harLog.build();
},

_onGetResourceContent: function(message, port)
{
function onContentAvailable(content, encoded)
{
var response = {
encoding: encoded ? "base64" : "",
content: content
};
this._dispatchCallback(message.requestId, port, response);
}
var resource = WebInspector.networkResources[message.id];
if (!resource)
return this._status.E_NOTFOUND(message.id);
resource.requestContent(onContentAvailable.bind(this));
},

_onAddAuditCategory: function(request)
{
var category = new WebInspector.ExtensionAuditCategory(request.id, request.displayName, request.resultCount);
if (WebInspector.panels.audits.getCategory(category.id))
return this._status.E_EXISTS(category.id);
this._clientObjects[request.id] = category;
WebInspector.panels.audits.addCategory(category);
},

_onAddAuditResult: function(request)
{
var auditResult = this._clientObjects[request.resultId];
if (!auditResult)
return this._status.E_NOTFOUND(request.resultId);
try {
auditResult.addResult(request.displayName, request.description, request.severity, request.details);
} catch (e) {
return e;
}
return this._status.OK();
},

_onStopAuditCategoryRun: function(request)
{
var auditRun = this._clientObjects[request.resultId];
if (!auditRun)
return this._status.E_NOTFOUND(request.resultId);
auditRun.cancel();
},

initExtensions: function()
{
InspectorExtensionRegistry.getExtensionsAsync();
},

_addExtensions: function(extensions)
{

InspectorFrontendHost.setExtensionAPI(this._buildExtensionAPIInjectedScript());
for (var i = 0; i < extensions.length; ++i) {
var extension = extensions[i];
try {
if (!extension.startPage)
return;
var iframe = document.createElement("iframe");
iframe.src = extension.startPage;
iframe.style.display = "none";
document.body.appendChild(iframe);
} catch (e) {
console.error("Failed to initialize extension " + extension.startPage + ":" + e);
}
}
},

_buildExtensionAPIInjectedScript: function()
{
var resourceTypes = {};
var resourceTypeProperties = Object.getOwnPropertyNames(WebInspector.Resource.Type);
for (var i = 0; i < resourceTypeProperties.length; ++i) {
var propName = resourceTypeProperties[i];
var propValue = WebInspector.Resource.Type[propName];
if (typeof propValue === "number")
resourceTypes[propName] = WebInspector.Resource.Type.toString(propValue);
}
var platformAPI = WebInspector.buildPlatformExtensionAPI ? WebInspector.buildPlatformExtensionAPI() : "";
return "(function(){ " +
"var apiPrivate = {};" +
"(" + WebInspector.commonExtensionSymbols.toString() + ")(apiPrivate);" +
"(" + WebInspector.injectedExtensionAPI.toString() + ").apply(this, arguments);" +
"webInspector.resources.Types = " + JSON.stringify(resourceTypes) + ";" +
platformAPI +
"})";
},

_onWindowMessage: function(event)
{
if (event.data !== "registerExtension")
return;
var port = event.ports[0];
port.addEventListener("message", this._onmessage.bind(this), false);
port.start();
},

_onmessage: function(event)
{
var request = event.data;
var result;

if (request.command in this._handlers)
result = this._handlers[request.command](request, event.target);
else
result = this._status.E_NOTSUPPORTED(request.command);

if (result && request.requestId)
this._dispatchCallback(request.requestId, event.target, result);
},

_registerHandler: function(command, callback)
{
this._handlers[command] = callback;
}
}

WebInspector.ExtensionServer._statuses =
{
OK: "",
E_EXISTS: "Object already exists: %s",
E_BADARG: "Invalid argument %s: %s",
E_BADARGTYPE: "Invalid type for argument %s: got %s, expected %s",
E_NOTFOUND: "Object not found: %s",
E_NOTSUPPORTED: "Object does not support requested operation: %s",
}

WebInspector.ExtensionStatus = function()
{
function makeStatus(code)
{
var description = WebInspector.ExtensionServer._statuses[code] || code;
var details = Array.prototype.slice.call(arguments, 1);
var status = { code: code, description: description, details: details };
if (code !== "OK") {
status.isError = true;
console.log("Extension server error: " + String.vsprintf(description, details));
}
return status;
}
for (status in WebInspector.ExtensionServer._statuses)
this[status] = makeStatus.bind(null, status);
}

WebInspector.addExtensions = function(extensions)
{
WebInspector.extensionServer._addExtensions(extensions);
}

WebInspector.extensionServer = new WebInspector.ExtensionServer();





WebInspector.ExtensionPanel = function(id, label, iconURL, options)
{
this.toolbarItemLabel = label;
this._addStyleRule(".toolbar-item." + id + " .toolbar-icon", "background-image: url(" + iconURL + ");");
WebInspector.Panel.call(this, id);
}

WebInspector.ExtensionPanel.prototype = {
get defaultFocusedElement()
{
return this.sidebarTreeElement || this.element;
},

updateMainViewWidth: function(width)
{
this.bodyElement.style.left = width + "px";
this.resize();
},

searchCanceled: function(startingNewSearch)
{
WebInspector.extensionServer.notifySearchAction(this._id, "cancelSearch");
WebInspector.Panel.prototype.searchCanceled.apply(this, arguments);
},

performSearch: function(query)
{
WebInspector.extensionServer.notifySearchAction(this._id, "performSearch", query);
WebInspector.Panel.prototype.performSearch.apply(this, arguments);
},

jumpToNextSearchResult: function()
{
WebInspector.extensionServer.notifySearchAction(this._id, "nextSearchResult");
WebInspector.Panel.prototype.jumpToNextSearchResult.call(this);
},

jumpToPreviousSearchResult: function()
{
WebInspector.extensionServer.notifySearchAction(this._id, "previousSearchResult");
WebInspector.Panel.prototype.jumpToPreviousSearchResult.call(this);
},

_addStyleRule: function(selector, body)
{
var style = document.createElement("style");
style.textContent = selector + " { " + body + " }";
document.head.appendChild(style);
}
}

WebInspector.ExtensionPanel.prototype.__proto__ = WebInspector.Panel.prototype;

WebInspector.ExtensionWatchSidebarPane = function(title, id)
{
WebInspector.SidebarPane.call(this, title);
this._id = id;
}

WebInspector.ExtensionWatchSidebarPane.prototype = {
setObject: function(object, title)
{
this._setObject(WebInspector.RemoteObject.fromLocalObject(object), title);
},

setExpression: function(expression, title)
{
InjectedScriptAccess.getDefault().evaluate(expression, this._onEvaluate.bind(this, title));
},

_onEvaluate: function(title, result)
{
this._setObject(WebInspector.RemoteObject.fromPayload(result), title);
},

_setObject: function(object, title)
{
this.bodyElement.removeChildren();
var section = new WebInspector.ObjectPropertiesSection(object, title, null, true);
if (!title)
section.headerElement.addStyleClass("hidden");
section.expanded = true;
this.bodyElement.appendChild(section.element);
WebInspector.extensionServer.notifyExtensionWatchSidebarUpdated(this._id);
}
}

WebInspector.ExtensionWatchSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;





WebInspector.AuditsPanel = function()
{
WebInspector.Panel.call(this, "audits");

this.createSidebar();
this.auditsTreeElement = new WebInspector.SidebarSectionTreeElement("", {}, true);
this.sidebarTree.appendChild(this.auditsTreeElement);
this.auditsTreeElement.listItemElement.addStyleClass("hidden");
this.auditsTreeElement.expand();

this.auditsItemTreeElement = new WebInspector.AuditsSidebarTreeElement();
this.auditsTreeElement.appendChild(this.auditsItemTreeElement);

this.auditResultsTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("RESULTS"), {}, true);
this.sidebarTree.appendChild(this.auditResultsTreeElement);
this.auditResultsTreeElement.expand();

this.clearResultsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear audit results."), "clear-status-bar-item");
this.clearResultsButton.addEventListener("click", this._clearButtonClicked.bind(this), false);

this.viewsContainerElement = document.createElement("div");
this.viewsContainerElement.id = "audit-views";
this.element.appendChild(this.viewsContainerElement);

this._constructCategories();

this._launcherView = new WebInspector.AuditLauncherView(this.initiateAudit.bind(this));
for (id in this.categoriesById)
this._launcherView.addCategory(this.categoriesById[id]);
}

WebInspector.AuditsPanel.prototype = {
get toolbarItemLabel()
{
return WebInspector.UIString("Audits");
},

get statusBarItems()
{
return [this.clearResultsButton.element];
},

get mainResourceLoadTime()
{
return this._mainResourceLoadTime;
},

set mainResourceLoadTime(x)
{
this._mainResourceLoadTime = x;
this._didMainResourceLoad();
},

get mainResourceDOMContentTime()
{
return this._mainResourceDOMContentTime;
},

set mainResourceDOMContentTime(x)
{
this._mainResourceDOMContentTime = x;
},

get categoriesById()
{
return this._auditCategoriesById;
},

resourceStarted: function(resource)
{
this._launcherView.resourceStarted(resource);
},

resourceFinished: function(resource)
{
this._launcherView.resourceFinished(resource);
},

addCategory: function(category)
{
this.categoriesById[category.id] = category;
this._launcherView.addCategory(category);
},

getCategory: function(id)
{
return this.categoriesById[id];
},

_constructCategories: function()
{
this._auditCategoriesById = {};
for (var categoryCtorID in WebInspector.AuditCategories) {
var auditCategory = new WebInspector.AuditCategories[categoryCtorID]();
auditCategory._id = categoryCtorID;
this.categoriesById[categoryCtorID] = auditCategory;
}
},

_executeAudit: function(categories, resultCallback)
{
var resources = [];
for (var id in WebInspector.networkResources)
resources.push(WebInspector.networkResources[id]);

var rulesRemaining = 0;
for (var i = 0; i < categories.length; ++i)
rulesRemaining += categories[i].ruleCount;

var results = [];
var mainResourceURL = WebInspector.mainResource.url;

function ruleResultReadyCallback(categoryResult, ruleResult)
{
if (ruleResult && ruleResult.children)
categoryResult.addRuleResult(ruleResult);

--rulesRemaining;

if (!rulesRemaining && resultCallback)
resultCallback(mainResourceURL, results);
}

if (!rulesRemaining) {
resultCallback(mainResourceURL, results);
return;
}

for (var i = 0; i < categories.length; ++i) {
var category = categories[i];
var result = new WebInspector.AuditCategoryResult(category);
results.push(result);
category.run(resources, ruleResultReadyCallback.bind(null, result));
}
},

_auditFinishedCallback: function(launcherCallback, mainResourceURL, results)
{
var children = this.auditResultsTreeElement.children;
var ordinal = 1;
for (var i = 0; i < children.length; ++i) {
if (children[i].mainResourceURL === mainResourceURL)
ordinal++;
}

var resultTreeElement = new WebInspector.AuditResultSidebarTreeElement(results, mainResourceURL, ordinal);
this.auditResultsTreeElement.appendChild(resultTreeElement);
resultTreeElement.reveal();
resultTreeElement.select();
if (launcherCallback)
launcherCallback();
},

initiateAudit: function(categoryIds, runImmediately, launcherCallback)
{
if (!categoryIds || !categoryIds.length)
return;

var categories = [];
for (var i = 0; i < categoryIds.length; ++i)
categories.push(this.categoriesById[categoryIds[i]]);

function initiateAuditCallback(categories, launcherCallback)
{
this._executeAudit(categories, this._auditFinishedCallback.bind(this, launcherCallback));
}

if (runImmediately)
initiateAuditCallback.call(this, categories, launcherCallback);
else
this._reloadResources(initiateAuditCallback.bind(this, categories, launcherCallback));
},

_reloadResources: function(callback)
{
this._pageReloadCallback = callback;
InspectorBackend.reloadPage();
},

_didMainResourceLoad: function()
{
if (this._pageReloadCallback) {
var callback = this._pageReloadCallback;
delete this._pageReloadCallback;
callback();
}
},

showResults: function(categoryResults)
{
if (!categoryResults._resultView)
categoryResults._resultView = new WebInspector.AuditResultView(categoryResults);

this.visibleView = categoryResults._resultView;
},

showLauncherView: function()
{
this.visibleView = this._launcherView;
},

get visibleView()
{
return this._visibleView;
},

set visibleView(x)
{
if (this._visibleView === x)
return;

if (this._visibleView)
this._visibleView.hide();

this._visibleView = x;

if (x)
x.show(this.viewsContainerElement);
},

reset: function()
{
this._launcherView.reset();
},

attach: function()
{
WebInspector.Panel.prototype.attach.call(this);

this.auditsItemTreeElement.select();
},

updateMainViewWidth: function(width)
{
this.viewsContainerElement.style.left = width + "px";
},

_clearButtonClicked: function()
{
this.auditsItemTreeElement.reveal();
this.auditsItemTreeElement.select();
this.auditResultsTreeElement.removeChildren();
}
}

WebInspector.AuditsPanel.prototype.__proto__ = WebInspector.Panel.prototype;



WebInspector.AuditCategory = function(displayName)
{
this._displayName = displayName;
this._rules = [];
}

WebInspector.AuditCategory.prototype = {
get id()
{

return this._id;
},

get displayName()
{
return this._displayName;
},

get ruleCount()
{
this._ensureInitialized();
return this._rules.length;
},

addRule: function(rule, severity)
{
rule.severity = severity;
this._rules.push(rule);
},

run: function(resources, callback)
{
this._ensureInitialized();
for (var i = 0; i < this._rules.length; ++i)
this._rules[i].run(resources, callback);
},

_ensureInitialized: function()
{
if (!this._initialized) {
if ("initialize" in this)
this.initialize();
this._initialized = true;
}
}
}


WebInspector.AuditRule = function(id, displayName)
{
this._id = id;
this._displayName = displayName;
}

WebInspector.AuditRule.Severity = {
Info: "info",
Warning: "warning",
Severe: "severe"
}

WebInspector.AuditRule.SeverityOrder = {
"info": 3,
"warning": 2,
"severe": 1
}

WebInspector.AuditRule.prototype = {
get id()
{
return this._id;
},

get displayName()
{
return this._displayName;
},

set severity(severity)
{
this._severity = severity;
},

run: function(resources, callback)
{
var result = new WebInspector.AuditRuleResult(this.displayName);
result.severity = this._severity;
this.doRun(resources, result, callback);
},

doRun: function(resources, result, callback)
{
throw new Error("doRun() not implemented");
}
}

WebInspector.AuditCategoryResult = function(category)
{
this.title = category.displayName;
this.ruleResults = [];
}

WebInspector.AuditCategoryResult.prototype = {
addRuleResult: function(ruleResult)
{
this.ruleResults.push(ruleResult);
}
}

WebInspector.AuditRuleResult = function(value, expanded, className)
{
this.value = value;
this.className = className;
this.expanded = expanded;
this.violationCount = 0;
}

WebInspector.AuditRuleResult.linkifyDisplayName = function(url)
{
return WebInspector.linkifyURL(url, WebInspector.displayNameForURL(url));
}

WebInspector.AuditRuleResult.resourceDomain = function(domain)
{
return domain || WebInspector.UIString("[empty domain]");
}

WebInspector.AuditRuleResult.prototype = {
addChild: function(value, expanded, className)
{
if (!this.children)
this.children = [];
var entry = new WebInspector.AuditRuleResult(value, expanded, className);
this.children.push(entry);
return entry;
},

addURL: function(url)
{
return this.addChild(WebInspector.AuditRuleResult.linkifyDisplayName(url));
},

addURLs: function(urls)
{
for (var i = 0; i < urls.length; ++i)
this.addURL(urls[i]);
},

addSnippet: function(snippet)
{
return this.addChild(snippet, false, "source-code");
}
}

WebInspector.AuditsSidebarTreeElement = function()
{
this.small = false;

WebInspector.SidebarTreeElement.call(this, "audits-sidebar-tree-item", WebInspector.UIString("Audits"), "", null, false);
}

WebInspector.AuditsSidebarTreeElement.prototype = {
onattach: function()
{
WebInspector.SidebarTreeElement.prototype.onattach.call(this);
},

onselect: function()
{
WebInspector.panels.audits.showLauncherView();
},

get selectable()
{
return true;
},

refresh: function()
{
this.refreshTitles();
}
}

WebInspector.AuditsSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;


WebInspector.AuditResultSidebarTreeElement = function(results, mainResourceURL, ordinal)
{
this.results = results;
this.mainResourceURL = mainResourceURL;

WebInspector.SidebarTreeElement.call(this, "audit-result-sidebar-tree-item", String.sprintf("%s (%d)", mainResourceURL, ordinal), "", {}, false);
}

WebInspector.AuditResultSidebarTreeElement.prototype = {
onselect: function()
{
WebInspector.panels.audits.showResults(this.results);
},

get selectable()
{
return true;
}
}

WebInspector.AuditResultSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;


WebInspector.AuditRules = {};


WebInspector.AuditCategories = {};





WebInspector.AuditResultView = function(categoryResults)
{
WebInspector.View.call(this);
this.element.className = "audit-result-view";

function categorySorter(a, b) {
return (a.title || "").localeCompare(b.title || "");
}
categoryResults.sort(categorySorter);
for (var i = 0; i < categoryResults.length; ++i)
this.element.appendChild(new WebInspector.AuditCategoryResultPane(categoryResults[i]).element);
}

WebInspector.AuditResultView.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.AuditCategoryResultPane = function(categoryResult)
{
WebInspector.SidebarPane.call(this, categoryResult.title);
var treeOutlineElement = document.createElement("ol");
this.bodyElement.addStyleClass("audit-result-tree");
this.bodyElement.appendChild(treeOutlineElement);

this._treeOutline = new TreeOutline(treeOutlineElement);
this._treeOutline.expandTreeElementsWhenArrowing = true;

function ruleSorter(a, b)
{
var result = WebInspector.AuditRule.SeverityOrder[a.severity || 0] - WebInspector.AuditRule.SeverityOrder[b.severity || 0];
if (!result)
result = (a.value || "").localeCompare(b.value || "");
return result;
}

categoryResult.ruleResults.sort(ruleSorter);

for (var i = 0; i < categoryResult.ruleResults.length; ++i) {
var ruleResult = categoryResult.ruleResults[i];
var treeElement = this._appendResult(this._treeOutline, ruleResult);
treeElement.listItemElement.addStyleClass("audit-result");

if (ruleResult.severity) {
var severityElement = document.createElement("img");
severityElement.className = "severity-" + ruleResult.severity;
treeElement.listItemElement.appendChild(severityElement);
}
}
this.expand();
}

WebInspector.AuditCategoryResultPane.prototype = {
_appendResult: function(parentTreeElement, result)
{
var title = "";

if (typeof result.value === "string") {
title = result.value;
if (result.violationCount)
title = String.sprintf("%s (%d)", title, result.violationCount);
}

var treeElement = new TreeElement(null, null, !!result.children);
treeElement.titleHTML = title;
parentTreeElement.appendChild(treeElement);

if (result.className)
treeElement.listItemElement.addStyleClass(result.className);
if (typeof result.value !== "string")
treeElement.listItemElement.appendChild(WebInspector.applyFormatters(result.value));

if (result.children) {
for (var i = 0; i < result.children.length; ++i)
this._appendResult(treeElement, result.children[i]);
}
if (result.expanded) {
treeElement.listItemElement.removeStyleClass("parent");
treeElement.listItemElement.addStyleClass("parent-expanded");
treeElement.expand();
}
return treeElement;
}
}

WebInspector.AuditCategoryResultPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;





WebInspector.AuditLauncherView = function(runnerCallback)
{
WebInspector.View.call(this);
this._runnerCallback = runnerCallback;
this._categoryIdPrefix = "audit-category-item-";
this._auditRunning = false;

this.element.addStyleClass("audit-launcher-view");

this._contentElement = document.createElement("div");
this._contentElement.className = "audit-launcher-view-content";
this.element.appendChild(this._contentElement);
this._boundCategoryClickListener = this._categoryClicked.bind(this);

this._resetResourceCount();

this._sortedCategories = [];

this._headerElement = document.createElement("h1");
this._headerElement.className = "no-audits";
this._headerElement.textContent = WebInspector.UIString("No audits to run");
this._contentElement.appendChild(this._headerElement);
}

WebInspector.AuditLauncherView.prototype = {
get totalResources()
{
return this._totalResources;
},

set totalResources(x)
{
if (this._totalResources === x)
return;
this._totalResources = x;
this._updateResourceProgress();
},

get loadedResources()
{
return this._loadedResources;
},

set loadedResources(x)
{
if (this._loadedResources === x)
return;
this._loadedResources = x;
this._updateResourceProgress();
},

_resetResourceCount: function()
{
this.loadedResources = 0;



this.totalResources = 1;
},

resourceStarted: function(resource)
{
++this.totalResources;
},

resourceFinished: function(resource)
{
++this.loadedResources;
},

reset: function()
{
this._resetResourceCount();
},

addCategory: function(category)
{
if (!this._sortedCategories.length)
this._createLauncherUI();

var categoryElement = this._createCategoryElement(category.displayName, category.id);
category._checkboxElement = categoryElement.firstChild;
if (this._selectAllCheckboxElement.checked) {
category._checkboxElement.checked = true;
++this._currentCategoriesCount;
}

function compareCategories(a, b)
{
var aTitle = a.displayName || "";
var bTitle = b.displayName || "";
return aTitle.localeCompare(bTitle);
}
var insertBefore = insertionIndexForObjectInListSortedByFunction(category, this._sortedCategories, compareCategories);
this._categoriesElement.insertBefore(categoryElement, this._categoriesElement.children[insertBefore]);
this._sortedCategories.splice(insertBefore, 0, category);
this._updateButton();
},

_setAuditRunning: function(auditRunning)
{
if (this._auditRunning === auditRunning)
return;
this._auditRunning = auditRunning;
this._updateButton();
this._updateResourceProgress();
},

_launchButtonClicked: function(event)
{
var catIds = [];
var childNodes = this._categoriesElement.childNodes;
for (var category = 0; category < this._sortedCategories.length; ++category) {
if (this._sortedCategories[category]._checkboxElement.checked)
catIds.push(this._sortedCategories[category].id);
}

this._setAuditRunning(true);
this._runnerCallback(catIds, this._auditPresentStateElement.checked, this._setAuditRunning.bind(this, false));
},

_selectAllClicked: function(checkCategories)
{
var childNodes = this._categoriesElement.childNodes;
for (var i = 0, length = childNodes.length; i < length; ++i)
childNodes[i].firstChild.checked = checkCategories;
this._currentCategoriesCount = checkCategories ? this._sortedCategories.length : 0;
this._updateButton();
},

_categoryClicked: function(event)
{
this._currentCategoriesCount += event.target.checked ? 1 : -1;
this._selectAllCheckboxElement.checked = this._currentCategoriesCount === this._sortedCategories.length;
this._updateButton();
},

_createCategoryElement: function(title, id)
{
var labelElement = document.createElement("label");
labelElement.id = this._categoryIdPrefix + id;

var element = document.createElement("input");
element.type = "checkbox";
if (id !== "")
element.addEventListener("click", this._boundCategoryClickListener, false);
labelElement.appendChild(element);
labelElement.appendChild(document.createTextNode(title));

return labelElement;
},

_createLauncherUI: function()
{
this._headerElement = document.createElement("h1");
this._headerElement.textContent = WebInspector.UIString("Select audits to run");

for (var child = 0; child < this._contentElement.children.length; ++child)
this._contentElement.removeChild(this._contentElement.children[child]);

this._contentElement.appendChild(this._headerElement);

function handleSelectAllClick(event)
{
this._selectAllClicked(event.target.checked);
}
var categoryElement = this._createCategoryElement(WebInspector.UIString("Select All"), "");
categoryElement.id = "audit-launcher-selectall";
this._selectAllCheckboxElement = categoryElement.firstChild;
this._selectAllCheckboxElement.checked = true;
this._selectAllCheckboxElement.addEventListener("click", handleSelectAllClick.bind(this), false);
this._contentElement.appendChild(categoryElement);

this._categoriesElement = document.createElement("div");
this._categoriesElement.className = "audit-categories-container";
this._contentElement.appendChild(this._categoriesElement);

this._currentCategoriesCount = 0;

var flexibleSpaceElement = document.createElement("div");
flexibleSpaceElement.className = "flexible-space";
this._contentElement.appendChild(flexibleSpaceElement);

this._buttonContainerElement = document.createElement("div");
this._buttonContainerElement.className = "button-container";

var labelElement = document.createElement("label");
this._auditPresentStateElement = document.createElement("input");
this._auditPresentStateElement.name = "audit-mode";
this._auditPresentStateElement.type = "radio";
this._auditPresentStateElement.checked = true;
this._auditPresentStateLabelElement = document.createTextNode(WebInspector.UIString("Audit Present State"));
labelElement.appendChild(this._auditPresentStateElement);
labelElement.appendChild(this._auditPresentStateLabelElement);
this._buttonContainerElement.appendChild(labelElement);

labelElement = document.createElement("label");
this.auditReloadedStateElement = document.createElement("input");
this.auditReloadedStateElement.name = "audit-mode";
this.auditReloadedStateElement.type = "radio";
labelElement.appendChild(this.auditReloadedStateElement);
labelElement.appendChild(document.createTextNode("Reload Page and Audit on Load"));
this._buttonContainerElement.appendChild(labelElement);

this._launchButton = document.createElement("button");
this._launchButton.type = "button";
this._launchButton.textContent = WebInspector.UIString("Run");
this._launchButton.addEventListener("click", this._launchButtonClicked.bind(this), false);
this._buttonContainerElement.appendChild(this._launchButton);

this._resourceProgressContainer = document.createElement("span");
this._resourceProgressContainer.className = "resource-progress";
var resourceProgressImage = document.createElement("img");
this._resourceProgressContainer.appendChild(resourceProgressImage);
this._resourceProgressTextElement = document.createElement("span");
this._resourceProgressContainer.appendChild(this._resourceProgressTextElement);
this._buttonContainerElement.appendChild(this._resourceProgressContainer);

this._contentElement.appendChild(this._buttonContainerElement);

this._selectAllClicked(this._selectAllCheckboxElement.checked);
this._updateButton();
this._updateResourceProgress();
},

_updateResourceProgress: function()
{
if (!this._resourceProgressContainer)
return;

if (!this._auditRunning) {
this._resetResourceCount();
this._resourceProgressContainer.addStyleClass("hidden");
} else
this._resourceProgressContainer.removeStyleClass("hidden");
this._resourceProgressTextElement.textContent = WebInspector.UIString("Loading (%d of %d)", this.loadedResources, this.totalResources);
},

_updateButton: function()
{
this._launchButton.disabled = !this._currentCategoriesCount || this._auditRunning;
}
}

WebInspector.AuditLauncherView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.AuditRules.IPAddressRegexp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;

WebInspector.AuditRules.CacheableResponseCodes =
{
200: true,
203: true,
206: true,
300: true,
301: true,
410: true,

304: true 
}

WebInspector.AuditRules.getDomainToResourcesMap = function(resources, types, needFullResources)
{
var domainToResourcesMap = {};
for (var i = 0, size = resources.length; i < size; ++i) {
var resource = resources[i];
if (types && types.indexOf(resource.type) === -1)
continue;
var parsedURL = resource.url.asParsedURL();
if (!parsedURL)
continue;
var domain = parsedURL.host;
var domainResources = domainToResourcesMap[domain];
if (domainResources === undefined) {
domainResources = [];
domainToResourcesMap[domain] = domainResources;
}
domainResources.push(needFullResources ? resource : resource.url);
}
return domainToResourcesMap;
}

WebInspector.AuditRules.evaluateInTargetWindow = function(func, args, callback)
{
InjectedScriptAccess.getDefault().evaluateOnSelf(func.toString(), args, callback);
}


WebInspector.AuditRules.GzipRule = function()
{
WebInspector.AuditRule.call(this, "network-gzip", "Enable gzip compression");
}

WebInspector.AuditRules.GzipRule.prototype = {
doRun: function(resources, result, callback)
{
var totalSavings = 0;
var compressedSize = 0;
var candidateSize = 0;
var summary = result.addChild("", true);
for (var i = 0, length = resources.length; i < length; ++i) {
var resource = resources[i];
if (this._shouldCompress(resource)) {
var size = resource.resourceSize;
candidateSize += size;
if (this._isCompressed(resource)) {
compressedSize += size;
continue;
}
var savings = 2 * size / 3;
totalSavings += savings;
summary.addChild(String.sprintf("%s could save ~%s", WebInspector.AuditRuleResult.linkifyDisplayName(resource.url), Number.bytesToString(savings, WebInspector.UIString)));
result.violationCount++;
}
}
if (!totalSavings)
return callback(null);
summary.value = String.sprintf("Compressing the following resources with gzip could reduce their transfer size by about two thirds (~%s):", Number.bytesToString(totalSavings, WebInspector.UIString));
callback(result);
},

_isCompressed: function(resource)
{
var encoding = resource.responseHeaders["Content-Encoding"];
return encoding === "gzip" || encoding === "deflate";
},

_shouldCompress: function(resource)
{
return WebInspector.Resource.Type.isTextType(resource.type) && resource.domain && resource.resourceSize !== undefined && resource.resourceSize > 150;
}
}

WebInspector.AuditRules.GzipRule.prototype.__proto__ = WebInspector.AuditRule.prototype;


WebInspector.AuditRules.CombineExternalResourcesRule = function(id, name, type, resourceTypeName, allowedPerDomain)
{
WebInspector.AuditRule.call(this, id, name);
this._type = type;
this._resourceTypeName = resourceTypeName;
this._allowedPerDomain = allowedPerDomain;
}

WebInspector.AuditRules.CombineExternalResourcesRule.prototype = {
doRun: function(resources, result, callback)
{
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(resources, [this._type]);
var penalizedResourceCount = 0;

var summary = result.addChild("", true);
for (var domain in domainToResourcesMap) {
var domainResources = domainToResourcesMap[domain];
var extraResourceCount = domainResources.length - this._allowedPerDomain;
if (extraResourceCount <= 0)
continue;
penalizedResourceCount += extraResourceCount - 1;
summary.addChild(String.sprintf("%d %s resources served from %s.", domainResources.length, this._resourceTypeName, WebInspector.AuditRuleResult.resourceDomain(domain)));
result.violationCount += domainResources.length;
}
if (!penalizedResourceCount)
return callback(null);

summary.value = "There are multiple resources served from same domain. Consider combining them into as few files as possible.";
callback(result);
}
}

WebInspector.AuditRules.CombineExternalResourcesRule.prototype.__proto__ = WebInspector.AuditRule.prototype;


WebInspector.AuditRules.CombineJsResourcesRule = function(allowedPerDomain) {
WebInspector.AuditRules.CombineExternalResourcesRule.call(this, "page-externaljs", "Combine external JavaScript", WebInspector.Resource.Type.Script, "JavaScript", allowedPerDomain);
}

WebInspector.AuditRules.CombineJsResourcesRule.prototype.__proto__ = WebInspector.AuditRules.CombineExternalResourcesRule.prototype;


WebInspector.AuditRules.CombineCssResourcesRule = function(allowedPerDomain) {
WebInspector.AuditRules.CombineExternalResourcesRule.call(this, "page-externalcss", "Combine external CSS", WebInspector.Resource.Type.Stylesheet, "CSS", allowedPerDomain);
}

WebInspector.AuditRules.CombineCssResourcesRule.prototype.__proto__ = WebInspector.AuditRules.CombineExternalResourcesRule.prototype;


WebInspector.AuditRules.MinimizeDnsLookupsRule = function(hostCountThreshold) {
WebInspector.AuditRule.call(this, "network-minimizelookups", "Minimize DNS lookups");
this._hostCountThreshold = hostCountThreshold;
}

WebInspector.AuditRules.MinimizeDnsLookupsRule.prototype = {
doRun: function(resources, result, callback)
{
var summary = result.addChild("");
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(resources, undefined);
for (var domain in domainToResourcesMap) {
if (domainToResourcesMap[domain].length > 1)
continue;
var parsedURL = domain.asParsedURL();
if (!parsedURL)
continue;
if (!parsedURL.host.search(WebInspector.AuditRules.IPAddressRegexp))
continue; 
summary.addSnippet(match[2]);
result.violationCount++;
}
if (!summary.children || summary.children.length <= this._hostCountThreshold)
return callback(null);

summary.value = "The following domains only serve one resource each. If possible, avoid the extra DNS lookups by serving these resources from existing domains.";
callback(result);
}
}

WebInspector.AuditRules.MinimizeDnsLookupsRule.prototype.__proto__ = WebInspector.AuditRule.prototype;


WebInspector.AuditRules.ParallelizeDownloadRule = function(optimalHostnameCount, minRequestThreshold, minBalanceThreshold)
{
WebInspector.AuditRule.call(this, "network-parallelizehosts", "Parallelize downloads across hostnames");
this._optimalHostnameCount = optimalHostnameCount;
this._minRequestThreshold = minRequestThreshold;
this._minBalanceThreshold = minBalanceThreshold;
}


WebInspector.AuditRules.ParallelizeDownloadRule.prototype = {
doRun: function(resources, result, callback)
{
function hostSorter(a, b)
{
var aCount = domainToResourcesMap[a].length;
var bCount = domainToResourcesMap[b].length;
return (aCount < bCount) ? 1 : (aCount == bCount) ? 0 : -1;
}

var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(
resources,
[WebInspector.Resource.Type.Stylesheet, WebInspector.Resource.Type.Image],
true);

var hosts = [];
for (var url in domainToResourcesMap)
hosts.push(url);

if (!hosts.length)
return callback(null); 

hosts.sort(hostSorter);

var optimalHostnameCount = this._optimalHostnameCount;
if (hosts.length > optimalHostnameCount)
hosts.splice(optimalHostnameCount);

var busiestHostResourceCount = domainToResourcesMap[hosts[0]].length;
var resourceCountAboveThreshold = busiestHostResourceCount - this._minRequestThreshold;
if (resourceCountAboveThreshold <= 0)
return callback(null);

var avgResourcesPerHost = 0;
for (var i = 0, size = hosts.length; i < size; ++i)
avgResourcesPerHost += domainToResourcesMap[hosts[i]].length;


avgResourcesPerHost /= optimalHostnameCount;
avgResourcesPerHost = Math.max(avgResourcesPerHost, 1);

var pctAboveAvg = (resourceCountAboveThreshold / avgResourcesPerHost) - 1.0;
var minBalanceThreshold = this._minBalanceThreshold;
if (pctAboveAvg < minBalanceThreshold)
return callback(null);

var resourcesOnBusiestHost = domainToResourcesMap[hosts[0]];
var entry = result.addChild(String.sprintf("This page makes %d parallelizable requests to %s. Increase download parallelization by distributing the following requests across multiple hostnames.", busiestHostResourceCount, hosts[0]), true);
for (var i = 0; i < resourcesOnBusiestHost.length; ++i)
entry.addURL(resourcesOnBusiestHost[i].url);

result.violationCount = resourcesOnBusiestHost.length;
callback(result);
}
}

WebInspector.AuditRules.ParallelizeDownloadRule.prototype.__proto__ = WebInspector.AuditRule.prototype;




WebInspector.AuditRules.UnusedCssRule = function()
{
WebInspector.AuditRule.call(this, "page-unusedcss", "Remove unused CSS rules");
}

WebInspector.AuditRules.UnusedCssRule.prototype = {
doRun: function(resources, result, callback)
{
var self = this;

function evalCallback(styleSheets) {
if (!styleSheets.length)
return callback(null);

var pseudoSelectorRegexp = /:hover|:link|:active|:visited|:focus|:before|:after/;
var selectors = [];
var testedSelectors = {};
for (var i = 0; i < styleSheets.length; ++i) {
var styleSheet = styleSheets[i];
for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) {
var selectorText = styleSheet.rules[curRule].selectorText;
if (selectorText.match(pseudoSelectorRegexp) || testedSelectors[selectorText])
continue;
selectors.push(selectorText);
testedSelectors[selectorText] = 1;
}
}

function selectorsCallback(callback, styleSheets, testedSelectors, foundSelectors)
{
var inlineBlockOrdinal = 0;
var totalStylesheetSize = 0;
var totalUnusedStylesheetSize = 0;
var summary;

for (var i = 0; i < styleSheets.length; ++i) {
var styleSheet = styleSheets[i];
var stylesheetSize = 0;
var unusedStylesheetSize = 0;
var unusedRules = [];
for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) {
var rule = styleSheet.rules[curRule];

var textLength = (rule.selectorRange && rule.style.properties.endOffset) ? rule.style.properties.endOffset - rule.selectorRange.start + 1 : 0;
if (!textLength && rule.style.cssText)
textLength = rule.style.cssText.length + rule.selectorText.length;
stylesheetSize += textLength;
if (!testedSelectors[rule.selectorText] || foundSelectors[rule.selectorText])
continue;
unusedStylesheetSize += textLength;
unusedRules.push(rule.selectorText);
}
totalStylesheetSize += stylesheetSize;
totalUnusedStylesheetSize += unusedStylesheetSize;

if (!unusedRules.length)
continue;

var resource = WebInspector.resourceManager.resourceForURL(styleSheet.sourceURL);
var isInlineBlock = resource && resource.type == WebInspector.Resource.Type.Document;
var url = !isInlineBlock ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL) : String.sprintf("Inline block #%d", ++inlineBlockOrdinal);
var pctUnused = Math.round(100 * unusedStylesheetSize / stylesheetSize);
if (!summary)
summary = result.addChild("", true);
var entry = summary.addChild(String.sprintf("%s: %s (%d%%) is not used by the current page.", url, Number.bytesToString(unusedStylesheetSize), pctUnused));

for (var j = 0; j < unusedRules.length; ++j)
entry.addSnippet(unusedRules[j]);

result.violationCount += unusedRules.length;
}

if (!totalUnusedStylesheetSize)
return callback(null);

var totalUnusedPercent = Math.round(100 * totalUnusedStylesheetSize / totalStylesheetSize);
summary.value = String.sprintf("%s (%d%%) of CSS is not used by the current page.", Number.bytesToString(totalUnusedStylesheetSize), totalUnusedPercent);

callback(result);
}

function routine(selectorArray)
{
var result = {};
for (var i = 0; i < selectorArray.length; ++i) {
try {
if (document.querySelector(selectorArray[i]))
result[selectorArray[i]] = true;
} catch(e) {

}
}
return result;
}

WebInspector.AuditRules.evaluateInTargetWindow(routine, [selectors], selectorsCallback.bind(null, callback, styleSheets, testedSelectors));
}

function styleSheetCallback(styleSheets, continuation, styleSheet)
{
if (styleSheet)
styleSheets.push(styleSheet);
if (continuation)
continuation(styleSheets);
}

function allStylesCallback(styleSheetIds)
{
if (!styleSheetIds || !styleSheetIds.length)
return evalCallback([]);
var styleSheets = [];
for (var i = 0; i < styleSheetIds.length; ++i)
WebInspector.CSSStyleSheet.createForId(styleSheetIds[i], styleSheetCallback.bind(null, styleSheets, i == styleSheetIds.length - 1 ? evalCallback : null));
}

InspectorBackend.getAllStyles2(allStylesCallback);
}
}

WebInspector.AuditRules.UnusedCssRule.prototype.__proto__ = WebInspector.AuditRule.prototype;


WebInspector.AuditRules.CacheControlRule = function(id, name)
{
WebInspector.AuditRule.call(this, id, name);
}

WebInspector.AuditRules.CacheControlRule.MillisPerMonth = 1000 * 60 * 60 * 24 * 30;

WebInspector.AuditRules.CacheControlRule.prototype = {

doRun: function(resources, result, callback)
{
var cacheableAndNonCacheableResources = this._cacheableAndNonCacheableResources(resources);
if (cacheableAndNonCacheableResources[0].length)
this.runChecks(cacheableAndNonCacheableResources[0], result);
this.handleNonCacheableResources(cacheableAndNonCacheableResources[1], result);

callback(result);
},

handleNonCacheableResources: function()
{
},

_cacheableAndNonCacheableResources: function(resources)
{
var processedResources = [[], []];
for (var i = 0; i < resources.length; ++i) {
var resource = resources[i];
if (!this.isCacheableResource(resource))
continue;
if (this._isExplicitlyNonCacheable(resource))
processedResources[1].push(resource);
else
processedResources[0].push(resource);
}
return processedResources;
},

execCheck: function(messageText, resourceCheckFunction, resources, result)
{
var resourceCount = resources.length;
var urls = [];
for (var i = 0; i < resourceCount; ++i) {
if (resourceCheckFunction.call(this, resources[i]))
urls.push(resources[i].url);
}
if (urls.length) {
var entry = result.addChild(messageText, true);
entry.addURLs(urls);
result.violationCount += urls.length;
}
},

freshnessLifetimeGreaterThan: function(resource, timeMs)
{
var dateHeader = this.responseHeader(resource, "Date");
if (!dateHeader)
return false;

var dateHeaderMs = Date.parse(dateHeader);
if (isNaN(dateHeaderMs))
return false;

var freshnessLifetimeMs;
var maxAgeMatch = this.responseHeaderMatch(resource, "Cache-Control", "max-age=(\\d+)");

if (maxAgeMatch)
freshnessLifetimeMs = (maxAgeMatch[1]) ? 1000 * maxAgeMatch[1] : 0;
else {
var expiresHeader = this.responseHeader(resource, "Expires");
if (expiresHeader) {
var expDate = Date.parse(expiresHeader);
if (!isNaN(expDate))
freshnessLifetimeMs = expDate - dateHeaderMs;
}
}

return (isNaN(freshnessLifetimeMs)) ? false : freshnessLifetimeMs > timeMs;
},

responseHeader: function(resource, header)
{
return resource.responseHeaders[header];
},

hasResponseHeader: function(resource, header)
{
return resource.responseHeaders[header] !== undefined;
},

isCompressible: function(resource)
{
return WebInspector.Resource.Type.isTextType(resource.type);
},

isPubliclyCacheable: function(resource)
{
if (this._isExplicitlyNonCacheable(resource))
return false;

if (this.responseHeaderMatch(resource, "Cache-Control", "public"))
return true;

return resource.url.indexOf("?") == -1 && !this.responseHeaderMatch(resource, "Cache-Control", "private");
},

responseHeaderMatch: function(resource, header, regexp)
{
return resource.responseHeaders[header]
? resource.responseHeaders[header].match(new RegExp(regexp, "im"))
: undefined;
},

hasExplicitExpiration: function(resource)
{
return this.hasResponseHeader(resource, "Date") &&
(this.hasResponseHeader(resource, "Expires") || this.responseHeaderMatch(resource, "Cache-Control", "max-age"));
},

_isExplicitlyNonCacheable: function(resource)
{
var hasExplicitExp = this.hasExplicitExpiration(resource);
return this.responseHeaderMatch(resource, "Cache-Control", "(no-cache|no-store|must-revalidate)") ||
this.responseHeaderMatch(resource, "Pragma", "no-cache") ||
(hasExplicitExp && !this.freshnessLifetimeGreaterThan(resource, 0)) ||
(!hasExplicitExp && resource.url && resource.url.indexOf("?") >= 0) ||
(!hasExplicitExp && !this.isCacheableResource(resource));
},

isCacheableResource: function(resource)
{
return resource.statusCode !== undefined && WebInspector.AuditRules.CacheableResponseCodes[resource.statusCode];
}
}

WebInspector.AuditRules.CacheControlRule.prototype.__proto__ = WebInspector.AuditRule.prototype;


WebInspector.AuditRules.BrowserCacheControlRule = function()
{
WebInspector.AuditRules.CacheControlRule.call(this, "http-browsercache", "Leverage browser caching");
}

WebInspector.AuditRules.BrowserCacheControlRule.prototype = {
handleNonCacheableResources: function(resources, result)
{
if (resources.length) {
var entry = result.addChild("The following resources are explicitly non-cacheable. Consider making them cacheable if possible:", true);
result.violationCount += resources.length;
for (var i = 0; i < resources.length; ++i)
entry.addURL(resources[i].url);
}
},

runChecks: function(resources, result, callback)
{
this.execCheck("The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers:",
this._missingExpirationCheck, resources, result);
this.execCheck("The following resources specify a \"Vary\" header that disables caching in most versions of Internet Explorer:",
this._varyCheck, resources, result);
this.execCheck("The following cacheable resources have a short freshness lifetime:",
this._oneMonthExpirationCheck, resources, result);


this.execCheck("To further improve cache hit rate, specify an expiration one year in the future for the following cacheable resources:",
this._oneYearExpirationCheck, resources, result);
},

_missingExpirationCheck: function(resource)
{
return this.isCacheableResource(resource) && !this.hasResponseHeader(resource, "Set-Cookie") && !this.hasExplicitExpiration(resource);
},

_varyCheck: function(resource)
{
var varyHeader = this.responseHeader(resource, "Vary");
if (varyHeader) {
varyHeader = varyHeader.replace(/User-Agent/gi, "");
varyHeader = varyHeader.replace(/Accept-Encoding/gi, "");
varyHeader = varyHeader.replace(/[, ]*/g, "");
}
return varyHeader && varyHeader.length && this.isCacheableResource(resource) && this.freshnessLifetimeGreaterThan(resource, 0);
},

_oneMonthExpirationCheck: function(resource)
{
return this.isCacheableResource(resource) &&
!this.hasResponseHeader(resource, "Set-Cookie") &&
!this.freshnessLifetimeGreaterThan(resource, WebInspector.AuditRules.CacheControlRule.MillisPerMonth) &&
this.freshnessLifetimeGreaterThan(resource, 0);
},

_oneYearExpirationCheck: function(resource)
{
return this.isCacheableResource(resource) &&
!this.hasResponseHeader(resource, "Set-Cookie") &&
!this.freshnessLifetimeGreaterThan(resource, 11 * WebInspector.AuditRules.CacheControlRule.MillisPerMonth) &&
this.freshnessLifetimeGreaterThan(resource, WebInspector.AuditRules.CacheControlRule.MillisPerMonth);
}
}

WebInspector.AuditRules.BrowserCacheControlRule.prototype.__proto__ = WebInspector.AuditRules.CacheControlRule.prototype;


WebInspector.AuditRules.ProxyCacheControlRule = function() {
WebInspector.AuditRules.CacheControlRule.call(this, "http-proxycache", "Leverage proxy caching");
}

WebInspector.AuditRules.ProxyCacheControlRule.prototype = {
runChecks: function(resources, result, callback)
{
this.execCheck("Resources with a \"?\" in the URL are not cached by most proxy caching servers:",
this._questionMarkCheck, resources, result);
this.execCheck("Consider adding a \"Cache-Control: public\" header to the following resources:",
this._publicCachingCheck, resources, result);
this.execCheck("The following publicly cacheable resources contain a Set-Cookie header. This security vulnerability can cause cookies to be shared by multiple users.",
this._setCookieCacheableCheck, resources, result);
},

_questionMarkCheck: function(resource)
{
return resource.url.indexOf("?") >= 0 && !this.hasResponseHeader(resource, "Set-Cookie") && this.isPubliclyCacheable(resource);
},

_publicCachingCheck: function(resource)
{
return this.isCacheableResource(resource) &&
!this.isCompressible(resource) &&
!this.responseHeaderMatch(resource, "Cache-Control", "public") &&
!this.hasResponseHeader(resource, "Set-Cookie");
},

_setCookieCacheableCheck: function(resource)
{
return this.hasResponseHeader(resource, "Set-Cookie") && this.isPubliclyCacheable(resource);
}
}

WebInspector.AuditRules.ProxyCacheControlRule.prototype.__proto__ = WebInspector.AuditRules.CacheControlRule.prototype;


WebInspector.AuditRules.ImageDimensionsRule = function()
{
WebInspector.AuditRule.call(this, "page-imagedims", "Specify image dimensions");
}

WebInspector.AuditRules.ImageDimensionsRule.prototype = {
doRun: function(resources, result, callback)
{
function doneCallback(context)
{
var map = context.urlToNoDimensionCount;
for (var url in map) {
var entry = entry || result.addChild("A width and height should be specified for all images in order to speed up page display. The following image(s) are missing a width and/or height:", true);
var value = WebInspector.AuditRuleResult.linkifyDisplayName(url);
if (map[url] > 1)
value += String.sprintf(" (%d uses)", map[url]);
entry.addChild(value);
result.violationCount++;
}
callback(entry ? result : null);
}

function imageStylesReady(imageId, context, styles)
{
--context.imagesLeft;

const node = WebInspector.domAgent.nodeForId(imageId);
var src = node.getAttribute("src");
if (!src.asParsedURL()) {
for (var frameOwnerCandidate = node; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
if (frameOwnerCandidate.documentURL) {
var completeSrc = WebInspector.completeURL(frameOwnerCandidate.documentURL, src);
break;
}
}
}
if (completeSrc)
src = completeSrc;

const computedStyle = styles.computedStyle;
if (computedStyle.getPropertyValue("position") === "absolute") {
if (!context.imagesLeft)
doneCallback(context);
return;
}

var widthFound = "width" in styles.styleAttributes;
var heightFound = "height" in styles.styleAttributes;

for (var i = styles.matchedCSSRules.length - 1; i >= 0 && !(widthFound && heightFound); --i) {
var style = styles.matchedCSSRules[i].style;
if (style.getPropertyValue("width") !== "")
widthFound = true;
if (style.getPropertyValue("height") !== "")
heightFound = true;
}

if (!widthFound || !heightFound) {
if (src in context.urlToNoDimensionCount)
++context.urlToNoDimensionCount[src];
else
context.urlToNoDimensionCount[src] = 1;
}

if (!context.imagesLeft)
doneCallback(context);
}

function receivedImages(imageIds)
{
if (!imageIds || !imageIds.length)
return callback(null);
var context = {imagesLeft: imageIds.length, urlToNoDimensionCount: {}};
for (var i = imageIds.length - 1; i >= 0; --i)
WebInspector.cssModel.getStylesAsync(imageIds[i], imageStylesReady.bind(this, imageIds[i], context));
}

function pushImageNodes()
{
const nodeIds = [];
var nodes = document.getElementsByTagName("img");
for (var i = 0; i < nodes.length; ++i) {
if (!nodes[i].src)
continue;
var nodeId = this.getNodeId(nodes[i]);
nodeIds.push(nodeId);
}
return nodeIds;
}

WebInspector.AuditRules.evaluateInTargetWindow(pushImageNodes, null, receivedImages);
}
}

WebInspector.AuditRules.ImageDimensionsRule.prototype.__proto__ = WebInspector.AuditRule.prototype;


WebInspector.AuditRules.CssInHeadRule = function()
{
WebInspector.AuditRule.call(this, "page-cssinhead", "Put CSS in the document head");
}

WebInspector.AuditRules.CssInHeadRule.prototype = {
doRun: function(resources, result, callback)
{
function evalCallback(evalResult)
{
if (!evalResult)
return callback(null);

var summary = result.addChild("");

var outputMessages = [];
for (var url in evalResult) {
var urlViolations = evalResult[url];
if (urlViolations[0]) {
result.addChild(String.sprintf("%s style block(s) in the %s body should be moved to the document head.", urlViolations[0], WebInspector.AuditRuleResult.linkifyDisplayName(url)));
result.violationCount += urlViolations[0];
}
for (var i = 0; i < urlViolations[1].length; ++i)
result.addChild(String.sprintf("Link node %s should be moved to the document head in %s", WebInspector.AuditRuleResult.linkifyDisplayName(urlViolations[1][i]), WebInspector.AuditRuleResult.linkifyDisplayName(url)));
result.violationCount += urlViolations[1].length;
}
summary.value = String.sprintf("CSS in the document body adversely impacts rendering performance.");
callback(result);
}

function routine()
{
function allViews() {
var views = [document.defaultView];
var curView = 0;
while (curView < views.length) {
var view = views[curView];
var frames = view.frames;
for (var i = 0; i < frames.length; ++i) {
if (frames[i] !== view)
views.push(frames[i]);
}
++curView;
}
return views;
}

var views = allViews();
var urlToViolationsArray = {};
var found = false;
for (var i = 0; i < views.length; ++i) {
var view = views[i];
if (!view.document)
continue;

var inlineStyles = view.document.querySelectorAll("body style");
var inlineStylesheets = view.document.querySelectorAll("body link[rel~='stylesheet'][href]");
if (!inlineStyles.length && !inlineStylesheets.length)
continue;

found = true;
var inlineStylesheetHrefs = [];
for (var j = 0; j < inlineStylesheets.length; ++j)
inlineStylesheetHrefs.push(inlineStylesheets[j].href);
urlToViolationsArray[view.location.href] = [inlineStyles.length, inlineStylesheetHrefs];
}
return found ? urlToViolationsArray : null;
}

WebInspector.AuditRules.evaluateInTargetWindow(routine, null, evalCallback);
}
}

WebInspector.AuditRules.CssInHeadRule.prototype.__proto__ = WebInspector.AuditRule.prototype;


WebInspector.AuditRules.StylesScriptsOrderRule = function()
{
WebInspector.AuditRule.call(this, "page-stylescriptorder", "Optimize the order of styles and scripts");
}

WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
doRun: function(resources, result, callback)
{
function evalCallback(resultValue)
{
if (!resultValue)
return callback(null);

var lateCssUrls = resultValue[0];
var cssBeforeInlineCount = resultValue[1];

var entry = result.addChild("The following external CSS files were included after an external JavaScript file in the document head. To ensure CSS files are downloaded in parallel, always include external CSS before external JavaScript.", true);
entry.addURLs(lateCssUrls);
result.violationCount += lateCssUrls.length;

if (cssBeforeInlineCount) {
result.addChild(String.sprintf(" %d inline script block%s found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline script before the external CSS file, or after the next resource.", cssBeforeInlineCount, cssBeforeInlineCount > 1 ? "s were" : " was"));
result.violationCount += cssBeforeInlineCount;
}
callback(result);
}

function routine()
{
var lateStyles = document.querySelectorAll("head script[src] ~ link[rel~='stylesheet'][href]");
var cssBeforeInlineCount = document.querySelectorAll("head link[rel~='stylesheet'][href] ~ script:not([src])").length;
if (!lateStyles.length && !cssBeforeInlineCount)
return null;

var lateStyleUrls = [];
for (var i = 0; i < lateStyles.length; ++i)
lateStyleUrls.push(lateStyles[i].href);
return [ lateStyleUrls, cssBeforeInlineCount ];
}

WebInspector.AuditRules.evaluateInTargetWindow(routine, null, evalCallback.bind(this));
}
}

WebInspector.AuditRules.StylesScriptsOrderRule.prototype.__proto__ = WebInspector.AuditRule.prototype;


WebInspector.AuditRules.CookieRuleBase = function(id, name)
{
WebInspector.AuditRule.call(this, id, name);
}

WebInspector.AuditRules.CookieRuleBase.prototype = {
doRun: function(resources, result, callback)
{
var self = this;
function resultCallback(receivedCookies, isAdvanced) {
self.processCookies(isAdvanced ? receivedCookies : [], resources, result);
callback(result);
}
WebInspector.Cookies.getCookiesAsync(resultCallback);
},

mapResourceCookies: function(resourcesByDomain, allCookies, callback)
{
for (var i = 0; i < allCookies.length; ++i) {
for (var resourceDomain in resourcesByDomain) {
if (WebInspector.Cookies.cookieDomainMatchesResourceDomain(allCookies[i].domain, resourceDomain))
this._callbackForResourceCookiePairs(resourcesByDomain[resourceDomain], allCookies[i], callback);
}
}
},

_callbackForResourceCookiePairs: function(resources, cookie, callback)
{
if (!resources)
return;
for (var i = 0; i < resources.length; ++i) {
if (WebInspector.Cookies.cookieMatchesResourceURL(cookie, resources[i].url))
callback(resources[i], cookie);
}
}
}

WebInspector.AuditRules.CookieRuleBase.prototype.__proto__ = WebInspector.AuditRule.prototype;


WebInspector.AuditRules.CookieSizeRule = function(avgBytesThreshold)
{
WebInspector.AuditRules.CookieRuleBase.call(this, "http-cookiesize", "Minimize cookie size");
this._avgBytesThreshold = avgBytesThreshold;
this._maxBytesThreshold = 1000;
}

WebInspector.AuditRules.CookieSizeRule.prototype = {
_average: function(cookieArray)
{
var total = 0;
for (var i = 0; i < cookieArray.length; ++i)
total += cookieArray[i].size;
return cookieArray.length ? Math.round(total / cookieArray.length) : 0;
},

_max: function(cookieArray)
{
var result = 0;
for (var i = 0; i < cookieArray.length; ++i)
result = Math.max(cookieArray[i].size, result);
return result;
},

processCookies: function(allCookies, resources, result)
{
function maxSizeSorter(a, b)
{
return b.maxCookieSize - a.maxCookieSize;
}

function avgSizeSorter(a, b)
{
return b.avgCookieSize - a.avgCookieSize;
}

var cookiesPerResourceDomain = {};

function collectorCallback(resource, cookie)
{
var cookies = cookiesPerResourceDomain[resource.domain];
if (!cookies) {
cookies = [];
cookiesPerResourceDomain[resource.domain] = cookies;
}
cookies.push(cookie);
}

if (!allCookies.length)
return;

var sortedCookieSizes = [];

var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(resources,
null,
true);
var matchingResourceData = {};
this.mapResourceCookies(domainToResourcesMap, allCookies, collectorCallback.bind(this));

for (var resourceDomain in cookiesPerResourceDomain) {
var cookies = cookiesPerResourceDomain[resourceDomain];
sortedCookieSizes.push({
domain: resourceDomain,
avgCookieSize: this._average(cookies),
maxCookieSize: this._max(cookies)
});
}
var avgAllCookiesSize = this._average(allCookies);

var hugeCookieDomains = [];
sortedCookieSizes.sort(maxSizeSorter);

for (var i = 0, len = sortedCookieSizes.length; i < len; ++i) {
var maxCookieSize = sortedCookieSizes[i].maxCookieSize;
if (maxCookieSize > this._maxBytesThreshold)
hugeCookieDomains.push(WebInspector.AuditRuleResult.resourceDomain(sortedCookieSizes[i].domain) + ": " + Number.bytesToString(maxCookieSize, WebInspector.UIString));
}

var bigAvgCookieDomains = [];
sortedCookieSizes.sort(avgSizeSorter);
for (var i = 0, len = sortedCookieSizes.length; i < len; ++i) {
var domain = sortedCookieSizes[i].domain;
var avgCookieSize = sortedCookieSizes[i].avgCookieSize;
if (avgCookieSize > this._avgBytesThreshold && avgCookieSize < this._maxBytesThreshold)
bigAvgCookieDomains.push(WebInspector.AuditRuleResult.resourceDomain(domain) + ": " + Number.bytesToString(avgCookieSize, WebInspector.UIString));
}
result.addChild(String.sprintf("The average cookie size for all requests on this page is %s", Number.bytesToString(avgAllCookiesSize, WebInspector.UIString)));

var message;
if (hugeCookieDomains.length) {
var entry = result.addChild("The following domains have a cookie size in excess of 1KB. This is harmful because requests with cookies larger than 1KB typically cannot fit into a single network packet.", true);
entry.addURLs(hugeCookieDomains);
result.violationCount += hugeCookieDomains.length;
}

if (bigAvgCookieDomains.length) {
var entry = result.addChild(String.sprintf("The following domains have an average cookie size in excess of %d bytes. Reducing the size of cookies for these domains can reduce the time it takes to send requests.", this._avgBytesThreshold), true);
entry.addURLs(bigAvgCookieDomains);
result.violationCount += bigAvgCookieDomains.length;
}
}
}

WebInspector.AuditRules.CookieSizeRule.prototype.__proto__ = WebInspector.AuditRules.CookieRuleBase.prototype;


WebInspector.AuditRules.StaticCookielessRule = function(minResources)
{
WebInspector.AuditRules.CookieRuleBase.call(this, "http-staticcookieless", "Serve static content from a cookieless domain");
this._minResources = minResources;
}

WebInspector.AuditRules.StaticCookielessRule.prototype = {
processCookies: function(allCookies, resources, result)
{
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(resources,
[WebInspector.Resource.Type.Stylesheet,
WebInspector.Resource.Type.Image],
true);
var totalStaticResources = 0;
for (var domain in domainToResourcesMap)
totalStaticResources += domainToResourcesMap[domain].length;
if (totalStaticResources < this._minResources)
return;
var matchingResourceData = {};
this.mapResourceCookies(domainToResourcesMap, allCookies, this._collectorCallback.bind(this, matchingResourceData));

var badUrls = [];
var cookieBytes = 0;
for (var url in matchingResourceData) {
badUrls.push(url);
cookieBytes += matchingResourceData[url]
}
if (badUrls.length < this._minResources)
return;

var entry = result.addChild(String.sprintf("%s of cookies were sent with the following static resources. Serve these static resources from a domain that does not set cookies:", Number.bytesToString(cookieBytes, WebInspector.UIString)), true);
entry.addURLs(badUrls);
result.violationCount = badUrls.length;
},

_collectorCallback: function(matchingResourceData, resource, cookie)
{
matchingResourceData[resource.url] = (matchingResourceData[resource.url] || 0) + cookie.size;
}
}

WebInspector.AuditRules.StaticCookielessRule.prototype.__proto__ = WebInspector.AuditRules.CookieRuleBase.prototype;





WebInspector.AuditCategories.PagePerformance = function() {
WebInspector.AuditCategory.call(this, WebInspector.AuditCategories.PagePerformance.AuditCategoryName);
}

WebInspector.AuditCategories.PagePerformance.AuditCategoryName = "Web Page Performance";

WebInspector.AuditCategories.PagePerformance.prototype = {
initialize: function()
{
this.addRule(new WebInspector.AuditRules.UnusedCssRule(), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.CssInHeadRule(), WebInspector.AuditRule.Severity.Severe);
this.addRule(new WebInspector.AuditRules.StylesScriptsOrderRule(), WebInspector.AuditRule.Severity.Severe);
}
}

WebInspector.AuditCategories.PagePerformance.prototype.__proto__ = WebInspector.AuditCategory.prototype;

WebInspector.AuditCategories.NetworkUtilization = function() {
WebInspector.AuditCategory.call(this, WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName);
}

WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName = "Network Utilization";

WebInspector.AuditCategories.NetworkUtilization.prototype = {
initialize: function()
{
this.addRule(new WebInspector.AuditRules.GzipRule(), WebInspector.AuditRule.Severity.Severe);
this.addRule(new WebInspector.AuditRules.ImageDimensionsRule(), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.CookieSizeRule(400), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.StaticCookielessRule(5), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.CombineJsResourcesRule(2), WebInspector.AuditRule.Severity.Severe);
this.addRule(new WebInspector.AuditRules.CombineCssResourcesRule(2), WebInspector.AuditRule.Severity.Severe);
this.addRule(new WebInspector.AuditRules.MinimizeDnsLookupsRule(4), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.ParallelizeDownloadRule(4, 10, 0.5), WebInspector.AuditRule.Severity.Warning);
this.addRule(new WebInspector.AuditRules.BrowserCacheControlRule(), WebInspector.AuditRule.Severity.Severe);
this.addRule(new WebInspector.AuditRules.ProxyCacheControlRule(), WebInspector.AuditRule.Severity.Warning);
}
}

WebInspector.AuditCategories.NetworkUtilization.prototype.__proto__ = WebInspector.AuditCategory.prototype;





WebInspector.applyFormatters = function(value)
{
var formatter;
var type = typeof value;
var args;

switch (type) {
case "string":
case "boolean":
case "number":
formatter = WebInspector.AuditFormatters.text;
args = [ value.toString() ];
break;

case "object":
if (value instanceof Array) {
formatter = WebInspector.AuditFormatters.concat;
args = value;
} else if (value.type && value.arguments) {
formatter = WebInspector.AuditFormatters[value.type];
args = value.arguments;
}
}
if (!formatter)
throw "Invalid value or formatter: " + type + JSON.stringify(value);

return formatter.apply(null, args);
}

WebInspector.AuditFormatters = {
text: function(text)
{
return document.createTextNode(text);
},

snippet: function(snippetText)
{
var div = document.createElement("div");
div.innerText = snippetText;
div.className = "source-code";
return div;
},

concat: function()
{
var parent = document.createElement("span");
for (var arg = 0; arg < arguments.length; ++arg)
parent.appendChild(WebInspector.applyFormatters(arguments[arg]));
return parent;
},

url: function(url, displayText, allowExternalNavigation)
{
var a = document.createElement("a");
a.href = url;
a.title = url;
a.textContent = displayText || url;
if (allowExternalNavigation)
a.target = "_blank";
return a;
}
};





WebInspector.ResourceHeadersView = function(resource)
{
WebInspector.View.call(this);
this.element.addStyleClass("resource-headers-view");

this._resource = resource;

this._headersListElement = document.createElement("ol");
this._headersListElement.className = "outline-disclosure";
this.element.appendChild(this._headersListElement);

this._headersTreeOutline = new TreeOutline(this._headersListElement);
this._headersTreeOutline.expandTreeElementsWhenArrowing = true;

this._urlTreeElement = new TreeElement("", null, false);
this._urlTreeElement.selectable = false;
this._headersTreeOutline.appendChild(this._urlTreeElement);

this._requestMethodTreeElement = new TreeElement("", null, false);
this._requestMethodTreeElement.selectable = false;
this._headersTreeOutline.appendChild(this._requestMethodTreeElement);

this._statusCodeTreeElement = new TreeElement("", null, false);
this._statusCodeTreeElement.selectable = false;
this._headersTreeOutline.appendChild(this._statusCodeTreeElement);

this._requestHeadersTreeElement = new TreeElement("", null, true);
this._requestHeadersTreeElement.expanded = true;
this._requestHeadersTreeElement.selectable = false;
this._headersTreeOutline.appendChild(this._requestHeadersTreeElement);

this._decodeHover = WebInspector.UIString("Double-Click to toggle between URL encoded and decoded formats");
this._decodeRequestParameters = true;

this._queryStringTreeElement = new TreeElement("", null, true);
this._queryStringTreeElement.expanded = true;
this._queryStringTreeElement.selectable = false;
this._queryStringTreeElement.hidden = true;
this._headersTreeOutline.appendChild(this._queryStringTreeElement);

this._formDataTreeElement = new TreeElement("", null, true);
this._formDataTreeElement.expanded = true;
this._formDataTreeElement.selectable = false;
this._formDataTreeElement.hidden = true;
this._headersTreeOutline.appendChild(this._formDataTreeElement);

this._requestPayloadTreeElement = new TreeElement(WebInspector.UIString("Request Payload"), null, true);
this._requestPayloadTreeElement.expanded = true;
this._requestPayloadTreeElement.selectable = false;
this._requestPayloadTreeElement.hidden = true;
this._headersTreeOutline.appendChild(this._requestPayloadTreeElement);

this._responseHeadersTreeElement = new TreeElement("", null, true);
this._responseHeadersTreeElement.expanded = true;
this._responseHeadersTreeElement.selectable = false;
this._headersTreeOutline.appendChild(this._responseHeadersTreeElement);

resource.addEventListener("requestHeaders changed", this._refreshRequestHeaders, this);
resource.addEventListener("responseHeaders changed", this._refreshResponseHeaders, this);
resource.addEventListener("finished", this._refreshHTTPInformation, this);

this._refreshURL();
this._refreshQueryString();
this._refreshRequestHeaders();
this._refreshResponseHeaders();
this._refreshHTTPInformation();
}

WebInspector.ResourceHeadersView.prototype = {

_refreshURL: function()
{
this._urlTreeElement.titleHTML = "<div class=\"header-name\">" + WebInspector.UIString("Request URL") + ":</div>" +
"<div class=\"header-value source-code\">" + this._resource.url.escapeHTML() + "</div>";
},

_refreshQueryString: function()
{
var queryParameters = this._resource.queryParameters;
this._queryStringTreeElement.hidden = !queryParameters;
if (queryParameters)
this._refreshParms(WebInspector.UIString("Query String Parameters"), queryParameters, this._queryStringTreeElement);
},

_refreshFormData: function()
{
this._formDataTreeElement.hidden = true;
this._requestPayloadTreeElement.hidden = true;

var formData = this._resource.requestFormData;
if (!formData)
return;

var formParameters = this._resource.formParameters;
if (formParameters) {
this._formDataTreeElement.hidden = false;
this._refreshParms(WebInspector.UIString("Form Data"), formParameters, this._formDataTreeElement);
} else {
this._requestPayloadTreeElement.hidden = false;
this._refreshRequestPayload(formData);
}
},

_refreshRequestPayload: function(formData)
{
this._requestPayloadTreeElement.removeChildren();

var title = "<div class=\"raw-form-data header-value source-code\">" + formData.escapeHTML() + "</div>";
var parmTreeElement = new TreeElement(null, null, false);
parmTreeElement.titleHTML = title;
parmTreeElement.selectable = false;
this._requestPayloadTreeElement.appendChild(parmTreeElement);
},

_refreshParms: function(title, parms, parmsTreeElement)
{
parmsTreeElement.removeChildren();

parmsTreeElement.titleHTML = title + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", parms.length) + "</span>";

for (var i = 0; i < parms.length; ++i) {
var name = parms[i].name;
var value = parms[i].value;

var errorDecoding = false;
if (this._decodeRequestParameters) {
if (value.indexOf("%") >= 0) {
try {
value = decodeURIComponent(value);
} catch(e) {
errorDecoding = true;
}
}

value = value.replace(/\+/g, " ");
}

valueEscaped = value.escapeHTML();
if (errorDecoding)
valueEscaped += " <span class=\"error-message\">" + WebInspector.UIString("(unable to decode value)").escapeHTML() + "</span>";

var title = "<div class=\"header-name\">" + name.escapeHTML() + ":</div>";
title += "<div class=\"header-value source-code\">" + valueEscaped + "</div>";

var parmTreeElement = new TreeElement(null, null, false);
parmTreeElement.titleHTML = title;
parmTreeElement.selectable = false;
parmTreeElement.tooltip = this._decodeHover;
parmTreeElement.ondblclick = this._toggleURLdecoding.bind(this);
parmsTreeElement.appendChild(parmTreeElement);
}
},

_toggleURLdecoding: function(event)
{
this._decodeRequestParameters = !this._decodeRequestParameters;
this._refreshQueryString();
this._refreshFormData();
},

_getHeaderValue: function(headers, key)
{
var lowerKey = key.toLowerCase();
for (var testKey in headers) {
if (testKey.toLowerCase() === lowerKey)
return headers[testKey];
}
},

_refreshRequestHeaders: function()
{
var additionalRow = null;
if (typeof this._resource.webSocketRequestKey3 !== "undefined")
additionalRow = {header: "(Key3)", value: this._resource.webSocketRequestKey3};
this._refreshHeaders(WebInspector.UIString("Request Headers"), this._resource.sortedRequestHeaders, additionalRow, this._requestHeadersTreeElement);
this._refreshFormData();
},

_refreshResponseHeaders: function()
{
var additionalRow = null;
if (typeof this._resource.webSocketChallengeResponse !== "undefined")
additionalRow = {header: "(Challenge Response)", value: this._resource.webSocketChallengeResponse};
this._refreshHeaders(WebInspector.UIString("Response Headers"), this._resource.sortedResponseHeaders, additionalRow, this._responseHeadersTreeElement);
},

_refreshHTTPInformation: function()
{
var requestMethodElement = this._requestMethodTreeElement;
requestMethodElement.hidden = !this._resource.statusCode;
var statusCodeElement = this._statusCodeTreeElement;
statusCodeElement.hidden = !this._resource.statusCode;
var statusCodeImage = "";

if (this._resource.statusCode) {
var statusImageSource = "";
if (this._resource.statusCode < 300)
statusImageSource = "Images/successGreenDot.png";
else if (this._resource.statusCode < 400)
statusImageSource = "Images/warningOrangeDot.png";
else
statusImageSource = "Images/errorRedDot.png";

var statusTextEscaped = this._resource.statusCode + " " + this._resource.statusText.escapeHTML();
statusCodeImage = "<img class=\"resource-status-image\" src=\"" + statusImageSource + "\" title=\"" + statusTextEscaped + "\">";

requestMethodElement.titleHTML = "<div class=\"header-name\">" + WebInspector.UIString("Request Method") + ":</div>" +
"<div class=\"header-value source-code\">" + this._resource.requestMethod + "</div>";

statusCodeElement.titleHTML = "<div class=\"header-name\">" + WebInspector.UIString("Status Code") + ":</div>" +
statusCodeImage + "<div class=\"header-value source-code\">" + statusTextEscaped + "</div>";
}
},

_refreshHeaders: function(title, headers, additionalRow, headersTreeElement)
{
headersTreeElement.removeChildren();

var length = headers.length;
headersTreeElement.titleHTML = title.escapeHTML() + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", length) + "</span>";
headersTreeElement.hidden = !length;

var length = headers.length;
for (var i = 0; i < length; ++i) {
var title = "<div class=\"header-name\">" + headers[i].header.escapeHTML() + ":</div>";
title += "<div class=\"header-value source-code\">" + headers[i].value.escapeHTML() + "</div>"

var headerTreeElement = new TreeElement(null, null, false);
headerTreeElement.titleHTML = title;
headerTreeElement.selectable = false;
headersTreeElement.appendChild(headerTreeElement);
}

if (additionalRow) {
var title = "<div class=\"header-name\">" + additionalRow.header.escapeHTML() + ":</div>";
title += "<div class=\"header-value source-code\">" + additionalRow.value.escapeHTML() + "</div>"

var headerTreeElement = new TreeElement(null, null, false);
headerTreeElement.titleHTML = title;
headerTreeElement.selectable = false;
headersTreeElement.appendChild(headerTreeElement);
}
}
}

WebInspector.ResourceHeadersView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.ResourceCookiesView = function(resource)
{
WebInspector.View.call(this);
this.element.addStyleClass("resource-cookies-view");

this._resource = resource;

resource.addEventListener("requestHeaders changed", this.show, this);
resource.addEventListener("responseHeaders changed", this.show, this);
}

WebInspector.ResourceCookiesView.prototype = {
show: function(parentElement)
{
if (!this._resource.requestCookies && !this._resource.responseCookies) {
if (!this._emptyMsgElement) {
this._emptyMsgElement = document.createElement("div");
this._emptyMsgElement.className = "storage-empty-view";
this._emptyMsgElement.textContent = WebInspector.UIString("This request has no cookies.");
this.element.appendChild(this._emptyMsgElement);
}
WebInspector.View.prototype.show.call(this, parentElement);
return;
}

if (this._emptyMsgElement)
this._emptyMsgElement.parentElement.removeChild(this._emptyMsgElement);

this._cookiesTable = new WebInspector.CookiesTable(null, true, true);
this._cookiesTable.addCookiesFolder(WebInspector.UIString("Request Cookies"), this._resource.requestCookies);
this._cookiesTable.addCookiesFolder(WebInspector.UIString("Response Cookies"), this._resource.responseCookies);
this.element.appendChild(this._cookiesTable.element);

WebInspector.View.prototype.show.call(this, parentElement);
this._cookiesTable.updateWidths();
}
}

WebInspector.ResourceCookiesView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.ResourceTimingView = function(resource)
{
WebInspector.View.call(this);
this.element.addStyleClass("resource-timing-view");

this._resource = resource;

resource.addEventListener("timing changed", this._refresh, this);
}

WebInspector.ResourceTimingView.prototype = {
show: function(parentElement)
{
if (!this._resource.timing) {
if (!this._emptyMsgElement) {
this._emptyMsgElement = document.createElement("div");
this._emptyMsgElement.className = "storage-empty-view";
this._emptyMsgElement.textContent = WebInspector.UIString("This request has no detailed timing info.");
this.element.appendChild(this._emptyMsgElement);
}
WebInspector.View.prototype.show.call(this, parentElement);
return;
}

if (this._emptyMsgElement)
this._emptyMsgElement.parentElement.removeChild(this._emptyMsgElement);

this._refresh();
WebInspector.View.prototype.show.call(this, parentElement);
},

_refresh: function()
{
if (this._tableElement)
this._tableElement.parentElement.removeChild(this._tableElement);

this._tableElement = WebInspector.ResourceTimingView.createTimingTable(this._resource);
this.element.appendChild(this._tableElement);
}
}

WebInspector.ResourceTimingView.createTimingTable = function(resource)
{
var tableElement = document.createElement("table");
var rows = [];

function addRow(title, className, start, end, color)
{
var row = {};
row.title = title;
row.className = className;
row.start = start;
row.end = end;
rows.push(row);
}

if (resource.timing.proxyStart !== -1)
addRow(WebInspector.UIString("Proxy"), "proxy", resource.timing.proxyStart, resource.timing.proxyEnd);

if (resource.timing.dnsStart !== -1)
addRow(WebInspector.UIString("DNS Lookup"), "dns", resource.timing.dnsStart, resource.timing.dnsEnd);

if (resource.timing.connectStart !== -1) {
if (resource.connectionReused)
addRow(WebInspector.UIString("Blocking"), "connecting", resource.timing.connectStart, resource.timing.connectEnd);
else {
var connectStart = resource.timing.connectStart;

if (resource.timing.dnsStart !== -1)
connectStart += resource.timing.dnsEnd - resource.timing.dnsStart;
addRow(WebInspector.UIString("Connecting"), "connecting", connectStart, resource.timing.connectEnd);
}
}

if (resource.timing.sslStart !== -1)
addRow(WebInspector.UIString("SSL"), "ssl", resource.timing.sslStart, resource.timing.sslEnd);

var sendStart = resource.timing.sendStart;
if (resource.timing.sslStart !== -1)
sendStart += resource.timing.sslEnd - resource.timing.sslStart;

addRow(WebInspector.UIString("Sending"), "sending", resource.timing.sendStart, resource.timing.sendEnd);
addRow(WebInspector.UIString("Waiting"), "waiting", resource.timing.sendEnd, resource.timing.receiveHeadersEnd);
addRow(WebInspector.UIString("Receiving"), "receiving", (resource.responseReceivedTime - resource.timing.requestTime) * 1000, (resource.endTime - resource.timing.requestTime) * 1000);

const chartWidth = 200;
var total = (resource.endTime - resource.timing.requestTime) * 1000;
var scale = chartWidth / total;

for (var i = 0; i < rows.length; ++i) {
var tr = document.createElement("tr");
tableElement.appendChild(tr);

var td = document.createElement("td");
td.textContent = rows[i].title;
tr.appendChild(td);

td = document.createElement("td");
td.width = chartWidth + "px";

var row = document.createElement("div");
row.className = "network-timing-row";
td.appendChild(row);

var bar = document.createElement("span");
bar.className = "network-timing-bar " + rows[i].className;
bar.style.left = scale * rows[i].start + "px";
bar.style.right = scale * (total - rows[i].end) + "px";
bar.style.backgroundColor = rows[i].color;
bar.textContent = "\u200B"; 
row.appendChild(bar);

var title = document.createElement("span");
title.className = "network-timing-bar-title";
if (total - rows[i].end < rows[i].start)
title.style.right = (scale * (total - rows[i].end) + 3) + "px";
else
title.style.left = (scale * rows[i].start + 3) + "px";
title.textContent = Number.millisToString(rows[i].end - rows[i].start);
row.appendChild(title);

tr.appendChild(td);
}
return tableElement;
}

WebInspector.ResourceTimingView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.NetworkItemView = function(resource)
{
WebInspector.View.call(this);

this.element.addStyleClass("network-item-view");

this._headersView = new WebInspector.ResourceHeadersView(resource);

var contentView = WebInspector.ResourceManager.resourceViewForResource(resource);
this._cookiesView = new WebInspector.ResourceCookiesView(resource);

this._tabbedPane = new WebInspector.TabbedPane(this.element);
this._tabbedPane.appendTab("headers", WebInspector.UIString("Headers"), this._headersView);
if (contentView.hasContent()) {

contentView.visible = false;
this._tabbedPane.appendTab("content", WebInspector.UIString("Content"), contentView);
}
this._tabbedPane.appendTab("cookies", WebInspector.UIString("Cookies"), this._cookiesView);

if (Preferences.showTimingTab) {
var timingView = new WebInspector.ResourceTimingView(resource);
this._tabbedPane.appendTab("timing", WebInspector.UIString("Timing"), timingView);
}

this._tabbedPane.addEventListener("tab-selected", this._tabSelected, this);
}

WebInspector.NetworkItemView.prototype = {
show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);
this._selectTab();
},

_selectTab: function(tabId)
{
if (!tabId)
tabId = WebInspector.settings.resourceViewTab;

if (!this._tabbedPane.selectTab(tabId)) {
this._isInFallbackSelection = true;
this._tabbedPane.selectTab("headers");
delete this._isInFallbackSelection;
}
},

_tabSelected: function(event)
{
WebInspector.settings.resourceViewTab = event.data.tabId;
},

resize: function()
{
if (this._cookiesView.visible)
this._cookiesView.resize();
}
}

WebInspector.NetworkItemView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.ResourceView = function(resource)
{
WebInspector.View.call(this);
this.element.addStyleClass("resource-view");
this.resource = resource;
}

WebInspector.ResourceView.prototype = {
hasContent: function()
{
return false;
}
}

WebInspector.ResourceView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, editDelegate, continueToHereDelegate)
{
this._parentElement = parentElement;

this._textModel = new WebInspector.TextEditorModel();
this._textModel.replaceTabsWithSpaces = true;

this._messages = [];
this._rowMessages = {};
this._messageBubbles = {};
this.breakpoints = [];

this._loaded = false;

this._continueToHereDelegate = continueToHereDelegate;
this._addBreakpointDelegate = addBreakpointDelegate;
this._editDelegate = editDelegate;
this._popoverObjectGroup = "popover";
}

WebInspector.SourceFrame.prototype = {

set visible(visible)
{
this._visible = visible;
this._createViewerIfNeeded();

if (visible) {
if (this._textViewer && this._scrollTop)
this._textViewer.element.scrollTop = this._scrollTop;
if (this._textViewer && this._scrollLeft)
this._textViewer.element.scrollLeft = this._scrollLeft;
} else {
this._hidePopup();
if (this._textViewer) {
this._scrollTop = this._textViewer.element.scrollTop;
this._scrollLeft = this._textViewer.element.scrollLeft;
this._textViewer.freeCachedElements();
}
}
},

get executionLine()
{
return this._executionLine;
},

set executionLine(x)
{
if (this._executionLine === x)
return;

var previousLine = this._executionLine;
this._executionLine = x;

if (this._textViewer)
this._updateExecutionLine(previousLine);
},

markDiff: function(diffData)
{
if (this._diffLines && this._textViewer)
this._removeDiffDecorations();

this._diffLines = diffData;
if (this._textViewer)
this._updateDiffDecorations();
},

revealLine: function(lineNumber)
{
if (this._textViewer)
this._textViewer.revealLine(lineNumber - 1, 0);
else
this._lineNumberToReveal = lineNumber;
},

addBreakpoint: function(breakpoint)
{
this.breakpoints.push(breakpoint);
breakpoint.addEventListener("removed", this._breakpointRemoved, this);
if (this._textViewer)
this._addBreakpointToSource(breakpoint);
},

_breakpointRemoved: function(event)
{
var breakpoint = event.target;

this.breakpoints.remove(breakpoint);
if (this._textViewer)
this._removeBreakpointFromSource(breakpoint);
},

addMessage: function(msg)
{

if (!msg.message || msg.line <= 0 || !msg.isErrorOrWarning())
return;
this._messages.push(msg)
if (this._textViewer)
this._addMessageToSource(msg);
},

addScript: function(script)
{
this._scripts[script.sourceID] = script;
},

clearMessages: function()
{
for (var line in this._messageBubbles) {
var bubble = this._messageBubbles[line];
bubble.parentNode.removeChild(bubble);
}

this._messages = [];
this._rowMessages = {};
this._messageBubbles = {};
if (this._textViewer)
this._textViewer.resize();
},

sizeToFitContentHeight: function()
{
if (this._textViewer)
this._textViewer.revalidateDecorationsAndPaint();
},

setContent: function(mimeType, content, url)
{
this._loaded = true;
this._textModel.setText(null, content);
this._mimeType = mimeType;
this._url = url;
this._createViewerIfNeeded();
},

updateContent: function(content)
{
this._textModel.setText(null, content);
},

get textModel()
{
return this._textModel;
},

get scrollTop()
{
return this._textViewer ? this._textViewer.element.scrollTop : 0;
},

set scrollTop(scrollTop)
{
if (this._textViewer)
this._textViewer.element.scrollTop = scrollTop;
},

highlightLine: function(line)
{
if (this._textViewer)
this._textViewer.highlightLine(line - 1);
else
this._lineToHighlight = line;
},

clearLineHighlight: function()
{
if (this._textViewer)
this._textViewer.clearLineHighlight();
else
delete this._lineToHighlight;
},

_createViewerIfNeeded: function()
{
if (!this._visible || !this._loaded || this._textViewer)
return;

this._textViewer = new WebInspector.TextViewer(this._textModel, WebInspector.platform, this._url);
var element = this._textViewer.element;
element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
element.addEventListener("mousedown", this._mouseDown.bind(this), true);
element.addEventListener("mousemove", this._mouseMove.bind(this), true);
element.addEventListener("scroll", this._scroll.bind(this), true);
this._parentElement.appendChild(element);

this._needsProgramCounterImage = true;
this._needsBreakpointImages = true;

this._textViewer.beginUpdates();

this._textViewer.mimeType = this._mimeType;
this._addExistingMessagesToSource();
this._addExistingBreakpointsToSource();
this._updateExecutionLine();
this._updateDiffDecorations();
this._textViewer.resize();

if (this._lineNumberToReveal) {
this.revealLine(this._lineNumberToReveal);
delete this._lineNumberToReveal;
}

if (this._pendingMarkRange) {
var range = this._pendingMarkRange;
this.markAndRevealRange(range);
delete this._pendingMarkRange;
}

if (this._lineToHighlight) {
this.highlightLine(this._lineToHighlight);
delete this._lineToHighlight;
}
this._textViewer.endUpdates();
if (this._editDelegate)
this._textViewer.editCallback = this._editDelegate;
},

findSearchMatches: function(query)
{
var ranges = [];


var regexObject = createSearchRegex(query);
this._collectRegexMatches(regexObject, ranges);


try {
if (/^\/.*\/$/.test(query))
this._collectRegexMatches(new RegExp(query.substring(1, query.length - 1)), ranges);
} catch (e) {

}
return ranges;
},

_collectRegexMatches: function(regexObject, ranges)
{
for (var i = 0; i < this._textModel.linesCount; ++i) {
var line = this._textModel.line(i);
var offset = 0;
do {
var match = regexObject.exec(line);
if (match) {
ranges.push(new WebInspector.TextRange(i, offset + match.index, i, offset + match.index + match[0].length));
offset += match.index + 1;
line = line.substring(match.index + 1);
}
} while (match)
}
return ranges;
},

markAndRevealRange: function(range)
{
if (this._textViewer)
this._textViewer.markAndRevealRange(range);
else
this._pendingMarkRange = range;
},

clearMarkedRange: function()
{
if (this._textViewer) {
this._textViewer.markAndRevealRange(null);
} else
delete this._pendingMarkRange;
},

_incrementMessageRepeatCount: function(msg, repeatDelta)
{
if (!msg._resourceMessageLineElement)
return;

if (!msg._resourceMessageRepeatCountElement) {
var repeatedElement = document.createElement("span");
msg._resourceMessageLineElement.appendChild(repeatedElement);
msg._resourceMessageRepeatCountElement = repeatedElement;
}

msg.repeatCount += repeatDelta;
msg._resourceMessageRepeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", msg.repeatCount);
},

_breakpointChanged: function(event)
{
var breakpoint = event.target;
var lineNumber = breakpoint.line - 1;
if (lineNumber >= this._textModel.linesCount)
return;

if (breakpoint.enabled)
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
else
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled");

if (breakpoint.condition)
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional");
else
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
},

_updateExecutionLine: function(previousLine)
{
if (previousLine) {
if (previousLine - 1 < this._textModel.linesCount)
this._textViewer.removeDecoration(previousLine - 1, "webkit-execution-line");
}

if (!this._executionLine)
return;

if (this._executionLine < this._textModel.linesCount)
this._textViewer.addDecoration(this._executionLine - 1, "webkit-execution-line");
},

_updateDiffDecorations: function()
{
if (!this._diffLines)
return;

function addDecorations(textViewer, lines, className)
{
for (var i = 0; i < lines.length; ++i)
textViewer.addDecoration(lines[i], className);
}
addDecorations(this._textViewer, this._diffLines.added, "webkit-added-line");
addDecorations(this._textViewer, this._diffLines.removed, "webkit-removed-line");
addDecorations(this._textViewer, this._diffLines.changed, "webkit-changed-line");
},

_removeDiffDecorations: function()
{
function removeDecorations(textViewer, lines, className)
{
for (var i = 0; i < lines.length; ++i)
textViewer.removeDecoration(lines[i], className);
}
removeDecorations(this._textViewer, this._diffLines.added, "webkit-added-line");
removeDecorations(this._textViewer, this._diffLines.removed, "webkit-removed-line");
removeDecorations(this._textViewer, this._diffLines.changed, "webkit-changed-line");
},

_addExistingMessagesToSource: function()
{
var length = this._messages.length;
for (var i = 0; i < length; ++i)
this._addMessageToSource(this._messages[i]);
},

_addMessageToSource: function(msg)
{
if (msg.line >= this._textModel.linesCount)
return;

var messageBubbleElement = this._messageBubbles[msg.line];
if (!messageBubbleElement || messageBubbleElement.nodeType !== Node.ELEMENT_NODE || !messageBubbleElement.hasStyleClass("webkit-html-message-bubble")) {
messageBubbleElement = document.createElement("div");
messageBubbleElement.className = "webkit-html-message-bubble";
this._messageBubbles[msg.line] = messageBubbleElement;
this._textViewer.addDecoration(msg.line - 1, messageBubbleElement);
}

var rowMessages = this._rowMessages[msg.line];
if (!rowMessages) {
rowMessages = [];
this._rowMessages[msg.line] = rowMessages;
}

for (var i = 0; i < rowMessages.length; ++i) {
if (rowMessages[i].isEqual(msg, true)) {
this._incrementMessageRepeatCount(rowMessages[i], msg.repeatDelta);
return;
}
}

rowMessages.push(msg);

var imageURL;
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Error:
messageBubbleElement.addStyleClass("webkit-html-error-message");
imageURL = "Images/errorIcon.png";
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
messageBubbleElement.addStyleClass("webkit-html-warning-message");
imageURL = "Images/warningIcon.png";
break;
}

var messageLineElement = document.createElement("div");
messageLineElement.className = "webkit-html-message-line";
messageBubbleElement.appendChild(messageLineElement);


var image = document.createElement("img");
image.src = imageURL;
image.className = "webkit-html-message-icon";
messageLineElement.appendChild(image);
messageLineElement.appendChild(document.createTextNode(msg.message));

msg._resourceMessageLineElement = messageLineElement;
},

_addExistingBreakpointsToSource: function()
{
for (var i = 0; i < this.breakpoints.length; ++i)
this._addBreakpointToSource(this.breakpoints[i]);
},

_addBreakpointToSource: function(breakpoint)
{
breakpoint.addEventListener("enable-changed", this._breakpointChanged, this);
breakpoint.addEventListener("condition-changed", this._breakpointChanged, this);

var lineNumber = breakpoint.line - 1;
if (lineNumber >= this._textModel.linesCount)
return;

this._textModel.setAttribute(lineNumber, "breakpoint", breakpoint);
breakpoint.sourceText = this._textModel.line(breakpoint.line - 1);

this._textViewer.beginUpdates();
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint");
if (!breakpoint.enabled)
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled");
if (breakpoint.condition)
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional");
this._textViewer.endUpdates();
},

_removeBreakpointFromSource: function(breakpoint)
{
breakpoint.removeEventListener("enable-changed", null, this);
breakpoint.removeEventListener("condition-changed", null, this);

var lineNumber = breakpoint.line - 1;
this._textViewer.beginUpdates();
this._textModel.removeAttribute(lineNumber, "breakpoint");
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint");
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
this._textViewer.endUpdates();
},

_contextMenu: function(event)
{
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (!target)
return;
var row = target.parentElement;

if (!WebInspector.panels.scripts)
return;

var lineNumber = row.lineNumber;
var contextMenu = new WebInspector.ContextMenu();

contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToHereDelegate.bind(this, lineNumber + 1));

var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
if (!breakpoint) {

contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._addBreakpointDelegate.bind(this, lineNumber + 1));

function addConditionalBreakpoint()
{
this._addBreakpointDelegate(lineNumber + 1);
var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
if (breakpoint)
this._editBreakpointCondition(breakpoint);
}

contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint…"), addConditionalBreakpoint.bind(this));
} else {

contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpoint.remove.bind(breakpoint));
contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), this._editBreakpointCondition.bind(this, breakpoint));
if (breakpoint.enabled)
contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), function() { breakpoint.enabled = false; });
else
contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), function() { breakpoint.enabled = true; });
}
contextMenu.show(event);
},

_scroll: function(event)
{
this._hidePopup();
},

_mouseDown: function(event)
{
this._resetHoverTimer();
this._hidePopup();
if (event.button != 0 || event.altKey || event.ctrlKey || event.metaKey)
return;
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (!target)
return;
var row = target.parentElement;

var lineNumber = row.lineNumber;

var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
if (breakpoint) {
if (event.shiftKey)
breakpoint.enabled = !breakpoint.enabled;
else
breakpoint.remove();
} else
this._addBreakpointDelegate(lineNumber + 1);
event.preventDefault();
},

_mouseMove: function(event)
{

if (this._hoverElement === event.target || event.target.hasStyleClass("source-frame-eval-expression"))
return;

this._resetHoverTimer();

if (this._popup) {
var self = this;
function doHide()
{
self._hidePopup();
delete self._hidePopupTimer;
}
if (!("_hidePopupTimer" in this))
this._hidePopupTimer = setTimeout(doHide, 500);
}

this._hoverElement = event.target;


if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
return;


if (this._hoverElement.hasStyleClass("webkit-javascript-keyword")) {
if (this._hoverElement.textContent !== "this")
return;
} else if (!this._hoverElement.hasStyleClass("webkit-javascript-ident"))
return;

const toolTipDelay = this._popup ? 600 : 1000;
this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
},

_resetHoverTimer: function()
{
if (this._hoverTimer) {
clearTimeout(this._hoverTimer);
delete this._hoverTimer;
}
},

_hidePopup: function()
{
if (!this._popup)
return;


var parentElement = this._popup.highlightElement.parentElement;
var child = this._popup.highlightElement.firstChild;
while (child) {
var nextSibling = child.nextSibling;
parentElement.insertBefore(child, this._popup.highlightElement);
child = nextSibling;
}
parentElement.removeChild(this._popup.highlightElement);

this._popup.hide();
delete this._popup;
InspectorBackend.releaseWrapperObjectGroup(0, this._popoverObjectGroup);
},

_mouseHover: function(element)
{
delete this._hoverTimer;

if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
return;

var lineRow = element.enclosingNodeOrSelfWithNodeName("tr");
if (!lineRow)
return;


var tokens = [ element ];
var token = element.previousSibling;
while (token && (token.className === "webkit-javascript-ident" || token.className === "webkit-javascript-keyword" || token.textContent.trim() === ".")) {
tokens.push(token);
token = token.previousSibling;
}
tokens.reverse();


var parentElement = element.parentElement;
var nextElement = element.nextSibling;
var container = document.createElement("span");
for (var i = 0; i < tokens.length; ++i)
container.appendChild(tokens[i]);
parentElement.insertBefore(container, nextElement);
this._showPopup(container);
},

_showPopup: function(element)
{
function killHidePopupTimer()
{
if (this._hidePopupTimer) {
clearTimeout(this._hidePopupTimer);
delete this._hidePopupTimer;



this._resetHoverTimer();
}
}

function showObjectPopup(result)
{
if (!WebInspector.panels.scripts.paused)
return;

var popupContentElement = null;
if (result.type !== "object" && result.type !== "node" && result.type !== "array") {
popupContentElement = document.createElement("span");
popupContentElement.className = "monospace console-formatted-" + result.type;
popupContentElement.style.whiteSpace = "pre";
popupContentElement.textContent = result.description;
if (result.type === "string")
popupContentElement.textContent = "\"" + popupContentElement.textContent + "\"";
this._popup = new WebInspector.Popover(popupContentElement);
this._popup.show(element);
} else {
var popupContentElement = document.createElement("div");

var titleElement = document.createElement("div");
titleElement.className = "source-frame-popover-title monospace";
titleElement.textContent = result.description;
popupContentElement.appendChild(titleElement);

var section = new WebInspector.ObjectPropertiesSection(result, "", null, false);
section.expanded = true;
section.element.addStyleClass("source-frame-popover-tree");
section.headerElement.addStyleClass("hidden");
popupContentElement.appendChild(section.element);

this._popup = new WebInspector.Popover(popupContentElement);
const popupWidth = 300;
const popupHeight = 250;
this._popup.show(element, popupWidth, popupHeight);
}
this._popup.highlightElement = element;
this._popup.highlightElement.addStyleClass("source-frame-eval-expression");
popupContentElement.addEventListener("mousemove", killHidePopupTimer.bind(this), true);
}

function evaluateCallback(result)
{
if (result.isError())
return;
if (!WebInspector.panels.scripts.paused)
return;
showObjectPopup.call(this, result);
}
WebInspector.panels.scripts.evaluateInSelectedCallFrame(element.textContent, false, this._popoverObjectGroup, evaluateCallback.bind(this));
},

_editBreakpointCondition: function(breakpoint)
{
this._showBreakpointConditionPopup(breakpoint.line);

function committed(element, newText)
{
breakpoint.condition = newText;
dismissed.call(this);
}

function dismissed()
{
if (this._conditionElement)
this._textViewer.removeDecoration(breakpoint.line - 1, this._conditionElement);
delete this._conditionEditorElement;
delete this._conditionElement;
}

var dismissedHandler = dismissed.bind(this);
this._conditionEditorElement.addEventListener("blur", dismissedHandler, false);

WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler);
this._conditionEditorElement.value = breakpoint.condition;
this._conditionEditorElement.select();
},

_showBreakpointConditionPopup: function(lineNumber)
{
this._conditionElement = this._createConditionElement(lineNumber);
this._textViewer.addDecoration(lineNumber - 1, this._conditionElement);
},

_createConditionElement: function(lineNumber)
{
var conditionElement = document.createElement("div");
conditionElement.className = "source-frame-breakpoint-condition";

var labelElement = document.createElement("label");
labelElement.className = "source-frame-breakpoint-message";
labelElement.htmlFor = "source-frame-breakpoint-condition";
labelElement.appendChild(document.createTextNode(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber)));
conditionElement.appendChild(labelElement);

var editorElement = document.createElement("input");
editorElement.id = "source-frame-breakpoint-condition";
editorElement.className = "monospace";
editorElement.type = "text"
conditionElement.appendChild(editorElement);
this._conditionEditorElement = editorElement;

return conditionElement;
},

_evalSelectionInCallFrame: function(event)
{
if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
return;

var selection = this.element.contentWindow.getSelection();
if (!selection.rangeCount)
return;

var expression = selection.getRangeAt(0).toString().trim();
WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", function(result) {
WebInspector.showConsole();
var commandMessage = new WebInspector.ConsoleCommand(expression);
WebInspector.console.addMessage(commandMessage);
WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, commandMessage));
});
},

resize: function()
{
if (this._textViewer)
this._textViewer.resize();
}
}


WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype;





WebInspector.DOMSyntaxHighlighter = function(mimeType)
{
this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
}

WebInspector.DOMSyntaxHighlighter.prototype = {
createSpan: function(content, className)
{
var span = document.createElement("span");
span.className = "webkit-" + className;
span.appendChild(document.createTextNode(content));
return span;
},

syntaxHighlightNode: function(node)
{
this._tokenizer.condition = this._tokenizer.initialCondition;
var lines = node.textContent.split("\n");
node.removeChildren();

for (var i = lines[0].length ? 0 : 1; i < lines.length; ++i) {
var line = lines[i];
var plainTextStart = 0;
this._tokenizer.line = line;
var column = 0;
do {
var newColumn = this._tokenizer.nextToken(column);
var tokenType = this._tokenizer.tokenType;
if (tokenType) {
if (column > plainTextStart) {
var plainText = line.substring(plainTextStart, column);
node.appendChild(document.createTextNode(plainText));
}
var token = line.substring(column, newColumn);
node.appendChild(this.createSpan(token, tokenType));
plainTextStart = newColumn;
}
column = newColumn;
} while (column < line.length)

if (plainTextStart < line.length) {
var plainText = line.substring(plainTextStart, line.length);
node.appendChild(document.createTextNode(plainText));
}
if (i < lines.length - 1)
node.appendChild(document.createElement("br"));
}
}
}





WebInspector.TextRange = function(startLine, startColumn, endLine, endColumn)
{
this.startLine = startLine;
this.startColumn = startColumn;
this.endLine = endLine;
this.endColumn = endColumn;
}

WebInspector.TextRange.prototype = {
isEmpty: function()
{
return this.startLine === this.endLine && this.startColumn === this.endColumn;
},

get linesCount()
{
return this.endLine - this.startLine;
},

clone: function()
{
return new WebInspector.TextRange(this.startLine, this.startColumn, this.endLine, this.endColumn); 
}
}

WebInspector.TextEditorModel = function()
{
this._lines = [""];
this._attributes = [];
this._undoStack = [];
this._noPunctuationRegex = /[^ !%&()*+,-.:;<=>?\[\]\^{|}~]+/;
}

WebInspector.TextEditorModel.prototype = {
set changeListener(changeListener)
{
this._changeListener = changeListener;
},

get linesCount()
{
return this._lines.length;
},

line: function(lineNumber)
{
if (lineNumber >= this._lines.length)
throw "Out of bounds:" + lineNumber;
return this._lines[lineNumber];
},

lineLength: function(lineNumber)
{
return this._lines[lineNumber].length;
},

setText: function(range, text)
{
if (!range)
range = new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length);
var command = this._pushUndoableCommand(range, text);
var newRange = this._innerSetText(range, text);
command.range = newRange.clone();

if (this._changeListener)
this._changeListener(range, newRange, command.text, text);
return newRange;
},

set replaceTabsWithSpaces(replaceTabsWithSpaces)
{
this._replaceTabsWithSpaces = replaceTabsWithSpaces;
},

_innerSetText: function(range, text)
{
this._eraseRange(range);
if (text === "")
return new WebInspector.TextRange(range.startLine, range.startColumn, range.startLine, range.startColumn);

var newLines = text.split("\n");
this._replaceTabsIfNeeded(newLines);

var prefix = this._lines[range.startLine].substring(0, range.startColumn);
var prefixArguments = this._arguments
var suffix = this._lines[range.startLine].substring(range.startColumn);

var postCaret = prefix.length;

if (newLines.length === 1) {
this._setLine(range.startLine, prefix + newLines[0] + suffix);
postCaret += newLines[0].length;
} else {
this._setLine(range.startLine, prefix + newLines[0]);
for (var i = 1; i < newLines.length; ++i)
this._insertLine(range.startLine + i, newLines[i]);
this._setLine(range.startLine + newLines.length - 1, newLines[newLines.length - 1] + suffix);
postCaret = newLines[newLines.length - 1].length;
}
return new WebInspector.TextRange(range.startLine, range.startColumn,
range.startLine + newLines.length - 1, postCaret);
},

_replaceTabsIfNeeded: function(lines)
{
if (!this._replaceTabsWithSpaces)
return;
var spaces = [ "    ", "   ", "  ", " "];
for (var i = 0; i < lines.length; ++i) {
var line = lines[i];
var index = line.indexOf("\t");
while (index !== -1) {
line = line.substring(0, index) + spaces[index % 4] + line.substring(index + 1);
index = line.indexOf("\t", index + 1);
}
lines[i] = line;
}
},

_eraseRange: function(range)
{
if (range.isEmpty())
return;

var prefix = this._lines[range.startLine].substring(0, range.startColumn);
var suffix = this._lines[range.endLine].substring(range.endColumn);

if (range.endLine > range.startLine)
this._removeLines(range.startLine + 1, range.endLine - range.startLine);
this._setLine(range.startLine, prefix + suffix);
},

_setLine: function(lineNumber, text)
{
this._lines[lineNumber] = text;
},

_removeLines: function(fromLine, count)
{
this._lines.splice(fromLine, count);
this._attributes.splice(fromLine, count);
},

_insertLine: function(lineNumber, text)
{
this._lines.splice(lineNumber, 0, text);
this._attributes.splice(lineNumber, 0, {});
},

wordRange: function(lineNumber, column)
{
return new WebInspector.TextRange(lineNumber, this.wordStart(lineNumber, column, true), lineNumber, this.wordEnd(lineNumber, column, true));
},

wordStart: function(lineNumber, column, gapless)
{
var line = this._lines[lineNumber];
var prefix = line.substring(0, column).split("").reverse().join("");
var prefixMatch = this._noPunctuationRegex.exec(prefix);
return prefixMatch && (!gapless || prefixMatch.index === 0) ? column - prefixMatch.index - prefixMatch[0].length : column;
},

wordEnd: function(lineNumber, column, gapless)
{
var line = this._lines[lineNumber];
var suffix = line.substring(column);
var suffixMatch = this._noPunctuationRegex.exec(suffix);
return suffixMatch && (!gapless || suffixMatch.index === 0) ? column + suffixMatch.index + suffixMatch[0].length : column;
},

copyRange: function(range)
{
if (!range)
range = new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length);

var clip = [];
if (range.startLine === range.endLine) {
clip.push(this._lines[range.startLine].substring(range.startColumn, range.endColumn));
return clip.join("\n");
}
clip.push(this._lines[range.startLine].substring(range.startColumn));
for (var i = range.startLine + 1; i < range.endLine; ++i)
clip.push(this._lines[i]);
clip.push(this._lines[range.endLine].substring(0, range.endColumn));
return clip.join("\n");
},

setAttribute: function(line, name, value)
{
var attrs = this._attributes[line];
if (!attrs) {
attrs = {};
this._attributes[line] = attrs;
}
attrs[name] = value;
},

getAttribute: function(line, name)
{
var attrs = this._attributes[line];
return attrs ? attrs[name] : null;
},

removeAttribute: function(line, name)
{
var attrs = this._attributes[line];
if (attrs)
delete attrs[name];
},

_pushUndoableCommand: function(range, text)
{
var command = {
text: this.copyRange(range),
startLine: range.startLine,
startColumn: range.startColumn,
endLine: range.startLine,
endColumn: range.startColumn
};
if (this._inUndo)
this._redoStack.push(command);
else {
if (!this._inRedo)
this._redoStack = [];
this._undoStack.push(command);
}
return command;
},

undo: function()
{
this._markRedoableState();

this._inUndo = true;
var range = this._doUndo(this._undoStack);
delete this._inUndo;

return range;
},

redo: function()
{
this.markUndoableState();

this._inRedo = true;
var range = this._doUndo(this._redoStack);
delete this._inRedo;

return range;
},

_doUndo: function(stack)
{
var range = null;
for (var i = stack.length - 1; i >= 0; --i) {
var command = stack[i];
stack.length = i;

range = this.setText(command.range, command.text);
if (i > 0 && stack[i - 1].explicit)
return range;
}
return range;
},

markUndoableState: function()
{
if (this._undoStack.length)
this._undoStack[this._undoStack.length - 1].explicit = true;
},

_markRedoableState: function()
{
if (this._redoStack.length)
this._redoStack[this._redoStack.length - 1].explicit = true;
},

resetUndoStack: function()
{
this._undoStack = [];
}
}





WebInspector.TextEditorHighlighter = function(textModel, damageCallback)
{
this._textModel = textModel;
this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/html");
this._damageCallback = damageCallback;
this.reset();
}

WebInspector.TextEditorHighlighter.prototype = {
set mimeType(mimeType)
{
var tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
if (tokenizer) {
this._tokenizer = tokenizer;
this._tokenizerCondition = this._tokenizer.initialCondition;
}
},

reset: function()
{
this._lastHighlightedLine = 0;
this._lastHighlightedColumn = 0;
this._tokenizerCondition = this._tokenizer.initialCondition;
},

highlight: function(endLine)
{

if (endLine <= this._lastHighlightedLine)
return;

this._requestedEndLine = endLine;

if (this._highlightTimer) {

return;
}


this._highlightInChunks(endLine);


if (this._lastHighlightedLine < endLine)
this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, endLine), 100);
},

_highlightInChunks: function(endLine)
{
delete this._highlightTimer;


if (this._requestedEndLine <= this._lastHighlightedLine)
return;

if (this._requestedEndLine !== endLine) {

this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._requestedEndLine), 100);
return;
}

this._highlightLines(this._requestedEndLine);


if (this._lastHighlightedLine < this._requestedEndLine)
this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._requestedEndLine), 10);
},

_highlightLines: function(endLine)
{

this._tokenizer.condition = this._tokenizerCondition;
var tokensCount = 0;
for (var lineNumber = this._lastHighlightedLine; lineNumber < endLine; ++lineNumber) {
var line = this._textModel.line(lineNumber);
this._tokenizer.line = line;
var attributes = this._textModel.getAttribute(lineNumber, "highlight") || {};


do {
var newColumn = this._tokenizer.nextToken(this._lastHighlightedColumn);
var tokenType = this._tokenizer.tokenType;
if (tokenType)
attributes[this._lastHighlightedColumn] = { length: newColumn - this._lastHighlightedColumn, tokenType: tokenType, subTokenizer: this._tokenizer.subTokenizer };
this._lastHighlightedColumn = newColumn;
if (++tokensCount > 1000)
break;
} while (this._lastHighlightedColumn < line.length)

this._textModel.setAttribute(lineNumber, "highlight", attributes);
if (this._lastHighlightedColumn < line.length) {

break;
} else
this._lastHighlightedColumn = 0;
}

this._damageCallback(this._lastHighlightedLine, lineNumber);
this._tokenizerCondition = this._tokenizer.condition;
this._lastHighlightedLine = lineNumber;
}
}





WebInspector.TextViewer = function(textModel, platform, url)
{
this._textModel = textModel;
this._textModel.changeListener = this._buildChunks.bind(this);
this._highlighter = new WebInspector.TextEditorHighlighter(this._textModel, this._highlightDataReady.bind(this));

this.element = document.createElement("div");
this.element.className = "text-editor monospace";
this.element.tabIndex = 0;

this.element.addEventListener("scroll", this._scroll.bind(this), false);
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
this.element.addEventListener("beforecopy", this._beforeCopy.bind(this), false);
this.element.addEventListener("copy", this._copy.bind(this), false);
this.element.addEventListener("dblclick", this._handleDoubleClick.bind(this), false);

this._url = url;

this._linesContainerElement = document.createElement("table");
this._linesContainerElement.className = "text-editor-lines";
this._linesContainerElement.setAttribute("cellspacing", 0);
this._linesContainerElement.setAttribute("cellpadding", 0);
this.element.appendChild(this._linesContainerElement);

this._defaultChunkSize = 50;
this._paintCoalescingLevel = 0;

this.freeCachedElements();
this._buildChunks();
}

WebInspector.TextViewer.prototype = {
set mimeType(mimeType)
{
this._highlighter.mimeType = mimeType;
},

get textModel()
{
return this._textModel;
},

revealLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return;

var chunk = this._makeLineAChunk(lineNumber);
chunk.element.scrollIntoViewIfNeeded();
},

set editCallback(editCallback)
{
this._editCallback = editCallback;
},

addDecoration: function(lineNumber, decoration)
{
var chunk = this._makeLineAChunk(lineNumber);
chunk.addDecoration(decoration);
},

removeDecoration: function(lineNumber, decoration)
{
var chunk = this._makeLineAChunk(lineNumber);
chunk.removeDecoration(decoration);
},

markAndRevealRange: function(range)
{
if (this._rangeToMark) {
var markedLine = this._rangeToMark.startLine;
this._rangeToMark = null;
this._paintLines(markedLine, markedLine + 1);
}

if (range) {
this._rangeToMark = range;
this.revealLine(range.startLine);
this._paintLines(range.startLine, range.startLine + 1);
if (this._markedRangeElement)
this._markedRangeElement.scrollIntoViewIfNeeded();
}
delete this._markedRangeElement;
},

highlightLine: function(lineNumber)
{
this.clearLineHighlight();
this._highlightedLine = lineNumber;
this.revealLine(lineNumber);
var chunk = this._makeLineAChunk(lineNumber);
chunk.addDecoration("webkit-highlighted-line");
},

clearLineHighlight: function()
{
if (typeof this._highlightedLine === "number") {
var chunk = this._makeLineAChunk(this._highlightedLine);
chunk.removeDecoration("webkit-highlighted-line");
delete this._highlightedLine;
}
},

freeCachedElements: function()
{
this._cachedSpans = [];
this._cachedTextNodes = [];
this._cachedRows = [];
},

_buildChunks: function()
{
this._linesContainerElement.removeChildren();

this._textChunks = [];
for (var i = 0; i < this._textModel.linesCount; i += this._defaultChunkSize) {
var chunk = new WebInspector.TextChunk(this, i, i + this._defaultChunkSize);
this._textChunks.push(chunk);
this._linesContainerElement.appendChild(chunk.element);
}

this._indexChunks();
this._highlighter.reset();
this._repaintAll();
},

_makeLineAChunk: function(lineNumber)
{
if (!this._textChunks)
this._buildChunks();

var chunkNumber = this._chunkNumberForLine(lineNumber);
var oldChunk = this._textChunks[chunkNumber];
if (oldChunk.linesCount === 1)
return oldChunk;

var wasExpanded = oldChunk.expanded;
oldChunk.expanded = false;

var insertIndex = oldChunk.chunkNumber + 1;


if (lineNumber > oldChunk.startLine) {
var prefixChunk = new WebInspector.TextChunk(this, oldChunk.startLine, lineNumber);
this._textChunks.splice(insertIndex++, 0, prefixChunk);
this._linesContainerElement.insertBefore(prefixChunk.element, oldChunk.element);
}


var lineChunk = new WebInspector.TextChunk(this, lineNumber, lineNumber + 1);
this._textChunks.splice(insertIndex++, 0, lineChunk);
this._linesContainerElement.insertBefore(lineChunk.element, oldChunk.element);


if (oldChunk.startLine + oldChunk.linesCount > lineNumber + 1) {
var suffixChunk = new WebInspector.TextChunk(this, lineNumber + 1, oldChunk.startLine + oldChunk.linesCount);
this._textChunks.splice(insertIndex, 0, suffixChunk);
this._linesContainerElement.insertBefore(suffixChunk.element, oldChunk.element);
}


this._textChunks.splice(oldChunk.chunkNumber, 1);
this._linesContainerElement.removeChild(oldChunk.element);
this._indexChunks();

if (wasExpanded) {
if (prefixChunk)
prefixChunk.expanded = true;
lineChunk.expanded = true;
if (suffixChunk)
suffixChunk.expanded = true;
}

return lineChunk;
},

_indexChunks: function()
{
for (var i = 0; i < this._textChunks.length; ++i)
this._textChunks[i].chunkNumber = i;
},

_scroll: function()
{
var scrollTop = this.element.scrollTop;
setTimeout(function() {
if (scrollTop === this.element.scrollTop)
this._repaintAll();
}.bind(this), 50);
},

_handleKeyDown: function()
{
if (this._editingLine || event.metaKey || event.shiftKey || event.ctrlKey || event.altKey)
return;

var scrollValue = 0;
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Up.code)
scrollValue = -1;
else if (event.keyCode == WebInspector.KeyboardShortcut.Keys.Down.code)
scrollValue = 1;

if (scrollValue) {
event.preventDefault();
event.stopPropagation();
this.element.scrollByLines(scrollValue);
return;
}

scrollValue = 0;
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Left.code)
scrollValue = -40;
else if (event.keyCode == WebInspector.KeyboardShortcut.Keys.Right.code)
scrollValue = 40;

if (scrollValue) {
event.preventDefault();
event.stopPropagation();
this.element.scrollLeft += scrollValue;
}
},

_handleDoubleClick: function(e)
{
if (!this._editCallback)
return;

var cell = e.target.enclosingNodeOrSelfWithNodeName("TD");
if (!cell)
return;

var lineRow = cell.parentElement;
if (lineRow.firstChild === cell)
return;  

var oldContent = lineRow.lastChild.innerHTML;
var cancelEditingCallback = this._cancelEditingLine.bind(this, lineRow.lastChild, oldContent);
var commitEditingCallback = this._commitEditingLine.bind(this, lineRow.lineNumber, lineRow.lastChild, cancelEditingCallback);
this._editingLine = WebInspector.startEditing(lineRow.lastChild, commitEditingCallback, cancelEditingCallback, null, true);
},

_commitEditingLine: function(lineNumber, element, cancelEditingCallback)
{
this._editCallback(lineNumber, element.textContent, cancelEditingCallback);
delete this._editingLine;
},

_cancelEditingLine: function(element, oldContent, e)
{
element.innerHTML = oldContent;
delete this._editingLine;
},

_beforeCopy: function(e)
{
e.preventDefault();
},

_copy: function(e)
{
var range = this._getSelection();
var text = this._textModel.copyRange(range);
InspectorFrontendHost.copyText(text);
e.preventDefault();
},

beginUpdates: function(enabled)
{
this._paintCoalescingLevel++;
},

endUpdates: function(enabled)
{
this._paintCoalescingLevel--;
if (!this._paintCoalescingLevel)
this._repaintAll();
},

_chunkForOffset: function(offset)
{
var currentOffset = 0;
var row = this._linesContainerElement.firstChild;
while (row) {
var rowHeight = row.offsetHeight;
if (offset >= currentOffset && offset < currentOffset + rowHeight)
return row.chunkNumber;
row = row.nextSibling;
currentOffset += rowHeight;
}
return this._textChunks.length - 1;
},

_chunkNumberForLine: function(lineNumber)
{
for (var i = 0; i < this._textChunks.length; ++i) {
var line = this._textChunks[i].startLine;
if (lineNumber >= this._textChunks[i].startLine && lineNumber < this._textChunks[i].startLine + this._textChunks[i].linesCount)
return i;
}
return this._textChunks.length - 1;
},

_chunkForLine: function(lineNumber)
{
return this._textChunks[this._chunkNumberForLine(lineNumber)];
},

_chunkStartLine: function(chunkNumber)
{
var lineNumber = 0;
for (var i = 0; i < chunkNumber && i < this._textChunks.length; ++i)
lineNumber += this._textChunks[i].linesCount;
return lineNumber;
},

_repaintAll: function()
{
if (this._paintCoalescingLevel)
return;

if (!this._textChunks)
this._buildChunks();

var visibleFrom = this.element.scrollTop;
var visibleTo = this.element.scrollTop + this.element.clientHeight;

var offset = 0;
var firstVisibleLine = -1;
var lastVisibleLine = 0;
var toExpand = [];
var toCollapse = [];
for (var i = 0; i < this._textChunks.length; ++i) {
var chunk = this._textChunks[i];
var chunkHeight = chunk.height;
if (offset + chunkHeight > visibleFrom && offset < visibleTo) {
toExpand.push(chunk);
if (firstVisibleLine === -1)
firstVisibleLine = chunk.startLine;
lastVisibleLine = chunk.startLine + chunk.linesCount;
} else {
toCollapse.push(chunk);
if (offset >= visibleTo)
break;
}
offset += chunkHeight;
}

for (var j = i; j < this._textChunks.length; ++j)
toCollapse.push(this._textChunks[i]);

var selection = this._getSelection();

this._muteHighlightListener = true;
this._highlighter.highlight(lastVisibleLine);
delete this._muteHighlightListener;

for (var i = 0; i < toCollapse.length; ++i)
toCollapse[i].expanded = false;
for (var i = 0; i < toExpand.length; ++i)
toExpand[i].expanded = true;

this._restoreSelection(selection);
},

_highlightDataReady: function(fromLine, toLine)
{
if (this._muteHighlightListener)
return;

var selection;
for (var i = fromLine; i < toLine; ++i) {
var lineRow = this._textModel.getAttribute(i, "line-row");
if (!lineRow || lineRow.highlighted)
continue;
if (!selection)
selection = this._getSelection();
this._paintLine(lineRow, i);
}
this._restoreSelection(selection);
},

_paintLines: function(fromLine, toLine)
{
for (var i = fromLine; i < toLine; ++i) {
var lineRow = this._textModel.getAttribute(i, "line-row");
if (lineRow)
this._paintLine(lineRow, i);
}
},

_paintLine: function(lineRow, lineNumber)
{
var element = lineRow.lastChild;
var highlight = this._textModel.getAttribute(lineNumber, "highlight");
if (!highlight) {
if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
this._markedRangeElement = highlightSearchResult(element, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
return;
}

element.removeChildren();
var line = this._textModel.line(lineNumber);

var plainTextStart = -1;
for (var j = 0; j < line.length;) {
if (j > 1000) {

if (plainTextStart === -1)
plainTextStart = j;
break;
}
var attribute = highlight[j];
if (!attribute || !attribute.tokenType) {
if (plainTextStart === -1)
plainTextStart = j;
j++;
} else {
if (plainTextStart !== -1) {
this._appendTextNode(element, line.substring(plainTextStart, j));
plainTextStart = -1;
}
this._appendSpan(element, line.substring(j, j + attribute.length), attribute.tokenType);
j += attribute.length;
}
}
if (plainTextStart !== -1)
this._appendTextNode(element, line.substring(plainTextStart, line.length));
if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
this._markedRangeElement = highlightSearchResult(element, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
if (lineRow.decorationsElement)
element.appendChild(lineRow.decorationsElement);
},

_releaseLinesHighlight: function(fromLine, toLine)
{
for (var i = fromLine; i < toLine; ++i) {
var lineRow = this._textModel.getAttribute(i, "line-row");
if (!lineRow)
continue;
var element = lineRow.lastChild;
if ("spans" in element) {
var spans = element.spans;
for (var j = 0; j < spans.length; ++j)
this._cachedSpans.push(spans[j]);
delete element.spans;
}
if ("textNodes" in element) {
var textNodes = element.textNodes;
for (var j = 0; j < textNodes.length; ++j)
this._cachedTextNodes.push(textNodes[j]);
delete element.textNodes;
}
}
},

_getSelection: function()
{
var selection = window.getSelection();
if (selection.isCollapsed)
return null;
var selectionRange = selection.getRangeAt(0);

if (!this.element.isAncestor(selectionRange.startContainer) || !this.element.isAncestor(selectionRange.endContainer))
return null;
var start = this._selectionToPosition(selectionRange.startContainer, selectionRange.startOffset);
var end = this._selectionToPosition(selectionRange.endContainer, selectionRange.endOffset);
return new WebInspector.TextRange(start.line, start.column, end.line, end.column);
},

_restoreSelection: function(range)
{
if (!range)
return;
var startRow = this._textModel.getAttribute(range.startLine, "line-row");
if (startRow)
var start = startRow.lastChild.rangeBoundaryForOffset(range.startColumn);
else {
var offset = range.startColumn;
var chunkNumber = this._chunkNumberForLine(range.startLine);
for (var i = this._chunkStartLine(chunkNumber); i < range.startLine; ++i)
offset += this._textModel.line(i).length + 1; 
var lineCell = this._textChunks[chunkNumber].element.lastChild;
if (lineCell.firstChild)
var start = { container: lineCell.firstChild, offset: offset };
else
var start = { container: lineCell, offset: 0 };
}

var endRow = this._textModel.getAttribute(range.endLine, "line-row");
if (endRow)
var end = endRow.lastChild.rangeBoundaryForOffset(range.endColumn);
else {
var offset = range.endColumn;
var chunkNumber = this._chunkNumberForLine(range.endLine);
for (var i = this._chunkStartLine(chunkNumber); i < range.endLine; ++i)
offset += this._textModel.line(i).length + 1; 
var lineCell = this._textChunks[chunkNumber].element.lastChild;
if (lineCell.firstChild)
var end = { container: lineCell.firstChild, offset: offset };
else
var end = { container: lineCell, offset: 0 };
}

var selectionRange = document.createRange();
selectionRange.setStart(start.container, start.offset);
selectionRange.setEnd(end.container, end.offset);

var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(selectionRange);
},

_selectionToPosition: function(container, offset)
{
if (container === this.element && offset === 0)
return { line: 0, column: 0 };
if (container === this.element && offset === 1)
return { line: this._textModel.linesCount - 1, column: this._textModel.lineLength(this._textModel.linesCount - 1) };

var lineRow = container.enclosingNodeOrSelfWithNodeName("tr");
var lineNumber = lineRow.lineNumber;
if (container.nodeName === "TD" && offset === 0)
return { line: lineNumber, column: 0 };
if (container.nodeName === "TD" && offset === 1)
return { line: lineNumber, column: this._textModel.lineLength(lineNumber) };

var column = 0;
var node = lineRow.lastChild.traverseNextTextNode(lineRow.lastChild);
while (node && node !== container) {
column += node.textContent.length;
node = node.traverseNextTextNode(lineRow.lastChild);
}


if (node === container && offset) {
var text = node.textContent;
for (var i = 0; i < offset; ++i) {
if (text.charAt(i) === "\n") {
lineNumber++;
column = 0;
} else
column++;
}
}
return { line: lineNumber, column: column };
},

_appendSpan: function(element, content, className)
{
if (className === "html-resource-link" || className === "html-external-link") {
element.appendChild(this._createLink(content, className === "html-external-link"));
return;
}

var span = this._cachedSpans.pop() || document.createElement("span");
span.className = "webkit-" + className;
span.textContent = content;
element.appendChild(span);
if (!("spans" in element))
element.spans = [];
element.spans.push(span);
},

_appendTextNode: function(element, text)
{
var textNode = this._cachedTextNodes.pop();
if (textNode) {
textNode.nodeValue = text;
} else
textNode = document.createTextNode(text);
element.appendChild(textNode);
if (!("textNodes" in element))
element.textNodes = [];
element.textNodes.push(textNode);
},

_createLink: function(content, isExternal)
{
var quote = content.charAt(0);
if (content.length > 1 && (quote === "\"" ||   quote === "'"))
content = content.substring(1, content.length - 1);
else
quote = null;

var a = WebInspector.linkifyURLAsNode(this._rewriteHref(content), content, null, isExternal);
var span = document.createElement("span");
span.className = "webkit-html-attribute-value";
if (quote)
span.appendChild(document.createTextNode(quote));
span.appendChild(a);
if (quote)
span.appendChild(document.createTextNode(quote));
return span;
},

_rewriteHref: function(hrefValue, isExternal)
{
if (!this._url || !hrefValue || hrefValue.indexOf("://") > 0)
return hrefValue;
return WebInspector.completeURL(this._url, hrefValue);
},

resize: function()
{
this._repaintAll();
}
}

var cachedSpans = [];

WebInspector.TextChunk = function(textViewer, startLine, endLine)
{
this._textViewer = textViewer;
this.element = document.createElement("tr");
this._textModel = textViewer._textModel;
this.element.chunk = this;
this.element.lineNumber = startLine;

this.startLine = startLine;
endLine = Math.min(this._textModel.linesCount, endLine);
this.linesCount = endLine - startLine;

this._lineNumberElement = document.createElement("td");
this._lineNumberElement.className = "webkit-line-number";
this.element.appendChild(this._lineNumberElement);

this._lineContentElement = document.createElement("td");
this._lineContentElement.className = "webkit-line-content";
this.element.appendChild(this._lineContentElement);

this._expanded = false;

var lineNumbers = [];
var lines = [];
for (var i = startLine; i < endLine; ++i) {
lineNumbers.push(i + 1);
lines.push(this._textModel.line(i));
}
if (this.linesCount === 1) {


var innerSpan = document.createElement("span");
innerSpan.className = "webkit-line-number-inner";
innerSpan.textContent = startLine + 1;
var outerSpan = document.createElement("div");
outerSpan.className = "webkit-line-number-outer";
outerSpan.appendChild(innerSpan);
this._lineNumberElement.appendChild(outerSpan);
} else
this._lineNumberElement.textContent = lineNumbers.join("\n");
this._lineContentElement.textContent = lines.join("\n");
}

WebInspector.TextChunk.prototype = {
addDecoration: function(decoration)
{
if (typeof decoration === "string") {
this.element.addStyleClass(decoration);
return;
}
if (!this.element.decorationsElement) {
this.element.decorationsElement = document.createElement("div");
this._lineContentElement.appendChild(this.element.decorationsElement);
}
this.element.decorationsElement.appendChild(decoration);
},

removeDecoration: function(decoration)
{
if (typeof decoration === "string") {
this.element.removeStyleClass(decoration);
return;
}
if (!this.element.decorationsElement)
return;
this.element.decorationsElement.removeChild(decoration);
},

get expanded()
{
return this._expanded;
},

set expanded(expanded)
{
if (this._expanded === expanded)
return;

this._expanded = expanded;

if (this.linesCount === 1) {
this._textModel.setAttribute(this.startLine, "line-row", this.element);
if (expanded)
this._textViewer._paintLines(this.startLine, this.startLine + 1);
return;
}

if (expanded) {
var parentElement = this.element.parentElement;
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
var lineRow = this._createRow(i);
this._textModel.setAttribute(i, "line-row", lineRow);
parentElement.insertBefore(lineRow, this.element);
}
parentElement.removeChild(this.element);

this._textViewer._paintLines(this.startLine, this.startLine + this.linesCount);
} else {
var firstLine = this._textModel.getAttribute(this.startLine, "line-row");
var parentElement = firstLine.parentElement;
this._textViewer._releaseLinesHighlight(this.startLine, this.startLine + this.linesCount);

parentElement.insertBefore(this.element, firstLine);
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
var lineRow = this._textModel.getAttribute(i, "line-row");
this._textModel.removeAttribute(i, "line-row");
this._textViewer._cachedRows.push(lineRow);
parentElement.removeChild(lineRow);
}
}
},

get height()
{
if (!this._expanded)
return this.element.offsetHeight;
var result = 0;
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
var lineRow = this._textModel.getAttribute(i, "line-row");
result += lineRow.offsetHeight;
}
return result;
},

_createRow: function(lineNumber)
{
var cachedRows = this._textViewer._cachedRows;
if (cachedRows.length) {
var lineRow = cachedRows[cachedRows.length - 1];
cachedRows.length--;
var lineNumberElement = lineRow.firstChild;
var lineContentElement = lineRow.lastChild;
} else {
var lineRow = document.createElement("tr");

var lineNumberElement = document.createElement("td");
lineNumberElement.className = "webkit-line-number";
lineRow.appendChild(lineNumberElement);

var lineContentElement = document.createElement("td");
lineContentElement.className = "webkit-line-content";
lineRow.appendChild(lineContentElement);        
}
lineRow.lineNumber = lineNumber;
lineNumberElement.textContent = lineNumber + 1;
lineContentElement.textContent = this._textModel.line(lineNumber);
return lineRow;
}
}






WebInspector.SourceTokenizer = function()
{
}

WebInspector.SourceTokenizer.prototype = {
set line(line) {
this._line = line;
},

set condition(condition)
{
this._condition = condition;
},

get condition()
{
return this._condition;
},

get subTokenizer()
{
return this._condition.subTokenizer;
},

getLexCondition: function()
{
return this.condition.lexCondition;
},

setLexCondition: function(lexCondition)
{
this.condition.lexCondition = lexCondition;
},

_charAt: function(cursor)
{
return cursor < this._line.length ? this._line.charAt(cursor) : "\n";
}
}


WebInspector.SourceTokenizer.Registry = function() {
this._tokenizers = {};
this._tokenizerConstructors = {
"text/css": "SourceCSSTokenizer",
"text/html": "SourceHTMLTokenizer",
"text/javascript": "SourceJavaScriptTokenizer"
};
}

WebInspector.SourceTokenizer.Registry.getInstance = function()
{
if (!WebInspector.SourceTokenizer.Registry._instance)
WebInspector.SourceTokenizer.Registry._instance = new WebInspector.SourceTokenizer.Registry();
return WebInspector.SourceTokenizer.Registry._instance;
}

WebInspector.SourceTokenizer.Registry.prototype = {
getTokenizer: function(mimeType)
{
if (!this._tokenizerConstructors[mimeType])
return null;
var tokenizerClass = this._tokenizerConstructors[mimeType];
var tokenizer = this._tokenizers[tokenizerClass];
if (!tokenizer) {
tokenizer = new WebInspector[tokenizerClass]();
this._tokenizers[mimeType] = tokenizer;
}
return tokenizer;
}
}


















WebInspector.SourceCSSTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);

this._propertyKeywords = WebInspector.CSSCompletions.keySet();

this._valueKeywords = [
"above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll",
"alternate", "always","amharic", "amharic-abegede", "antialiased", "appworkspace", "aqua", "arabic-indic", "armenian",
"auto", "avoid", "background", "backwards", "baseline", "below", "bidi-override", "binary", "bengali", "black", "blink",
"block", "block-axis", "blue", "bold", "bolder", "border", "border-box", "both", "bottom", "break-all", "break-word", "button",
"button-bevel", "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", "capitalize", "caps-lock-indicator",
"caption", "captiontext", "caret", "cell", "center", "checkbox", "circle", "cjk-earthly-branch", "cjk-heavenly-stem", "cjk-ideographic",
"clear", "clip", "close-quote", "col-resize", "collapse", "compact", "condensed", "contain", "content", "content-box", "context-menu",
"continuous", "copy", "cover", "crop", "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal", "decimal-leading-zero", "default",
"default-button", "destination-atop", "destination-in", "destination-out", "destination-over", "devanagari", "disc", "discard", "document",
"dot-dash", "dot-dot-dash", "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", "element",
"ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", "ethiopic-abegede-am-et", "ethiopic-abegede-gez",
"ethiopic-abegede-ti-er", "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", "ethiopic-halehame-aa-et",
"ethiopic-halehame-am-et", "ethiopic-halehame-gez", "ethiopic-halehame-om-et", "ethiopic-halehame-sid-et",
"ethiopic-halehame-so-et", "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", "ew-resize", "expanded",
"extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "forwards", "from", "fuchsia", "geometricPrecision",
"georgian", "gray", "graytext", "green", "grey", "groove", "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", "help",
"hidden", "hide", "higher", "highlight", "highlighttext", "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext", "inherit", "initial", "inline",
"inline-axis", "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "kannada", "katakana",
"katakana-iroha", "khmer", "landscape", "lao", "large", "larger", "left", "level", "lighter", "lime", "line-through", "linear", "lines",
"list-button", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-greek", "lower-hexadecimal", "lower-latin",
"lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "maroon", "match", "media-controls-background", "media-current-time-display",
"media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button", "media-rewind-button",
"media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display",
"media-volume-slider", "media-volume-slider-container", "media-volume-sliderthumb", "medium", "menu", "menulist", "menulist-button",
"menulist-text", "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", "mix", "mongolian", "monospace", "move", "multiple",
"myanmar", "n-resize", "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none",
"normal", "not-allowed", "nowrap", "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "olive", "open-quote", "optimizeLegibility",
"optimizeSpeed", "orange", "oriya", "oromo", "outset", "outside", "overlay", "overline", "padding", "padding-box", "painted", "paused",
"persian", "plus-darker", "plus-lighter", "pointer", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "purple",
"push-button", "radio", "read-only", "read-write", "read-write-plaintext-only", "red", "relative", "repeat", "repeat-x",
"repeat-y", "reset", "reverse", "rgb", "rgba", "ridge", "right", "round", "row-resize", "rtl", "run-in", "running", "s-resize", "sans-serif",
"scroll", "scrollbar", "se-resize", "searchfield", "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
"searchfield-results-decoration", "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", "silver", "single",
"skip-white-space", "slide", "slider-horizontal", "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "solid", "somali", "source-atop", "source-in", "source-out", "source-over",
"space", "square", "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub", "subpixel-antialiased", "super",
"sw-resize", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group",
"table-row", "table-row-group", "teal", "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", "thick", "thin",
"threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", "tigrinya-er-abegede",
"tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-greek",
"upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible",
"visibleFill", "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider", "window", "windowframe", "windowtext",
"x-large", "x-small", "xor", "xx-large", "xx-small", "yellow", "-wap-marquee", "-webkit-activelink", "-webkit-auto", "-webkit-baseline-middle",
"-webkit-body", "-webkit-box", "-webkit-center", "-webkit-control", "-webkit-focus-ring-color", "-webkit-grab", "-webkit-grabbing",
"-webkit-gradient", "-webkit-inline-box", "-webkit-left", "-webkit-link", "-webkit-marquee", "-webkit-mini-control", "-webkit-nowrap", "-webkit-right",
"-webkit-small-control", "-webkit-text", "-webkit-xxx-large", "-webkit-zoom-in", "-webkit-zoom-out",
].keySet();

this._mediaTypes = ["all", "aural", "braille", "embossed", "handheld", "import", "print", "projection", "screen", "tty", "tv"].keySet();

this._lexConditions = {
INITIAL: 0,
COMMENT: 1,
DSTRING: 2,
SSTRING: 3
};

this._parseConditions = {
INITIAL: 0,
PROPERTY: 1,
PROPERTY_VALUE: 2,
AT_RULE: 3
};

this.case_INITIAL = 1000;
this.case_COMMENT = 1002;
this.case_DSTRING = 1003;
this.case_SSTRING = 1004;

this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL }
}

WebInspector.SourceCSSTokenizer.prototype = {
_stringToken: function(cursor, stringEnds)
{
if (this._isPropertyValue())
this.tokenType = "css-string";
else
this.tokenType = null;
return cursor;
},

_isPropertyValue: function()
{
return this._condition.parseCondition === this._parseConditions.PROPERTY_VALUE || this._condition.parseCondition === this._parseConditions.AT_RULE;
},

nextToken: function(cursor)
{
var cursorOnEnter = cursor;
var gotoCase = 1;
while (1) {
switch (gotoCase)


{
case 1: var yych;
var yyaccept = 0;
if (this.getLexCondition() < 2) {
if (this.getLexCondition() < 1) {
{ gotoCase = this.case_INITIAL; continue; };
} else {
{ gotoCase = this.case_COMMENT; continue; };
}
} else {
if (this.getLexCondition() < 3) {
{ gotoCase = this.case_DSTRING; continue; };
} else {
{ gotoCase = this.case_SSTRING; continue; };
}
}

case this.case_COMMENT:

yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 4; continue; };
{ gotoCase = 3; continue; };
} else {
if (yych <= '\r') { gotoCase = 4; continue; };
if (yych == '*') { gotoCase = 6; continue; };
{ gotoCase = 3; continue; };
}
case 2:
{ this.tokenType = "css-comment"; return cursor; }
case 3:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 12; continue; };
case 4:
++cursor;
{ this.tokenType = null; return cursor; }
case 6:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '*') { gotoCase = 9; continue; };
if (yych != '/') { gotoCase = 11; continue; };
case 7:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{ this.tokenType = "css-comment"; return cursor; }
case 9:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 9; continue; };
if (yych == '/') { gotoCase = 7; continue; };
case 11:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 12:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 2; continue; };
{ gotoCase = 11; continue; };
} else {
if (yych <= '\r') { gotoCase = 2; continue; };
if (yych == '*') { gotoCase = 9; continue; };
{ gotoCase = 11; continue; };
}

case this.case_DSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 17; continue; };
if (yych <= '\f') { gotoCase = 16; continue; };
{ gotoCase = 17; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 16; continue; };
{ gotoCase = 19; continue; };
} else {
if (yych == '\\') { gotoCase = 21; continue; };
{ gotoCase = 16; continue; };
}
}
case 15:
{ return this._stringToken(cursor); }
case 16:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 23; continue; };
case 17:
++cursor;
case 18:
{ this.tokenType = null; return cursor; }
case 19:
++cursor;
case 20:
this.setLexCondition(this._lexConditions.INITIAL);
{ return this._stringToken(cursor, true); }
case 21:
yych = this._charAt(++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 22; continue; };
if (yych <= '&') { gotoCase = 18; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 18; continue; };
} else {
if (yych != 'b') { gotoCase = 18; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 18; continue; };
} else {
if (yych <= 'n') { gotoCase = 22; continue; };
if (yych <= 'q') { gotoCase = 18; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 18; continue; };
} else {
if (yych != 'v') { gotoCase = 18; continue; };
}
}
}
case 22:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 23:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 15; continue; };
if (yych <= '\f') { gotoCase = 22; continue; };
{ gotoCase = 15; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 22; continue; };
{ gotoCase = 26; continue; };
} else {
if (yych != '\\') { gotoCase = 22; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 22; continue; };
if (yych >= '\'') { gotoCase = 22; continue; };
} else {
if (yych <= '\\') {
if (yych >= '\\') { gotoCase = 22; continue; };
} else {
if (yych == 'b') { gotoCase = 22; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 22; continue; };
} else {
if (yych <= 'n') { gotoCase = 22; continue; };
if (yych >= 'r') { gotoCase = 22; continue; };
}
} else {
if (yych <= 't') {
if (yych >= 't') { gotoCase = 22; continue; };
} else {
if (yych == 'v') { gotoCase = 22; continue; };
}
}
}
cursor = YYMARKER;
{ gotoCase = 15; continue; };
case 26:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 20; continue; };

case this.case_INITIAL:
yych = this._charAt(cursor);
if (yych <= ';') {
if (yych <= '\'') {
if (yych <= '"') {
if (yych <= ' ') { gotoCase = 29; continue; };
if (yych <= '!') { gotoCase = 31; continue; };
{ gotoCase = 33; continue; };
} else {
if (yych == '$') { gotoCase = 31; continue; };
if (yych >= '\'') { gotoCase = 34; continue; };
}
} else {
if (yych <= '.') {
if (yych <= ',') { gotoCase = 29; continue; };
if (yych <= '-') { gotoCase = 35; continue; };
{ gotoCase = 36; continue; };
} else {
if (yych <= '/') { gotoCase = 37; continue; };
if (yych <= '9') { gotoCase = 38; continue; };
if (yych <= ':') { gotoCase = 40; continue; };
{ gotoCase = 42; continue; };
}
}
} else {
if (yych <= '^') {
if (yych <= '?') {
if (yych == '=') { gotoCase = 31; continue; };
} else {
if (yych == '\\') { gotoCase = 29; continue; };
if (yych <= ']') { gotoCase = 31; continue; };
}
} else {
if (yych <= 'z') {
if (yych != '`') { gotoCase = 31; continue; };
} else {
if (yych <= '{') { gotoCase = 44; continue; };
if (yych == '}') { gotoCase = 46; continue; };
}
}
}
case 29:
++cursor;
case 30:
{ this.tokenType = null; return cursor; }
case 31:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 49; continue; };
case 32:
{
var token = this._line.substring(cursorOnEnter, cursor);
if (this._condition.parseCondition === this._parseConditions.INITIAL) {
if (token === "@import" || token === "@media") {
this.tokenType = "css-at-rule";
this._condition.parseCondition = this._parseConditions.AT_RULE;
} else if (token.indexOf("@") === 0)
this.tokenType = "css-at-rule";
else
this.tokenType = "css-selector";
}
else if (this._condition.parseCondition === this._parseConditions.AT_RULE && token in this._mediaTypes)
this.tokenType = "css-keyword";
else if (this._condition.parseCondition === this._parseConditions.PROPERTY && token in this._propertyKeywords)
this.tokenType = "css-property";
else if (this._isPropertyValue() && token in this._valueKeywords)
this.tokenType = "css-keyword";
else if (token === "!important")
this.tokenType = "css-important";
else
this.tokenType = null;
return cursor;
}
case 33:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '-') {
if (yych <= '!') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 124; continue; };
{ gotoCase = 122; continue; };
}
} else {
if (yych <= '$') {
if (yych <= '"') { gotoCase = 114; continue; };
if (yych <= '#') { gotoCase = 124; continue; };
{ gotoCase = 122; continue; };
} else {
if (yych == '\'') { gotoCase = 122; continue; };
if (yych <= ',') { gotoCase = 124; continue; };
{ gotoCase = 122; continue; };
}
}
} else {
if (yych <= '[') {
if (yych <= '<') {
if (yych <= '.') { gotoCase = 124; continue; };
if (yych <= '9') { gotoCase = 122; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '=') { gotoCase = 122; continue; };
if (yych <= '?') { gotoCase = 124; continue; };
{ gotoCase = 122; continue; };
}
} else {
if (yych <= '^') {
if (yych <= '\\') { gotoCase = 126; continue; };
if (yych <= ']') { gotoCase = 122; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych == '`') { gotoCase = 124; continue; };
if (yych <= 'z') { gotoCase = 122; continue; };
{ gotoCase = 124; continue; };
}
}
}
case 34:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '-') {
if (yych <= '"') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 116; continue; };
{ gotoCase = 112; continue; };
}
} else {
if (yych <= '&') {
if (yych == '$') { gotoCase = 112; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych <= '\'') { gotoCase = 114; continue; };
if (yych <= ',') { gotoCase = 116; continue; };
{ gotoCase = 112; continue; };
}
}
} else {
if (yych <= '[') {
if (yych <= '<') {
if (yych <= '.') { gotoCase = 116; continue; };
if (yych <= '9') { gotoCase = 112; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych <= '=') { gotoCase = 112; continue; };
if (yych <= '?') { gotoCase = 116; continue; };
{ gotoCase = 112; continue; };
}
} else {
if (yych <= '^') {
if (yych <= '\\') { gotoCase = 118; continue; };
if (yych <= ']') { gotoCase = 112; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych == '`') { gotoCase = 116; continue; };
if (yych <= 'z') { gotoCase = 112; continue; };
{ gotoCase = 116; continue; };
}
}
}
case 35:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '.') { gotoCase = 65; continue; };
if (yych <= '/') { gotoCase = 49; continue; };
if (yych <= '9') { gotoCase = 50; continue; };
{ gotoCase = 49; continue; };
case 36:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 30; continue; };
if (yych <= '9') { gotoCase = 68; continue; };
{ gotoCase = 30; continue; };
case 37:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '*') { gotoCase = 104; continue; };
{ gotoCase = 49; continue; };
case 38:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
switch (yych) {
case '!':
case '"':
case '$':
case '\'':
case '-':
case '/':
case '=':
case '@':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '[':
case ']':
case 'a':
case 'b':
case 'f':
case 'h':
case 'j':
case 'l':
case 'n':
case 'o':
case 'q':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':    { gotoCase = 48; continue; };
case '%':    { gotoCase = 67; continue; };
case '.':    { gotoCase = 65; continue; };
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':    { gotoCase = 50; continue; };
case 'H':    { gotoCase = 52; continue; };
case '_':    { gotoCase = 53; continue; };
case 'c':    { gotoCase = 54; continue; };
case 'd':    { gotoCase = 55; continue; };
case 'e':    { gotoCase = 56; continue; };
case 'g':    { gotoCase = 57; continue; };
case 'i':    { gotoCase = 58; continue; };
case 'k':    { gotoCase = 59; continue; };
case 'm':    { gotoCase = 60; continue; };
case 'p':    { gotoCase = 61; continue; };
case 'r':    { gotoCase = 62; continue; };
case 's':    { gotoCase = 63; continue; };
case 't':    { gotoCase = 64; continue; };
default:    { gotoCase = 39; continue; };
}
case 39:
{
if (this._isPropertyValue())
this.tokenType = "css-number";
else
this.tokenType = null;
return cursor;
}
case 40:
++cursor;
{
this.tokenType = null;
if (this._condition.parseCondition === this._parseConditions.PROPERTY)
this._condition.parseCondition = this._parseConditions.PROPERTY_VALUE;
return cursor;
}
case 42:
++cursor;
{
this.tokenType = null;
if (this._condition.parseCondition === this._parseConditions.AT_RULE)
this._condition.parseCondition = this._parseConditions.INITIAL;
else
this._condition.parseCondition = this._parseConditions.PROPERTY;
return cursor;
}
case 44:
++cursor;
{
this.tokenType = null;
if (this._condition.parseCondition === this._parseConditions.AT_RULE)
this._condition.parseCondition = this._parseConditions.INITIAL;
else
this._condition.parseCondition = this._parseConditions.PROPERTY;
return cursor;
}
case 46:
++cursor;
{
this.tokenType = null;
this._condition.parseCondition = this._parseConditions.INITIAL;
return cursor;
}
case 48:
++cursor;
yych = this._charAt(cursor);
case 49:
if (yych <= '9') {
if (yych <= '&') {
if (yych <= '"') {
if (yych <= ' ') { gotoCase = 32; continue; };
{ gotoCase = 48; continue; };
} else {
if (yych == '$') { gotoCase = 48; continue; };
{ gotoCase = 32; continue; };
}
} else {
if (yych <= ',') {
if (yych <= '\'') { gotoCase = 48; continue; };
{ gotoCase = 32; continue; };
} else {
if (yych == '.') { gotoCase = 32; continue; };
{ gotoCase = 48; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '<') { gotoCase = 32; continue; };
{ gotoCase = 48; continue; };
} else {
if (yych <= '?') { gotoCase = 32; continue; };
if (yych <= '[') { gotoCase = 48; continue; };
{ gotoCase = 32; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 32; continue; };
{ gotoCase = 48; continue; };
} else {
if (yych <= '`') { gotoCase = 32; continue; };
if (yych <= 'z') { gotoCase = 48; continue; };
{ gotoCase = 32; continue; };
}
}
}
case 50:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
switch (yych) {
case '!':
case '"':
case '$':
case '\'':
case '-':
case '/':
case '=':
case '@':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '[':
case ']':
case 'a':
case 'b':
case 'f':
case 'h':
case 'j':
case 'l':
case 'n':
case 'o':
case 'q':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':    { gotoCase = 48; continue; };
case '%':    { gotoCase = 67; continue; };
case '.':    { gotoCase = 65; continue; };
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':    { gotoCase = 50; continue; };
case 'H':    { gotoCase = 52; continue; };
case '_':    { gotoCase = 53; continue; };
case 'c':    { gotoCase = 54; continue; };
case 'd':    { gotoCase = 55; continue; };
case 'e':    { gotoCase = 56; continue; };
case 'g':    { gotoCase = 57; continue; };
case 'i':    { gotoCase = 58; continue; };
case 'k':    { gotoCase = 59; continue; };
case 'm':    { gotoCase = 60; continue; };
case 'p':    { gotoCase = 61; continue; };
case 'r':    { gotoCase = 62; continue; };
case 's':    { gotoCase = 63; continue; };
case 't':    { gotoCase = 64; continue; };
default:    { gotoCase = 39; continue; };
}
case 52:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 53:
yych = this._charAt(++cursor);
if (yych == '_') { gotoCase = 101; continue; };
{ gotoCase = 49; continue; };
case 54:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 55:
yych = this._charAt(++cursor);
if (yych == 'e') { gotoCase = 100; continue; };
{ gotoCase = 49; continue; };
case 56:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 63; continue; };
if (yych == 'x') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 57:
yych = this._charAt(++cursor);
if (yych == 'r') { gotoCase = 98; continue; };
{ gotoCase = 49; continue; };
case 58:
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 59:
yych = this._charAt(++cursor);
if (yych == 'H') { gotoCase = 97; continue; };
{ gotoCase = 49; continue; };
case 60:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 63; continue; };
if (yych == 's') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 61:
yych = this._charAt(++cursor);
if (yych <= 's') {
if (yych == 'c') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
} else {
if (yych <= 't') { gotoCase = 63; continue; };
if (yych == 'x') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
}
case 62:
yych = this._charAt(++cursor);
if (yych == 'a') { gotoCase = 95; continue; };
if (yych == 'e') { gotoCase = 96; continue; };
{ gotoCase = 49; continue; };
case 63:
yych = this._charAt(++cursor);
if (yych <= '9') {
if (yych <= '&') {
if (yych <= '"') {
if (yych <= ' ') { gotoCase = 39; continue; };
{ gotoCase = 48; continue; };
} else {
if (yych == '$') { gotoCase = 48; continue; };
{ gotoCase = 39; continue; };
}
} else {
if (yych <= ',') {
if (yych <= '\'') { gotoCase = 48; continue; };
{ gotoCase = 39; continue; };
} else {
if (yych == '.') { gotoCase = 39; continue; };
{ gotoCase = 48; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '<') { gotoCase = 39; continue; };
{ gotoCase = 48; continue; };
} else {
if (yych <= '?') { gotoCase = 39; continue; };
if (yych <= '[') { gotoCase = 48; continue; };
{ gotoCase = 39; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 39; continue; };
{ gotoCase = 48; continue; };
} else {
if (yych <= '`') { gotoCase = 39; continue; };
if (yych <= 'z') { gotoCase = 48; continue; };
{ gotoCase = 39; continue; };
}
}
}
case 64:
yych = this._charAt(++cursor);
if (yych == 'u') { gotoCase = 93; continue; };
{ gotoCase = 49; continue; };
case 65:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 66; continue; };
if (yych <= '9') { gotoCase = 68; continue; };
case 66:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 32; continue; };
} else {
{ gotoCase = 39; continue; };
}
case 67:
yych = this._charAt(++cursor);
{ gotoCase = 39; continue; };
case 68:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'f') {
if (yych <= 'H') {
if (yych <= '/') {
if (yych == '%') { gotoCase = 67; continue; };
{ gotoCase = 39; continue; };
} else {
if (yych <= '9') { gotoCase = 68; continue; };
if (yych <= 'G') { gotoCase = 39; continue; };
{ gotoCase = 80; continue; };
}
} else {
if (yych <= 'b') {
if (yych == '_') { gotoCase = 72; continue; };
{ gotoCase = 39; continue; };
} else {
if (yych <= 'c') { gotoCase = 74; continue; };
if (yych <= 'd') { gotoCase = 77; continue; };
if (yych >= 'f') { gotoCase = 39; continue; };
}
}
} else {
if (yych <= 'm') {
if (yych <= 'i') {
if (yych <= 'g') { gotoCase = 78; continue; };
if (yych <= 'h') { gotoCase = 39; continue; };
{ gotoCase = 76; continue; };
} else {
if (yych == 'k') { gotoCase = 81; continue; };
if (yych <= 'l') { gotoCase = 39; continue; };
{ gotoCase = 75; continue; };
}
} else {
if (yych <= 'q') {
if (yych == 'p') { gotoCase = 73; continue; };
{ gotoCase = 39; continue; };
} else {
if (yych <= 'r') { gotoCase = 71; continue; };
if (yych <= 's') { gotoCase = 67; continue; };
if (yych <= 't') { gotoCase = 79; continue; };
{ gotoCase = 39; continue; };
}
}
}
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 67; continue; };
if (yych == 'x') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 71:
yych = this._charAt(++cursor);
if (yych == 'a') { gotoCase = 91; continue; };
if (yych == 'e') { gotoCase = 92; continue; };
{ gotoCase = 66; continue; };
case 72:
yych = this._charAt(++cursor);
if (yych == '_') { gotoCase = 88; continue; };
{ gotoCase = 66; continue; };
case 73:
yych = this._charAt(++cursor);
if (yych <= 's') {
if (yych == 'c') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
} else {
if (yych <= 't') { gotoCase = 67; continue; };
if (yych == 'x') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
}
case 74:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 75:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 67; continue; };
if (yych == 's') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 76:
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 77:
yych = this._charAt(++cursor);
if (yych == 'e') { gotoCase = 87; continue; };
{ gotoCase = 66; continue; };
case 78:
yych = this._charAt(++cursor);
if (yych == 'r') { gotoCase = 85; continue; };
{ gotoCase = 66; continue; };
case 79:
yych = this._charAt(++cursor);
if (yych == 'u') { gotoCase = 83; continue; };
{ gotoCase = 66; continue; };
case 80:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 81:
yych = this._charAt(++cursor);
if (yych != 'H') { gotoCase = 66; continue; };
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 83:
yych = this._charAt(++cursor);
if (yych != 'r') { gotoCase = 66; continue; };
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 85:
yych = this._charAt(++cursor);
if (yych != 'a') { gotoCase = 66; continue; };
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 87:
yych = this._charAt(++cursor);
if (yych == 'g') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 88:
yych = this._charAt(++cursor);
if (yych != 'q') { gotoCase = 66; continue; };
yych = this._charAt(++cursor);
if (yych != 'e') { gotoCase = 66; continue; };
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 91:
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 92:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 67; continue; };
{ gotoCase = 66; continue; };
case 93:
yych = this._charAt(++cursor);
if (yych != 'r') { gotoCase = 49; continue; };
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 95:
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 96:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 97:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 98:
yych = this._charAt(++cursor);
if (yych != 'a') { gotoCase = 49; continue; };
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 100:
yych = this._charAt(++cursor);
if (yych == 'g') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 101:
yych = this._charAt(++cursor);
if (yych != 'q') { gotoCase = 49; continue; };
yych = this._charAt(++cursor);
if (yych != 'e') { gotoCase = 49; continue; };
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 63; continue; };
{ gotoCase = 49; continue; };
case 104:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 108; continue; };
{ gotoCase = 104; continue; };
} else {
if (yych <= '\r') { gotoCase = 108; continue; };
if (yych != '*') { gotoCase = 104; continue; };
}
case 106:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 106; continue; };
if (yych == '/') { gotoCase = 110; continue; };
{ gotoCase = 104; continue; };
case 108:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "css-comment"; return cursor; }
case 110:
++cursor;
{ this.tokenType = "css-comment"; return cursor; }
case 112:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '-') {
if (yych <= '"') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 116; continue; };
{ gotoCase = 112; continue; };
}
} else {
if (yych <= '&') {
if (yych == '$') { gotoCase = 112; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych <= '\'') { gotoCase = 114; continue; };
if (yych <= ',') { gotoCase = 116; continue; };
{ gotoCase = 112; continue; };
}
}
} else {
if (yych <= '[') {
if (yych <= '<') {
if (yych <= '.') { gotoCase = 116; continue; };
if (yych <= '9') { gotoCase = 112; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych <= '=') { gotoCase = 112; continue; };
if (yych <= '?') { gotoCase = 116; continue; };
{ gotoCase = 112; continue; };
}
} else {
if (yych <= '^') {
if (yych <= '\\') { gotoCase = 118; continue; };
if (yych <= ']') { gotoCase = 112; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych == '`') { gotoCase = 116; continue; };
if (yych <= 'z') { gotoCase = 112; continue; };
{ gotoCase = 116; continue; };
}
}
}
case 114:
++cursor;
if ((yych = this._charAt(cursor)) <= '9') {
if (yych <= '&') {
if (yych <= '"') {
if (yych >= '!') { gotoCase = 48; continue; };
} else {
if (yych == '$') { gotoCase = 48; continue; };
}
} else {
if (yych <= ',') {
if (yych <= '\'') { gotoCase = 48; continue; };
} else {
if (yych != '.') { gotoCase = 48; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych >= '=') { gotoCase = 48; continue; };
} else {
if (yych <= '?') { gotoCase = 115; continue; };
if (yych <= '[') { gotoCase = 48; continue; };
}
} else {
if (yych <= '_') {
if (yych != '^') { gotoCase = 48; continue; };
} else {
if (yych <= '`') { gotoCase = 115; continue; };
if (yych <= 'z') { gotoCase = 48; continue; };
}
}
}
case 115:
{ return this._stringToken(cursor, true); }
case 116:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 66; continue; };
if (yych <= '\f') { gotoCase = 116; continue; };
{ gotoCase = 66; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 116; continue; };
{ gotoCase = 121; continue; };
} else {
if (yych != '\\') { gotoCase = 116; continue; };
}
}
case 118:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 66; continue; };
} else {
if (yych != '\r') { gotoCase = 66; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 116; continue; };
if (yych <= '&') { gotoCase = 66; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych == '\\') { gotoCase = 116; continue; };
{ gotoCase = 66; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 116; continue; };
if (yych <= 'e') { gotoCase = 66; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych == 'n') { gotoCase = 116; continue; };
{ gotoCase = 66; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 66; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych == 'v') { gotoCase = 116; continue; };
{ gotoCase = 66; continue; };
}
}
}
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ return this._stringToken(cursor); }
case 121:
yych = this._charAt(++cursor);
{ gotoCase = 115; continue; };
case 122:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '-') {
if (yych <= '!') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych >= '!') { gotoCase = 122; continue; };
}
} else {
if (yych <= '$') {
if (yych <= '"') { gotoCase = 114; continue; };
if (yych >= '$') { gotoCase = 122; continue; };
} else {
if (yych == '\'') { gotoCase = 122; continue; };
if (yych >= '-') { gotoCase = 122; continue; };
}
}
} else {
if (yych <= '[') {
if (yych <= '<') {
if (yych <= '.') { gotoCase = 124; continue; };
if (yych <= '9') { gotoCase = 122; continue; };
} else {
if (yych <= '=') { gotoCase = 122; continue; };
if (yych >= '@') { gotoCase = 122; continue; };
}
} else {
if (yych <= '^') {
if (yych <= '\\') { gotoCase = 126; continue; };
if (yych <= ']') { gotoCase = 122; continue; };
} else {
if (yych == '`') { gotoCase = 124; continue; };
if (yych <= 'z') { gotoCase = 122; continue; };
}
}
}
case 124:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 66; continue; };
if (yych <= '\f') { gotoCase = 124; continue; };
{ gotoCase = 66; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 124; continue; };
{ gotoCase = 121; continue; };
} else {
if (yych != '\\') { gotoCase = 124; continue; };
}
}
case 126:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 66; continue; };
} else {
if (yych != '\r') { gotoCase = 66; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 124; continue; };
if (yych <= '&') { gotoCase = 66; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych == '\\') { gotoCase = 124; continue; };
{ gotoCase = 66; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 124; continue; };
if (yych <= 'e') { gotoCase = 66; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych == 'n') { gotoCase = 124; continue; };
{ gotoCase = 66; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 66; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych == 'v') { gotoCase = 124; continue; };
{ gotoCase = 66; continue; };
}
}
}
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ return this._stringToken(cursor); }

case this.case_SSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 133; continue; };
if (yych <= '\f') { gotoCase = 132; continue; };
{ gotoCase = 133; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 132; continue; };
{ gotoCase = 135; continue; };
} else {
if (yych == '\\') { gotoCase = 137; continue; };
{ gotoCase = 132; continue; };
}
}
case 131:
{ return this._stringToken(cursor); }
case 132:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 139; continue; };
case 133:
++cursor;
case 134:
{ this.tokenType = null; return cursor; }
case 135:
++cursor;
case 136:
this.setLexCondition(this._lexConditions.INITIAL);
{ return this._stringToken(cursor, true); }
case 137:
yych = this._charAt(++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 138; continue; };
if (yych <= '&') { gotoCase = 134; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 134; continue; };
} else {
if (yych != 'b') { gotoCase = 134; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 134; continue; };
} else {
if (yych <= 'n') { gotoCase = 138; continue; };
if (yych <= 'q') { gotoCase = 134; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 134; continue; };
} else {
if (yych != 'v') { gotoCase = 134; continue; };
}
}
}
case 138:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 139:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 131; continue; };
if (yych <= '\f') { gotoCase = 138; continue; };
{ gotoCase = 131; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 138; continue; };
{ gotoCase = 142; continue; };
} else {
if (yych != '\\') { gotoCase = 138; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 138; continue; };
if (yych >= '\'') { gotoCase = 138; continue; };
} else {
if (yych <= '\\') {
if (yych >= '\\') { gotoCase = 138; continue; };
} else {
if (yych == 'b') { gotoCase = 138; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 138; continue; };
} else {
if (yych <= 'n') { gotoCase = 138; continue; };
if (yych >= 'r') { gotoCase = 138; continue; };
}
} else {
if (yych <= 't') {
if (yych >= 't') { gotoCase = 138; continue; };
} else {
if (yych == 'v') { gotoCase = 138; continue; };
}
}
}
cursor = YYMARKER;
{ gotoCase = 131; continue; };
case 142:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 136; continue; };
}

}
}
}

WebInspector.SourceCSSTokenizer.prototype.__proto__ = WebInspector.SourceTokenizer.prototype;


















WebInspector.SourceHTMLTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);


this._lexConditions = {
INITIAL: 0,
COMMENT: 1,
DOCTYPE: 2,
TAG: 3,
DSTRING: 4,
SSTRING: 5
};
this.case_INITIAL = 1000;
this.case_COMMENT = 1001;
this.case_DOCTYPE = 1002;
this.case_TAG = 1003;
this.case_DSTRING = 1004;
this.case_SSTRING = 1005;

this._parseConditions = {
INITIAL: 0,
ATTRIBUTE: 1,
ATTRIBUTE_VALUE: 2,
LINKIFY: 4,
A_NODE: 8,
SCRIPT: 16
};

this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
this.condition = this.initialCondition;
}

WebInspector.SourceHTMLTokenizer.prototype = {
set line(line) {
if (this._internalJavaScriptTokenizer) {
var match = /<\/script/i.exec(line);
if (match) {
this._internalJavaScriptTokenizer.line = line.substring(0, match.index);
} else
this._internalJavaScriptTokenizer.line = line;
}
this._line = line;
},

_isExpectingAttribute: function()
{
return this._condition.parseCondition & this._parseConditions.ATTRIBUTE;
},

_isExpectingAttributeValue: function()
{
return this._condition.parseCondition & this._parseConditions.ATTRIBUTE_VALUE;
},

_setExpectingAttribute: function()
{
if (this._isExpectingAttributeValue())
this._condition.parseCondition ^= this._parseConditions.ATTRIBUTE_VALUE;
this._condition.parseCondition |= this._parseConditions.ATTRIBUTE;
},

_setExpectingAttributeValue: function()
{
if (this._isExpectingAttribute())
this._condition.parseCondition ^= this._parseConditions.ATTRIBUTE;
this._condition.parseCondition |= this._parseConditions.ATTRIBUTE_VALUE;
},

_stringToken: function(cursor, stringEnds)
{
if (!this._isExpectingAttributeValue()) {
this.tokenType = null;
return cursor;
}
this.tokenType = this._attrValueTokenType();
if (stringEnds)
this._setExpectingAttribute();
return cursor;
},

_attrValueTokenType: function()
{
if (this._condition.parseCondition & this._parseConditions.LINKIFY) {
if (this._condition.parseCondition & this._parseConditions.A_NODE)
return "html-external-link";
return "html-resource-link";
}
return "html-attribute-value";
},

nextToken: function(cursor)
{
if (this._internalJavaScriptTokenizer) {

this.line = this._line;
if (cursor !== this._internalJavaScriptTokenizer._line.length) {

this._internalJavaScriptTokenizer.condition = this._condition.internalJavaScriptTokenizerCondition;
var result = this._internalJavaScriptTokenizer.nextToken(cursor);
this.tokenType = this._internalJavaScriptTokenizer.tokenType;
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.condition;
return result;
} else if (cursor !== this._line.length)
delete this._internalJavaScriptTokenizer;
}

var cursorOnEnter = cursor;
var gotoCase = 1;
while (1) {
switch (gotoCase)


{
case 1: var yych;
var yyaccept = 0;
if (this.getLexCondition() < 3) {
if (this.getLexCondition() < 1) {
{ gotoCase = this.case_INITIAL; continue; };
} else {
if (this.getLexCondition() < 2) {
{ gotoCase = this.case_COMMENT; continue; };
} else {
{ gotoCase = this.case_DOCTYPE; continue; };
}
}
} else {
if (this.getLexCondition() < 4) {
{ gotoCase = this.case_TAG; continue; };
} else {
if (this.getLexCondition() < 5) {
{ gotoCase = this.case_DSTRING; continue; };
} else {
{ gotoCase = this.case_SSTRING; continue; };
}
}
}

case this.case_COMMENT:

yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 4; continue; };
{ gotoCase = 3; continue; };
} else {
if (yych <= '\r') { gotoCase = 4; continue; };
if (yych == '-') { gotoCase = 6; continue; };
{ gotoCase = 3; continue; };
}
case 2:
{ this.tokenType = "html-comment"; return cursor; }
case 3:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 9; continue; };
case 4:
++cursor;
case 5:
{ this.tokenType = null; return cursor; }
case 6:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych != '-') { gotoCase = 5; continue; };
case 7:
++cursor;
yych = this._charAt(cursor);
if (yych == '>') { gotoCase = 10; continue; };
case 8:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 9:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 2; continue; };
{ gotoCase = 8; continue; };
} else {
if (yych <= '\r') { gotoCase = 2; continue; };
if (yych == '-') { gotoCase = 12; continue; };
{ gotoCase = 8; continue; };
}
case 10:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{ this.tokenType = "html-comment"; return cursor; }
case 12:
++cursor;
yych = this._charAt(cursor);
if (yych == '-') { gotoCase = 7; continue; };
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 2; continue; };
} else {
{ gotoCase = 5; continue; };
}

case this.case_DOCTYPE:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 18; continue; };
{ gotoCase = 17; continue; };
} else {
if (yych <= '\r') { gotoCase = 18; continue; };
if (yych == '>') { gotoCase = 20; continue; };
{ gotoCase = 17; continue; };
}
case 16:
{ this.tokenType = "html-doctype"; return cursor; }
case 17:
yych = this._charAt(++cursor);
{ gotoCase = 23; continue; };
case 18:
++cursor;
{ this.tokenType = null; return cursor; }
case 20:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{ this.tokenType = "html-doctype"; return cursor; }
case 22:
++cursor;
yych = this._charAt(cursor);
case 23:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 16; continue; };
{ gotoCase = 22; continue; };
} else {
if (yych <= '\r') { gotoCase = 16; continue; };
if (yych == '>') { gotoCase = 16; continue; };
{ gotoCase = 22; continue; };
}

case this.case_DSTRING:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 28; continue; };
{ gotoCase = 27; continue; };
} else {
if (yych <= '\r') { gotoCase = 28; continue; };
if (yych == '"') { gotoCase = 30; continue; };
{ gotoCase = 27; continue; };
}
case 26:
{ return this._stringToken(cursor); }
case 27:
yych = this._charAt(++cursor);
{ gotoCase = 34; continue; };
case 28:
++cursor;
{ this.tokenType = null; return cursor; }
case 30:
++cursor;
case 31:
this.setLexCondition(this._lexConditions.TAG);
{ return this._stringToken(cursor, true); }
case 32:
yych = this._charAt(++cursor);
{ gotoCase = 31; continue; };
case 33:
++cursor;
yych = this._charAt(cursor);
case 34:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 26; continue; };
{ gotoCase = 33; continue; };
} else {
if (yych <= '\r') { gotoCase = 26; continue; };
if (yych == '"') { gotoCase = 32; continue; };
{ gotoCase = 33; continue; };
}

case this.case_INITIAL:
yych = this._charAt(cursor);
if (yych == '<') { gotoCase = 39; continue; };
++cursor;
{ this.tokenType = null; return cursor; }
case 39:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '/') {
if (yych == '!') { gotoCase = 44; continue; };
if (yych >= '/') { gotoCase = 41; continue; };
} else {
if (yych <= 'S') {
if (yych >= 'S') { gotoCase = 42; continue; };
} else {
if (yych == 's') { gotoCase = 42; continue; };
}
}
case 40:
this.setLexCondition(this._lexConditions.TAG);
{
if (this._condition.parseCondition & this._parseConditions.SCRIPT) {

this.setLexCondition(this._lexConditions.INITIAL);
this.tokenType = null;
return cursor;
}

this._condition.parseCondition = this._parseConditions.INITIAL;
this.tokenType = "html-tag";
return cursor;
}
case 41:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == 'S') { gotoCase = 68; continue; };
if (yych == 's') { gotoCase = 68; continue; };
{ gotoCase = 40; continue; };
case 42:
yych = this._charAt(++cursor);
if (yych == 'C') { gotoCase = 62; continue; };
if (yych == 'c') { gotoCase = 62; continue; };
case 43:
cursor = YYMARKER;
{ gotoCase = 40; continue; };
case 44:
yych = this._charAt(++cursor);
if (yych <= 'C') {
if (yych != '-') { gotoCase = 43; continue; };
} else {
if (yych <= 'D') { gotoCase = 46; continue; };
if (yych == 'd') { gotoCase = 46; continue; };
{ gotoCase = 43; continue; };
}
yych = this._charAt(++cursor);
if (yych == '-') { gotoCase = 54; continue; };
{ gotoCase = 43; continue; };
case 46:
yych = this._charAt(++cursor);
if (yych == 'O') { gotoCase = 47; continue; };
if (yych != 'o') { gotoCase = 43; continue; };
case 47:
yych = this._charAt(++cursor);
if (yych == 'C') { gotoCase = 48; continue; };
if (yych != 'c') { gotoCase = 43; continue; };
case 48:
yych = this._charAt(++cursor);
if (yych == 'T') { gotoCase = 49; continue; };
if (yych != 't') { gotoCase = 43; continue; };
case 49:
yych = this._charAt(++cursor);
if (yych == 'Y') { gotoCase = 50; continue; };
if (yych != 'y') { gotoCase = 43; continue; };
case 50:
yych = this._charAt(++cursor);
if (yych == 'P') { gotoCase = 51; continue; };
if (yych != 'p') { gotoCase = 43; continue; };
case 51:
yych = this._charAt(++cursor);
if (yych == 'E') { gotoCase = 52; continue; };
if (yych != 'e') { gotoCase = 43; continue; };
case 52:
++cursor;
this.setLexCondition(this._lexConditions.DOCTYPE);
{ this.tokenType = "html-doctype"; return cursor; }
case 54:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 57; continue; };
{ gotoCase = 54; continue; };
} else {
if (yych <= '\r') { gotoCase = 57; continue; };
if (yych != '-') { gotoCase = 54; continue; };
}
++cursor;
yych = this._charAt(cursor);
if (yych == '-') { gotoCase = 59; continue; };
{ gotoCase = 43; continue; };
case 57:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "html-comment"; return cursor; }
case 59:
++cursor;
yych = this._charAt(cursor);
if (yych != '>') { gotoCase = 54; continue; };
++cursor;
{ this.tokenType = "html-comment"; return cursor; }
case 62:
yych = this._charAt(++cursor);
if (yych == 'R') { gotoCase = 63; continue; };
if (yych != 'r') { gotoCase = 43; continue; };
case 63:
yych = this._charAt(++cursor);
if (yych == 'I') { gotoCase = 64; continue; };
if (yych != 'i') { gotoCase = 43; continue; };
case 64:
yych = this._charAt(++cursor);
if (yych == 'P') { gotoCase = 65; continue; };
if (yych != 'p') { gotoCase = 43; continue; };
case 65:
yych = this._charAt(++cursor);
if (yych == 'T') { gotoCase = 66; continue; };
if (yych != 't') { gotoCase = 43; continue; };
case 66:
++cursor;
this.setLexCondition(this._lexConditions.TAG);
{
if (this._condition.parseCondition & this._parseConditions.SCRIPT) {

this.setLexCondition(this._lexConditions.INITIAL);
this.tokenType = null;
return cursor;
}
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.SCRIPT;
this._setExpectingAttribute();
return cursor;
}
case 68:
yych = this._charAt(++cursor);
if (yych == 'C') { gotoCase = 69; continue; };
if (yych != 'c') { gotoCase = 43; continue; };
case 69:
yych = this._charAt(++cursor);
if (yych == 'R') { gotoCase = 70; continue; };
if (yych != 'r') { gotoCase = 43; continue; };
case 70:
yych = this._charAt(++cursor);
if (yych == 'I') { gotoCase = 71; continue; };
if (yych != 'i') { gotoCase = 43; continue; };
case 71:
yych = this._charAt(++cursor);
if (yych == 'P') { gotoCase = 72; continue; };
if (yych != 'p') { gotoCase = 43; continue; };
case 72:
yych = this._charAt(++cursor);
if (yych == 'T') { gotoCase = 73; continue; };
if (yych != 't') { gotoCase = 43; continue; };
case 73:
++cursor;
this.setLexCondition(this._lexConditions.TAG);
{
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.INITIAL;
return cursor;
}

case this.case_SSTRING:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 79; continue; };
{ gotoCase = 78; continue; };
} else {
if (yych <= '\r') { gotoCase = 79; continue; };
if (yych == '\'') { gotoCase = 81; continue; };
{ gotoCase = 78; continue; };
}
case 77:
{ return this._stringToken(cursor); }
case 78:
yych = this._charAt(++cursor);
{ gotoCase = 85; continue; };
case 79:
++cursor;
{ this.tokenType = null; return cursor; }
case 81:
++cursor;
case 82:
this.setLexCondition(this._lexConditions.TAG);
{ return this._stringToken(cursor, true); }
case 83:
yych = this._charAt(++cursor);
{ gotoCase = 82; continue; };
case 84:
++cursor;
yych = this._charAt(cursor);
case 85:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 77; continue; };
{ gotoCase = 84; continue; };
} else {
if (yych <= '\r') { gotoCase = 77; continue; };
if (yych == '\'') { gotoCase = 83; continue; };
{ gotoCase = 84; continue; };
}

case this.case_TAG:
yych = this._charAt(cursor);
if (yych <= '&') {
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 90; continue; };
if (yych >= '\r') { gotoCase = 90; continue; };
} else {
if (yych <= ' ') {
if (yych >= ' ') { gotoCase = 90; continue; };
} else {
if (yych == '"') { gotoCase = 92; continue; };
}
}
} else {
if (yych <= '>') {
if (yych <= ';') {
if (yych <= '\'') { gotoCase = 93; continue; };
} else {
if (yych <= '<') { gotoCase = 90; continue; };
if (yych <= '=') { gotoCase = 94; continue; };
{ gotoCase = 96; continue; };
}
} else {
if (yych <= '[') {
if (yych >= '[') { gotoCase = 90; continue; };
} else {
if (yych == ']') { gotoCase = 90; continue; };
}
}
}
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 109; continue; };
case 89:
{
if (this._condition.parseCondition === this._parseConditions.SCRIPT) {

this.tokenType = null;
return cursor;
}

if (this._condition.parseCondition === this._parseConditions.INITIAL) {
this.tokenType = "html-tag";
this._setExpectingAttribute();
var token = this._line.substring(cursorOnEnter, cursor);
if (token === "a")
this._condition.parseCondition |= this._parseConditions.A_NODE;
else if (this._condition.parseCondition & this._parseConditions.A_NODE)
this._condition.parseCondition ^= this._parseConditions.A_NODE;
} else if (this._isExpectingAttribute()) {
var token = this._line.substring(cursorOnEnter, cursor);
if (token === "href" || token === "src")
this._condition.parseCondition |= this._parseConditions.LINKIFY;
else if (this._condition.parseCondition |= this._parseConditions.LINKIFY)
this._condition.parseCondition ^= this._parseConditions.LINKIFY;
this.tokenType = "html-attribute-name";
} else if (this._isExpectingAttributeValue())
this.tokenType = this._attrValueTokenType();
else
this.tokenType = null;
return cursor;
}
case 90:
++cursor;
{ this.tokenType = null; return cursor; }
case 92:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 105; continue; };
case 93:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 99; continue; };
case 94:
++cursor;
{
if (this._isExpectingAttribute())
this._setExpectingAttributeValue();
this.tokenType = null;
return cursor;
}
case 96:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{
this.tokenType = "html-tag";
if (this._condition.parseCondition & this._parseConditions.SCRIPT) {
if (!this._internalJavaScriptTokenizer) {
this._internalJavaScriptTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.initialCondition;
}

return cursor;
}

this._condition.parseCondition = this._parseConditions.INITIAL;
return cursor;
}
case 98:
++cursor;
yych = this._charAt(cursor);
case 99:
if (yych <= '\f') {
if (yych != '\n') { gotoCase = 98; continue; };
} else {
if (yych <= '\r') { gotoCase = 100; continue; };
if (yych == '\'') { gotoCase = 102; continue; };
{ gotoCase = 98; continue; };
}
case 100:
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ return this._stringToken(cursor); }
case 102:
++cursor;
{ return this._stringToken(cursor, true); }
case 104:
++cursor;
yych = this._charAt(cursor);
case 105:
if (yych <= '\f') {
if (yych != '\n') { gotoCase = 104; continue; };
} else {
if (yych <= '\r') { gotoCase = 106; continue; };
if (yych == '"') { gotoCase = 102; continue; };
{ gotoCase = 104; continue; };
}
case 106:
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ return this._stringToken(cursor); }
case 108:
++cursor;
yych = this._charAt(cursor);
case 109:
if (yych <= '"') {
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 89; continue; };
if (yych <= '\f') { gotoCase = 108; continue; };
{ gotoCase = 89; continue; };
} else {
if (yych == ' ') { gotoCase = 89; continue; };
if (yych <= '!') { gotoCase = 108; continue; };
{ gotoCase = 89; continue; };
}
} else {
if (yych <= '>') {
if (yych == '\'') { gotoCase = 89; continue; };
if (yych <= ';') { gotoCase = 108; continue; };
{ gotoCase = 89; continue; };
} else {
if (yych <= '[') {
if (yych <= 'Z') { gotoCase = 108; continue; };
{ gotoCase = 89; continue; };
} else {
if (yych == ']') { gotoCase = 89; continue; };
{ gotoCase = 108; continue; };
}
}
}
}

}
}
}

WebInspector.SourceHTMLTokenizer.prototype.__proto__ = WebInspector.SourceTokenizer.prototype;


















WebInspector.SourceJavaScriptTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);

this._keywords = [
"null", "true", "false", "break", "case", "catch", "const", "default", "finally", "for",
"instanceof", "new", "var", "continue", "function", "return", "void", "delete", "if",
"this", "do", "while", "else", "in", "switch", "throw", "try", "typeof", "debugger",
"class", "enum", "export", "extends", "import", "super", "get", "set", "with"
].keySet();

this._lexConditions = {
DIV: 0,
NODIV: 1,
COMMENT: 2,
DSTRING: 3,
SSTRING: 4,
REGEX: 5
};

this.case_DIV = 1000;
this.case_NODIV = 1001;
this.case_COMMENT = 1002;
this.case_DSTRING = 1003;
this.case_SSTRING = 1004;
this.case_REGEX = 1005;

this.initialCondition = { lexCondition: this._lexConditions.NODIV }
this.condition = this.initialCondition;
}

WebInspector.SourceJavaScriptTokenizer.prototype = {
nextToken: function(cursor)
{
var cursorOnEnter = cursor;
var gotoCase = 1;
while (1) {
switch (gotoCase)


{
case 1: var yych;
var yyaccept = 0;
if (this.getLexCondition() < 3) {
if (this.getLexCondition() < 1) {
{ gotoCase = this.case_DIV; continue; };
} else {
if (this.getLexCondition() < 2) {
{ gotoCase = this.case_NODIV; continue; };
} else {
{ gotoCase = this.case_COMMENT; continue; };
}
}
} else {
if (this.getLexCondition() < 4) {
{ gotoCase = this.case_DSTRING; continue; };
} else {
if (this.getLexCondition() < 5) {
{ gotoCase = this.case_SSTRING; continue; };
} else {
{ gotoCase = this.case_REGEX; continue; };
}
}
}

case this.case_COMMENT:

yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 4; continue; };
{ gotoCase = 3; continue; };
} else {
if (yych <= '\r') { gotoCase = 4; continue; };
if (yych == '*') { gotoCase = 6; continue; };
{ gotoCase = 3; continue; };
}
case 2:
{ this.tokenType = "javascript-comment"; return cursor; }
case 3:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 12; continue; };
case 4:
++cursor;
{ this.tokenType = null; return cursor; }
case 6:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '*') { gotoCase = 9; continue; };
if (yych != '/') { gotoCase = 11; continue; };
case 7:
++cursor;
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-comment"; return cursor; }
case 9:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 9; continue; };
if (yych == '/') { gotoCase = 7; continue; };
case 11:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 12:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 2; continue; };
{ gotoCase = 11; continue; };
} else {
if (yych <= '\r') { gotoCase = 2; continue; };
if (yych == '*') { gotoCase = 9; continue; };
{ gotoCase = 11; continue; };
}

case this.case_DIV:
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych <= '(') {
if (yych <= '#') {
if (yych <= ' ') { gotoCase = 15; continue; };
if (yych <= '!') { gotoCase = 17; continue; };
if (yych <= '"') { gotoCase = 19; continue; };
} else {
if (yych <= '%') {
if (yych <= '$') { gotoCase = 20; continue; };
{ gotoCase = 22; continue; };
} else {
if (yych <= '&') { gotoCase = 23; continue; };
if (yych <= '\'') { gotoCase = 24; continue; };
{ gotoCase = 25; continue; };
}
}
} else {
if (yych <= ',') {
if (yych <= ')') { gotoCase = 26; continue; };
if (yych <= '*') { gotoCase = 28; continue; };
if (yych <= '+') { gotoCase = 29; continue; };
{ gotoCase = 25; continue; };
} else {
if (yych <= '.') {
if (yych <= '-') { gotoCase = 30; continue; };
{ gotoCase = 31; continue; };
} else {
if (yych <= '/') { gotoCase = 32; continue; };
if (yych <= '0') { gotoCase = 34; continue; };
{ gotoCase = 36; continue; };
}
}
}
} else {
if (yych <= '\\') {
if (yych <= '>') {
if (yych <= ';') { gotoCase = 25; continue; };
if (yych <= '<') { gotoCase = 37; continue; };
if (yych <= '=') { gotoCase = 38; continue; };
{ gotoCase = 39; continue; };
} else {
if (yych <= '@') {
if (yych <= '?') { gotoCase = 25; continue; };
} else {
if (yych <= 'Z') { gotoCase = 20; continue; };
if (yych <= '[') { gotoCase = 25; continue; };
{ gotoCase = 40; continue; };
}
}
} else {
if (yych <= 'z') {
if (yych <= '^') {
if (yych <= ']') { gotoCase = 25; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych != '`') { gotoCase = 20; continue; };
}
} else {
if (yych <= '|') {
if (yych <= '{') { gotoCase = 25; continue; };
{ gotoCase = 42; continue; };
} else {
if (yych <= '~') { gotoCase = 25; continue; };
if (yych >= 0x80) { gotoCase = 20; continue; };
}
}
}
}
case 15:
++cursor;
case 16:
{ this.tokenType = null; return cursor; }
case 17:
++cursor;
if ((yych = this._charAt(cursor)) == '=') { gotoCase = 115; continue; };
case 18:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = null; return cursor; }
case 19:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 16; continue; };
if (yych == '\r') { gotoCase = 16; continue; };
{ gotoCase = 107; continue; };
case 20:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 50; continue; };
case 21:
{
var token = this._line.substring(cursorOnEnter, cursor);
if (token in this._keywords)
this.tokenType = "javascript-keyword";
else
this.tokenType = "javascript-ident";
return cursor;
}
case 22:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 23:
yych = this._charAt(++cursor);
if (yych == '&') { gotoCase = 43; continue; };
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 24:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 16; continue; };
if (yych == '\r') { gotoCase = 16; continue; };
{ gotoCase = 96; continue; };
case 25:
yych = this._charAt(++cursor);
{ gotoCase = 18; continue; };
case 26:
++cursor;
{ this.tokenType = null; return cursor; }
case 28:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 29:
yych = this._charAt(++cursor);
if (yych == '+') { gotoCase = 43; continue; };
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 30:
yych = this._charAt(++cursor);
if (yych == '-') { gotoCase = 43; continue; };
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 31:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 18; continue; };
if (yych <= '9') { gotoCase = 89; continue; };
{ gotoCase = 18; continue; };
case 32:
yyaccept = 2;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '.') {
if (yych == '*') { gotoCase = 78; continue; };
} else {
if (yych <= '/') { gotoCase = 80; continue; };
if (yych == '=') { gotoCase = 77; continue; };
}
case 33:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = null; return cursor; }
case 34:
yyaccept = 3;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'E') {
if (yych <= '/') {
if (yych == '.') { gotoCase = 63; continue; };
} else {
if (yych <= '7') { gotoCase = 72; continue; };
if (yych >= 'E') { gotoCase = 62; continue; };
}
} else {
if (yych <= 'd') {
if (yych == 'X') { gotoCase = 74; continue; };
} else {
if (yych <= 'e') { gotoCase = 62; continue; };
if (yych == 'x') { gotoCase = 74; continue; };
}
}
case 35:
{ this.tokenType = "javascript-number"; return cursor; }
case 36:
yyaccept = 3;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 63; continue; };
if (yych <= '/') { gotoCase = 35; continue; };
{ gotoCase = 60; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 35; continue; };
{ gotoCase = 62; continue; };
} else {
if (yych == 'e') { gotoCase = 62; continue; };
{ gotoCase = 35; continue; };
}
}
case 37:
yych = this._charAt(++cursor);
if (yych <= ';') { gotoCase = 18; continue; };
if (yych <= '<') { gotoCase = 59; continue; };
if (yych <= '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 38:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 58; continue; };
{ gotoCase = 18; continue; };
case 39:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 18; continue; };
if (yych <= '=') { gotoCase = 43; continue; };
if (yych <= '>') { gotoCase = 56; continue; };
{ gotoCase = 18; continue; };
case 40:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == 'u') { gotoCase = 44; continue; };
{ gotoCase = 16; continue; };
case 41:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 42:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
if (yych != '|') { gotoCase = 18; continue; };
case 43:
yych = this._charAt(++cursor);
{ gotoCase = 18; continue; };
case 44:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 46; continue; };
} else {
if (yych <= 'F') { gotoCase = 46; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 46; continue; };
}
case 45:
cursor = YYMARKER;
if (yyaccept <= 1) {
if (yyaccept <= 0) {
{ gotoCase = 16; continue; };
} else {
{ gotoCase = 21; continue; };
}
} else {
if (yyaccept <= 2) {
{ gotoCase = 33; continue; };
} else {
{ gotoCase = 35; continue; };
}
}
case 46:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 47; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 47:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 48; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 48:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 49; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 49:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 50:
if (yych <= '[') {
if (yych <= '/') {
if (yych == '$') { gotoCase = 49; continue; };
{ gotoCase = 21; continue; };
} else {
if (yych <= '9') { gotoCase = 49; continue; };
if (yych <= '@') { gotoCase = 21; continue; };
if (yych <= 'Z') { gotoCase = 49; continue; };
{ gotoCase = 21; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '\\') { gotoCase = 51; continue; };
if (yych <= '^') { gotoCase = 21; continue; };
{ gotoCase = 49; continue; };
} else {
if (yych <= '`') { gotoCase = 21; continue; };
if (yych <= 'z') { gotoCase = 49; continue; };
if (yych <= 0x7F) { gotoCase = 21; continue; };
{ gotoCase = 49; continue; };
}
}
case 51:
++cursor;
yych = this._charAt(cursor);
if (yych != 'u') { gotoCase = 45; continue; };
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 53; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 53:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 54; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 54:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 55; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 55:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 49; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 49; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 49; continue; };
{ gotoCase = 45; continue; };
}
case 56:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 18; continue; };
if (yych <= '=') { gotoCase = 43; continue; };
if (yych >= '?') { gotoCase = 18; continue; };
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 58:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 59:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 60:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 63; continue; };
if (yych <= '/') { gotoCase = 35; continue; };
{ gotoCase = 60; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 35; continue; };
} else {
if (yych != 'e') { gotoCase = 35; continue; };
}
}
case 62:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych == '+') { gotoCase = 69; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= '-') { gotoCase = 69; continue; };
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 70; continue; };
{ gotoCase = 45; continue; };
}
case 63:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 63; continue; };
{ gotoCase = 35; continue; };
} else {
if (yych <= 'E') { gotoCase = 65; continue; };
if (yych != 'e') { gotoCase = 35; continue; };
}
case 65:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 45; continue; };
} else {
if (yych <= '-') { gotoCase = 66; continue; };
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 67; continue; };
{ gotoCase = 45; continue; };
}
case 66:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
case 67:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 67; continue; };
{ gotoCase = 35; continue; };
case 69:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
case 70:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 70; continue; };
{ gotoCase = 35; continue; };
case 72:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '7') { gotoCase = 72; continue; };
{ gotoCase = 35; continue; };
case 74:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 75; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 75:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 75; continue; };
{ gotoCase = 35; continue; };
} else {
if (yych <= 'F') { gotoCase = 75; continue; };
if (yych <= '`') { gotoCase = 35; continue; };
if (yych <= 'f') { gotoCase = 75; continue; };
{ gotoCase = 35; continue; };
}
case 77:
yych = this._charAt(++cursor);
{ gotoCase = 33; continue; };
case 78:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 85; continue; };
{ gotoCase = 78; continue; };
} else {
if (yych <= '\r') { gotoCase = 85; continue; };
if (yych == '*') { gotoCase = 83; continue; };
{ gotoCase = 78; continue; };
}
case 80:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 82; continue; };
if (yych != '\r') { gotoCase = 80; continue; };
case 82:
{ this.tokenType = "javascript-comment"; return cursor; }
case 83:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 83; continue; };
if (yych == '/') { gotoCase = 87; continue; };
{ gotoCase = 78; continue; };
case 85:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "javascript-comment"; return cursor; }
case 87:
++cursor;
{ this.tokenType = "javascript-comment"; return cursor; }
case 89:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 89; continue; };
{ gotoCase = 35; continue; };
} else {
if (yych <= 'E') { gotoCase = 91; continue; };
if (yych != 'e') { gotoCase = 35; continue; };
}
case 91:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 45; continue; };
} else {
if (yych <= '-') { gotoCase = 92; continue; };
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 93; continue; };
{ gotoCase = 45; continue; };
}
case 92:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
case 93:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 93; continue; };
{ gotoCase = 35; continue; };
case 95:
++cursor;
yych = this._charAt(cursor);
case 96:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 45; continue; };
if (yych <= '\f') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 95; continue; };
{ gotoCase = 98; continue; };
} else {
if (yych != '\\') { gotoCase = 95; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 45; continue; };
{ gotoCase = 101; continue; };
} else {
if (yych == '\r') { gotoCase = 101; continue; };
{ gotoCase = 45; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 95; continue; };
if (yych <= '&') { gotoCase = 45; continue; };
{ gotoCase = 95; continue; };
} else {
if (yych == '\\') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 95; continue; };
if (yych <= 'e') { gotoCase = 45; continue; };
{ gotoCase = 95; continue; };
} else {
if (yych == 'n') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 45; continue; };
{ gotoCase = 95; continue; };
} else {
if (yych <= 'u') { gotoCase = 100; continue; };
if (yych <= 'v') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
}
}
}
case 98:
++cursor;
{ this.tokenType = "javascript-string"; return cursor; }
case 100:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 103; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 103; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 103; continue; };
{ gotoCase = 45; continue; };
}
case 101:
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 103:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 104; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 104:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 105; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 105:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 95; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
}
case 106:
++cursor;
yych = this._charAt(cursor);
case 107:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 45; continue; };
if (yych <= '\f') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 106; continue; };
{ gotoCase = 98; continue; };
} else {
if (yych != '\\') { gotoCase = 106; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 45; continue; };
{ gotoCase = 110; continue; };
} else {
if (yych == '\r') { gotoCase = 110; continue; };
{ gotoCase = 45; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 106; continue; };
if (yych <= '&') { gotoCase = 45; continue; };
{ gotoCase = 106; continue; };
} else {
if (yych == '\\') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 106; continue; };
if (yych <= 'e') { gotoCase = 45; continue; };
{ gotoCase = 106; continue; };
} else {
if (yych == 'n') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 45; continue; };
{ gotoCase = 106; continue; };
} else {
if (yych <= 'u') { gotoCase = 109; continue; };
if (yych <= 'v') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
}
}
}
case 109:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 112; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 112; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 112; continue; };
{ gotoCase = 45; continue; };
}
case 110:
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 112:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 113; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 113:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 114; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 114:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 106; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
}
case 115:
++cursor;
if ((yych = this._charAt(cursor)) == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };

case this.case_DSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 120; continue; };
if (yych <= '\f') { gotoCase = 119; continue; };
{ gotoCase = 120; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 119; continue; };
{ gotoCase = 122; continue; };
} else {
if (yych == '\\') { gotoCase = 124; continue; };
{ gotoCase = 119; continue; };
}
}
case 118:
{ this.tokenType = "javascript-string"; return cursor; }
case 119:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 126; continue; };
case 120:
++cursor;
case 121:
{ this.tokenType = null; return cursor; }
case 122:
++cursor;
case 123:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-string"; return cursor; }
case 124:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 125; continue; };
if (yych <= '&') { gotoCase = 121; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 121; continue; };
} else {
if (yych != 'b') { gotoCase = 121; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 121; continue; };
} else {
if (yych <= 'n') { gotoCase = 125; continue; };
if (yych <= 'q') { gotoCase = 121; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 121; continue; };
} else {
if (yych <= 'u') { gotoCase = 127; continue; };
if (yych >= 'w') { gotoCase = 121; continue; };
}
}
}
case 125:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 126:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 118; continue; };
if (yych <= '\f') { gotoCase = 125; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 125; continue; };
{ gotoCase = 133; continue; };
} else {
if (yych == '\\') { gotoCase = 132; continue; };
{ gotoCase = 125; continue; };
}
}
case 127:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 128; continue; };
if (yych <= '9') { gotoCase = 129; continue; };
} else {
if (yych <= 'F') { gotoCase = 129; continue; };
if (yych <= '`') { gotoCase = 128; continue; };
if (yych <= 'f') { gotoCase = 129; continue; };
}
case 128:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 118; continue; };
} else {
{ gotoCase = 121; continue; };
}
case 129:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 128; continue; };
if (yych >= ':') { gotoCase = 128; continue; };
} else {
if (yych <= 'F') { gotoCase = 130; continue; };
if (yych <= '`') { gotoCase = 128; continue; };
if (yych >= 'g') { gotoCase = 128; continue; };
}
case 130:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 128; continue; };
if (yych >= ':') { gotoCase = 128; continue; };
} else {
if (yych <= 'F') { gotoCase = 131; continue; };
if (yych <= '`') { gotoCase = 128; continue; };
if (yych >= 'g') { gotoCase = 128; continue; };
}
case 131:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 128; continue; };
if (yych <= '9') { gotoCase = 125; continue; };
{ gotoCase = 128; continue; };
} else {
if (yych <= 'F') { gotoCase = 125; continue; };
if (yych <= '`') { gotoCase = 128; continue; };
if (yych <= 'f') { gotoCase = 125; continue; };
{ gotoCase = 128; continue; };
}
case 132:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 125; continue; };
if (yych <= '&') { gotoCase = 128; continue; };
{ gotoCase = 125; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 128; continue; };
{ gotoCase = 125; continue; };
} else {
if (yych == 'b') { gotoCase = 125; continue; };
{ gotoCase = 128; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 125; continue; };
{ gotoCase = 128; continue; };
} else {
if (yych <= 'n') { gotoCase = 125; continue; };
if (yych <= 'q') { gotoCase = 128; continue; };
{ gotoCase = 125; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 128; continue; };
{ gotoCase = 125; continue; };
} else {
if (yych <= 'u') { gotoCase = 127; continue; };
if (yych <= 'v') { gotoCase = 125; continue; };
{ gotoCase = 128; continue; };
}
}
}
case 133:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 123; continue; };

case this.case_NODIV:
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych <= '(') {
if (yych <= '#') {
if (yych <= ' ') { gotoCase = 136; continue; };
if (yych <= '!') { gotoCase = 138; continue; };
if (yych <= '"') { gotoCase = 140; continue; };
} else {
if (yych <= '%') {
if (yych <= '$') { gotoCase = 141; continue; };
{ gotoCase = 143; continue; };
} else {
if (yych <= '&') { gotoCase = 144; continue; };
if (yych <= '\'') { gotoCase = 145; continue; };
{ gotoCase = 146; continue; };
}
}
} else {
if (yych <= ',') {
if (yych <= ')') { gotoCase = 147; continue; };
if (yych <= '*') { gotoCase = 149; continue; };
if (yych <= '+') { gotoCase = 150; continue; };
{ gotoCase = 146; continue; };
} else {
if (yych <= '.') {
if (yych <= '-') { gotoCase = 151; continue; };
{ gotoCase = 152; continue; };
} else {
if (yych <= '/') { gotoCase = 153; continue; };
if (yych <= '0') { gotoCase = 154; continue; };
{ gotoCase = 156; continue; };
}
}
}
} else {
if (yych <= '\\') {
if (yych <= '>') {
if (yych <= ';') { gotoCase = 146; continue; };
if (yych <= '<') { gotoCase = 157; continue; };
if (yych <= '=') { gotoCase = 158; continue; };
{ gotoCase = 159; continue; };
} else {
if (yych <= '@') {
if (yych <= '?') { gotoCase = 146; continue; };
} else {
if (yych <= 'Z') { gotoCase = 141; continue; };
if (yych <= '[') { gotoCase = 146; continue; };
{ gotoCase = 160; continue; };
}
}
} else {
if (yych <= 'z') {
if (yych <= '^') {
if (yych <= ']') { gotoCase = 146; continue; };
{ gotoCase = 161; continue; };
} else {
if (yych != '`') { gotoCase = 141; continue; };
}
} else {
if (yych <= '|') {
if (yych <= '{') { gotoCase = 146; continue; };
{ gotoCase = 162; continue; };
} else {
if (yych <= '~') { gotoCase = 146; continue; };
if (yych >= 0x80) { gotoCase = 141; continue; };
}
}
}
}
case 136:
++cursor;
case 137:
{ this.tokenType = null; return cursor; }
case 138:
++cursor;
if ((yych = this._charAt(cursor)) == '=') { gotoCase = 260; continue; };
case 139:
{ this.tokenType = null; return cursor; }
case 140:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 137; continue; };
if (yych == '\r') { gotoCase = 137; continue; };
{ gotoCase = 252; continue; };
case 141:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 170; continue; };
case 142:
this.setLexCondition(this._lexConditions.DIV);
{
var token = this._line.substring(cursorOnEnter, cursor);
if (token in this._keywords)
this.tokenType = "javascript-keyword";
else
this.tokenType = "javascript-ident";
return cursor;
}
case 143:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 144:
yych = this._charAt(++cursor);
if (yych == '&') { gotoCase = 163; continue; };
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 145:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 137; continue; };
if (yych == '\r') { gotoCase = 137; continue; };
{ gotoCase = 241; continue; };
case 146:
yych = this._charAt(++cursor);
{ gotoCase = 139; continue; };
case 147:
++cursor;
this.setLexCondition(this._lexConditions.DIV);
{ this.tokenType = null; return cursor; }
case 149:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 150:
yych = this._charAt(++cursor);
if (yych == '+') { gotoCase = 163; continue; };
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 151:
yych = this._charAt(++cursor);
if (yych == '-') { gotoCase = 163; continue; };
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 152:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 139; continue; };
if (yych <= '9') { gotoCase = 234; continue; };
{ gotoCase = 139; continue; };
case 153:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 137; continue; };
{ gotoCase = 197; continue; };
} else {
if (yych <= '\r') { gotoCase = 137; continue; };
if (yych <= ')') { gotoCase = 197; continue; };
{ gotoCase = 202; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 204; continue; };
{ gotoCase = 197; continue; };
} else {
if (yych <= '[') { gotoCase = 200; continue; };
if (yych <= '\\') { gotoCase = 199; continue; };
if (yych <= ']') { gotoCase = 137; continue; };
{ gotoCase = 197; continue; };
}
}
case 154:
yyaccept = 2;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'E') {
if (yych <= '/') {
if (yych == '.') { gotoCase = 183; continue; };
} else {
if (yych <= '7') { gotoCase = 192; continue; };
if (yych >= 'E') { gotoCase = 182; continue; };
}
} else {
if (yych <= 'd') {
if (yych == 'X') { gotoCase = 194; continue; };
} else {
if (yych <= 'e') { gotoCase = 182; continue; };
if (yych == 'x') { gotoCase = 194; continue; };
}
}
case 155:
this.setLexCondition(this._lexConditions.DIV);
{ this.tokenType = "javascript-number"; return cursor; }
case 156:
yyaccept = 2;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 183; continue; };
if (yych <= '/') { gotoCase = 155; continue; };
{ gotoCase = 180; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 155; continue; };
{ gotoCase = 182; continue; };
} else {
if (yych == 'e') { gotoCase = 182; continue; };
{ gotoCase = 155; continue; };
}
}
case 157:
yych = this._charAt(++cursor);
if (yych <= ';') { gotoCase = 139; continue; };
if (yych <= '<') { gotoCase = 179; continue; };
if (yych <= '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 158:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 178; continue; };
{ gotoCase = 139; continue; };
case 159:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 139; continue; };
if (yych <= '=') { gotoCase = 163; continue; };
if (yych <= '>') { gotoCase = 176; continue; };
{ gotoCase = 139; continue; };
case 160:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == 'u') { gotoCase = 164; continue; };
{ gotoCase = 137; continue; };
case 161:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 162:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
if (yych != '|') { gotoCase = 139; continue; };
case 163:
yych = this._charAt(++cursor);
{ gotoCase = 139; continue; };
case 164:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 166; continue; };
} else {
if (yych <= 'F') { gotoCase = 166; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 166; continue; };
}
case 165:
cursor = YYMARKER;
if (yyaccept <= 1) {
if (yyaccept <= 0) {
{ gotoCase = 137; continue; };
} else {
{ gotoCase = 142; continue; };
}
} else {
if (yyaccept <= 2) {
{ gotoCase = 155; continue; };
} else {
{ gotoCase = 217; continue; };
}
}
case 166:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 167; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 167:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 168; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 168:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 169; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 169:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 170:
if (yych <= '[') {
if (yych <= '/') {
if (yych == '$') { gotoCase = 169; continue; };
{ gotoCase = 142; continue; };
} else {
if (yych <= '9') { gotoCase = 169; continue; };
if (yych <= '@') { gotoCase = 142; continue; };
if (yych <= 'Z') { gotoCase = 169; continue; };
{ gotoCase = 142; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '\\') { gotoCase = 171; continue; };
if (yych <= '^') { gotoCase = 142; continue; };
{ gotoCase = 169; continue; };
} else {
if (yych <= '`') { gotoCase = 142; continue; };
if (yych <= 'z') { gotoCase = 169; continue; };
if (yych <= 0x7F) { gotoCase = 142; continue; };
{ gotoCase = 169; continue; };
}
}
case 171:
++cursor;
yych = this._charAt(cursor);
if (yych != 'u') { gotoCase = 165; continue; };
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 173; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 173:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 174; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 174:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 175; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 175:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 169; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 169; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 169; continue; };
{ gotoCase = 165; continue; };
}
case 176:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 139; continue; };
if (yych <= '=') { gotoCase = 163; continue; };
if (yych >= '?') { gotoCase = 139; continue; };
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 178:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 179:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 180:
yyaccept = 2;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 183; continue; };
if (yych <= '/') { gotoCase = 155; continue; };
{ gotoCase = 180; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 155; continue; };
} else {
if (yych != 'e') { gotoCase = 155; continue; };
}
}
case 182:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych == '+') { gotoCase = 189; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= '-') { gotoCase = 189; continue; };
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 190; continue; };
{ gotoCase = 165; continue; };
}
case 183:
yyaccept = 2;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 183; continue; };
{ gotoCase = 155; continue; };
} else {
if (yych <= 'E') { gotoCase = 185; continue; };
if (yych != 'e') { gotoCase = 155; continue; };
}
case 185:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 165; continue; };
} else {
if (yych <= '-') { gotoCase = 186; continue; };
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 187; continue; };
{ gotoCase = 165; continue; };
}
case 186:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
case 187:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 187; continue; };
{ gotoCase = 155; continue; };
case 189:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
case 190:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 190; continue; };
{ gotoCase = 155; continue; };
case 192:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '7') { gotoCase = 192; continue; };
{ gotoCase = 155; continue; };
case 194:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 195; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 195:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 195; continue; };
{ gotoCase = 155; continue; };
} else {
if (yych <= 'F') { gotoCase = 195; continue; };
if (yych <= '`') { gotoCase = 155; continue; };
if (yych <= 'f') { gotoCase = 195; continue; };
{ gotoCase = 155; continue; };
}
case 197:
++cursor;
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 197; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych == '\r') { gotoCase = 165; continue; };
{ gotoCase = 197; continue; };
}
} else {
if (yych <= '[') {
if (yych <= '/') { gotoCase = 220; continue; };
if (yych <= 'Z') { gotoCase = 197; continue; };
{ gotoCase = 228; continue; };
} else {
if (yych <= '\\') { gotoCase = 227; continue; };
if (yych <= ']') { gotoCase = 165; continue; };
{ gotoCase = 197; continue; };
}
}
case 199:
yych = this._charAt(++cursor);
if (yych == '\n') { gotoCase = 165; continue; };
if (yych == '\r') { gotoCase = 165; continue; };
{ gotoCase = 197; continue; };
case 200:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 200; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 200; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 165; continue; };
{ gotoCase = 200; continue; };
} else {
if (yych <= '\\') { gotoCase = 215; continue; };
if (yych <= ']') { gotoCase = 213; continue; };
{ gotoCase = 200; continue; };
}
}
case 202:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 209; continue; };
{ gotoCase = 202; continue; };
} else {
if (yych <= '\r') { gotoCase = 209; continue; };
if (yych == '*') { gotoCase = 207; continue; };
{ gotoCase = 202; continue; };
}
case 204:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 206; continue; };
if (yych != '\r') { gotoCase = 204; continue; };
case 206:
{ this.tokenType = "javascript-comment"; return cursor; }
case 207:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 207; continue; };
if (yych == '/') { gotoCase = 211; continue; };
{ gotoCase = 202; continue; };
case 209:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "javascript-comment"; return cursor; }
case 211:
++cursor;
{ this.tokenType = "javascript-comment"; return cursor; }
case 213:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 213; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 213; continue; };
{ gotoCase = 197; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 220; continue; };
{ gotoCase = 213; continue; };
} else {
if (yych <= '[') { gotoCase = 218; continue; };
if (yych <= '\\') { gotoCase = 216; continue; };
{ gotoCase = 213; continue; };
}
}
case 215:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 165; continue; };
if (yych == '\r') { gotoCase = 165; continue; };
{ gotoCase = 200; continue; };
case 216:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 217; continue; };
if (yych != '\r') { gotoCase = 213; continue; };
case 217:
this.setLexCondition(this._lexConditions.REGEX);
{ this.tokenType = "javascript-regexp"; return cursor; }
case 218:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 218; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 218; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 165; continue; };
{ gotoCase = 218; continue; };
} else {
if (yych <= '\\') { gotoCase = 225; continue; };
if (yych <= ']') { gotoCase = 223; continue; };
{ gotoCase = 218; continue; };
}
}
case 220:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'h') {
if (yych == 'g') { gotoCase = 220; continue; };
} else {
if (yych <= 'i') { gotoCase = 220; continue; };
if (yych == 'm') { gotoCase = 220; continue; };
}
{ this.tokenType = "javascript-regexp"; return cursor; }
case 223:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 223; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 223; continue; };
{ gotoCase = 197; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 220; continue; };
{ gotoCase = 223; continue; };
} else {
if (yych <= '[') { gotoCase = 218; continue; };
if (yych <= '\\') { gotoCase = 226; continue; };
{ gotoCase = 223; continue; };
}
}
case 225:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 165; continue; };
if (yych == '\r') { gotoCase = 165; continue; };
{ gotoCase = 218; continue; };
case 226:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 217; continue; };
if (yych == '\r') { gotoCase = 217; continue; };
{ gotoCase = 223; continue; };
case 227:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 217; continue; };
if (yych == '\r') { gotoCase = 217; continue; };
{ gotoCase = 197; continue; };
case 228:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 228; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 228; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 165; continue; };
{ gotoCase = 228; continue; };
} else {
if (yych <= '\\') { gotoCase = 232; continue; };
if (yych >= '^') { gotoCase = 228; continue; };
}
}
case 230:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 230; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 230; continue; };
{ gotoCase = 197; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 220; continue; };
{ gotoCase = 230; continue; };
} else {
if (yych <= '[') { gotoCase = 228; continue; };
if (yych <= '\\') { gotoCase = 233; continue; };
{ gotoCase = 230; continue; };
}
}
case 232:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 165; continue; };
if (yych == '\r') { gotoCase = 165; continue; };
{ gotoCase = 228; continue; };
case 233:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 217; continue; };
if (yych == '\r') { gotoCase = 217; continue; };
{ gotoCase = 230; continue; };
case 234:
yyaccept = 2;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 234; continue; };
{ gotoCase = 155; continue; };
} else {
if (yych <= 'E') { gotoCase = 236; continue; };
if (yych != 'e') { gotoCase = 155; continue; };
}
case 236:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 165; continue; };
} else {
if (yych <= '-') { gotoCase = 237; continue; };
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 238; continue; };
{ gotoCase = 165; continue; };
}
case 237:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
case 238:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 238; continue; };
{ gotoCase = 155; continue; };
case 240:
++cursor;
yych = this._charAt(cursor);
case 241:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 165; continue; };
if (yych <= '\f') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 240; continue; };
{ gotoCase = 243; continue; };
} else {
if (yych != '\\') { gotoCase = 240; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 165; continue; };
{ gotoCase = 246; continue; };
} else {
if (yych == '\r') { gotoCase = 246; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 240; continue; };
if (yych <= '&') { gotoCase = 165; continue; };
{ gotoCase = 240; continue; };
} else {
if (yych == '\\') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 240; continue; };
if (yych <= 'e') { gotoCase = 165; continue; };
{ gotoCase = 240; continue; };
} else {
if (yych == 'n') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 165; continue; };
{ gotoCase = 240; continue; };
} else {
if (yych <= 'u') { gotoCase = 245; continue; };
if (yych <= 'v') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
}
}
}
case 243:
++cursor;
{ this.tokenType = "javascript-string"; return cursor; }
case 245:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 248; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 248; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 248; continue; };
{ gotoCase = 165; continue; };
}
case 246:
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 248:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 249; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 249:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 250; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 250:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 240; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
}
case 251:
++cursor;
yych = this._charAt(cursor);
case 252:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 165; continue; };
if (yych <= '\f') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 251; continue; };
{ gotoCase = 243; continue; };
} else {
if (yych != '\\') { gotoCase = 251; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 165; continue; };
{ gotoCase = 255; continue; };
} else {
if (yych == '\r') { gotoCase = 255; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 251; continue; };
if (yych <= '&') { gotoCase = 165; continue; };
{ gotoCase = 251; continue; };
} else {
if (yych == '\\') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 251; continue; };
if (yych <= 'e') { gotoCase = 165; continue; };
{ gotoCase = 251; continue; };
} else {
if (yych == 'n') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 165; continue; };
{ gotoCase = 251; continue; };
} else {
if (yych <= 'u') { gotoCase = 254; continue; };
if (yych <= 'v') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
}
}
}
case 254:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 257; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 257; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 257; continue; };
{ gotoCase = 165; continue; };
}
case 255:
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 257:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 258; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 258:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 259; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 259:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 251; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
}
case 260:
++cursor;
if ((yych = this._charAt(cursor)) == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };

case this.case_REGEX:
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 264; continue; };
{ gotoCase = 265; continue; };
} else {
if (yych == '\r') { gotoCase = 265; continue; };
{ gotoCase = 264; continue; };
}
} else {
if (yych <= '[') {
if (yych <= '/') { gotoCase = 267; continue; };
if (yych <= 'Z') { gotoCase = 264; continue; };
{ gotoCase = 269; continue; };
} else {
if (yych <= '\\') { gotoCase = 270; continue; };
if (yych <= ']') { gotoCase = 265; continue; };
{ gotoCase = 264; continue; };
}
}
case 263:
{ this.tokenType = "javascript-regexp"; return cursor; }
case 264:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 272; continue; };
case 265:
++cursor;
case 266:
{ this.tokenType = null; return cursor; }
case 267:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 278; continue; };
case 268:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-regexp"; return cursor; }
case 269:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 266; continue; };
if (yych <= '\f') { gotoCase = 276; continue; };
{ gotoCase = 266; continue; };
} else {
if (yych <= '*') {
if (yych <= ')') { gotoCase = 276; continue; };
{ gotoCase = 266; continue; };
} else {
if (yych == '/') { gotoCase = 266; continue; };
{ gotoCase = 276; continue; };
}
}
case 270:
yych = this._charAt(++cursor);
if (yych == '\n') { gotoCase = 266; continue; };
if (yych == '\r') { gotoCase = 266; continue; };
case 271:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 272:
if (yych <= '.') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 271; continue; };
{ gotoCase = 263; continue; };
} else {
if (yych == '\r') { gotoCase = 263; continue; };
{ gotoCase = 271; continue; };
}
} else {
if (yych <= '[') {
if (yych <= '/') { gotoCase = 277; continue; };
if (yych <= 'Z') { gotoCase = 271; continue; };
{ gotoCase = 275; continue; };
} else {
if (yych <= '\\') { gotoCase = 273; continue; };
if (yych <= ']') { gotoCase = 263; continue; };
{ gotoCase = 271; continue; };
}
}
case 273:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 274; continue; };
if (yych != '\r') { gotoCase = 271; continue; };
case 274:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 263; continue; };
} else {
{ gotoCase = 266; continue; };
}
case 275:
++cursor;
yych = this._charAt(cursor);
case 276:
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 274; continue; };
{ gotoCase = 275; continue; };
} else {
if (yych <= '\r') { gotoCase = 274; continue; };
if (yych <= ')') { gotoCase = 275; continue; };
{ gotoCase = 274; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 274; continue; };
{ gotoCase = 275; continue; };
} else {
if (yych <= '\\') { gotoCase = 281; continue; };
if (yych <= ']') { gotoCase = 279; continue; };
{ gotoCase = 275; continue; };
}
}
case 277:
++cursor;
yych = this._charAt(cursor);
case 278:
if (yych <= 'h') {
if (yych == 'g') { gotoCase = 277; continue; };
{ gotoCase = 268; continue; };
} else {
if (yych <= 'i') { gotoCase = 277; continue; };
if (yych == 'm') { gotoCase = 277; continue; };
{ gotoCase = 268; continue; };
}
case 279:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 263; continue; };
{ gotoCase = 279; continue; };
} else {
if (yych <= '\r') { gotoCase = 263; continue; };
if (yych <= ')') { gotoCase = 279; continue; };
{ gotoCase = 271; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 277; continue; };
{ gotoCase = 279; continue; };
} else {
if (yych <= '[') { gotoCase = 275; continue; };
if (yych <= '\\') { gotoCase = 282; continue; };
{ gotoCase = 279; continue; };
}
}
case 281:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 274; continue; };
if (yych == '\r') { gotoCase = 274; continue; };
{ gotoCase = 275; continue; };
case 282:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 274; continue; };
if (yych == '\r') { gotoCase = 274; continue; };
{ gotoCase = 279; continue; };

case this.case_SSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 287; continue; };
if (yych <= '\f') { gotoCase = 286; continue; };
{ gotoCase = 287; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 286; continue; };
{ gotoCase = 289; continue; };
} else {
if (yych == '\\') { gotoCase = 291; continue; };
{ gotoCase = 286; continue; };
}
}
case 285:
{ this.tokenType = "javascript-string"; return cursor; }
case 286:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 293; continue; };
case 287:
++cursor;
case 288:
{ this.tokenType = null; return cursor; }
case 289:
++cursor;
case 290:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-string"; return cursor; }
case 291:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 292; continue; };
if (yych <= '&') { gotoCase = 288; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 288; continue; };
} else {
if (yych != 'b') { gotoCase = 288; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 288; continue; };
} else {
if (yych <= 'n') { gotoCase = 292; continue; };
if (yych <= 'q') { gotoCase = 288; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 288; continue; };
} else {
if (yych <= 'u') { gotoCase = 294; continue; };
if (yych >= 'w') { gotoCase = 288; continue; };
}
}
}
case 292:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 293:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 285; continue; };
if (yych <= '\f') { gotoCase = 292; continue; };
{ gotoCase = 285; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 292; continue; };
{ gotoCase = 300; continue; };
} else {
if (yych == '\\') { gotoCase = 299; continue; };
{ gotoCase = 292; continue; };
}
}
case 294:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 295; continue; };
if (yych <= '9') { gotoCase = 296; continue; };
} else {
if (yych <= 'F') { gotoCase = 296; continue; };
if (yych <= '`') { gotoCase = 295; continue; };
if (yych <= 'f') { gotoCase = 296; continue; };
}
case 295:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 285; continue; };
} else {
{ gotoCase = 288; continue; };
}
case 296:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 295; continue; };
if (yych >= ':') { gotoCase = 295; continue; };
} else {
if (yych <= 'F') { gotoCase = 297; continue; };
if (yych <= '`') { gotoCase = 295; continue; };
if (yych >= 'g') { gotoCase = 295; continue; };
}
case 297:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 295; continue; };
if (yych >= ':') { gotoCase = 295; continue; };
} else {
if (yych <= 'F') { gotoCase = 298; continue; };
if (yych <= '`') { gotoCase = 295; continue; };
if (yych >= 'g') { gotoCase = 295; continue; };
}
case 298:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 295; continue; };
if (yych <= '9') { gotoCase = 292; continue; };
{ gotoCase = 295; continue; };
} else {
if (yych <= 'F') { gotoCase = 292; continue; };
if (yych <= '`') { gotoCase = 295; continue; };
if (yych <= 'f') { gotoCase = 292; continue; };
{ gotoCase = 295; continue; };
}
case 299:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 292; continue; };
if (yych <= '&') { gotoCase = 295; continue; };
{ gotoCase = 292; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 295; continue; };
{ gotoCase = 292; continue; };
} else {
if (yych == 'b') { gotoCase = 292; continue; };
{ gotoCase = 295; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 292; continue; };
{ gotoCase = 295; continue; };
} else {
if (yych <= 'n') { gotoCase = 292; continue; };
if (yych <= 'q') { gotoCase = 295; continue; };
{ gotoCase = 292; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 295; continue; };
{ gotoCase = 292; continue; };
} else {
if (yych <= 'u') { gotoCase = 294; continue; };
if (yych <= 'v') { gotoCase = 292; continue; };
{ gotoCase = 295; continue; };
}
}
}
case 300:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 290; continue; };
}

}
}
}

WebInspector.SourceJavaScriptTokenizer.prototype.__proto__ = WebInspector.SourceTokenizer.prototype;





WebInspector.SourceView = function(resource)
{
WebInspector.ResourceView.call(this, resource);

this.element.addStyleClass("source");

var canEditScripts = WebInspector.panels.scripts && WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script;
this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this));
resource.addEventListener("finished", this._resourceLoadingFinished, this);
this._frameNeedsSetup = true;
}



WebInspector.SourceView.DefaultMIMETypeForResourceType = {
0: "text/html",
1: "text/css",
4: "text/javascript"
}

WebInspector.SourceView.prototype = {
show: function(parentElement)
{
WebInspector.ResourceView.prototype.show.call(this, parentElement);
this.setupSourceFrameIfNeeded();
this.sourceFrame.visible = true;
this.resize();
},

hide: function()
{
this.sourceFrame.visible = false;
if (!this._frameNeedsSetup)
this.sourceFrame.clearLineHighlight();
WebInspector.View.prototype.hide.call(this);
this._currentSearchResultIndex = -1;
},

resize: function()
{
if (this.sourceFrame)
this.sourceFrame.resize();
},

get scrollTop()
{
return this.sourceFrame.scrollTop;
},

set scrollTop(scrollTop)
{
this.sourceFrame.scrollTop = scrollTop;
},


setupSourceFrameIfNeeded: function()
{
if (!this._frameNeedsSetup)
return;

delete this._frameNeedsSetup;
this.resource.requestContent(this._contentLoaded.bind(this));
},

hasContent: function()
{
return true;
},

_contentLoaded: function(content)
{
var mimeType = this._canonicalMimeType(this.resource);
this.sourceFrame.setContent(mimeType, content, this.resource.url);
this._sourceFrameSetupFinished();
var breakpoints = WebInspector.breakpointManager.breakpointsForURL(this.resource.url);
for (var i = 0; i < breakpoints.length; ++i)
this.sourceFrame.addBreakpoint(breakpoints[i]);
},

_canonicalMimeType: function(resource)
{
return WebInspector.SourceView.DefaultMIMETypeForResourceType[resource.type] || resource.mimeType;
},

_resourceLoadingFinished: function(event)
{
this._frameNeedsSetup = true;
this._sourceFrameSetup = false;
if (this.visible)
this.setupSourceFrameIfNeeded();
this.resource.removeEventListener("finished", this._resourceLoadingFinished, this);
},

_continueToLine: function(line)
{
var scriptsPanel = WebInspector.panels.scripts;
if (scriptsPanel) {
var sourceID = this._sourceIDForLine(line);
scriptsPanel.continueToLine(sourceID, line);
}
},

_addBreakpoint: function(line)
{
var sourceID = this._sourceIDForLine(line);
WebInspector.breakpointManager.setBreakpoint(sourceID, this.resource.url, line, true, "");
if (!WebInspector.panels.scripts.breakpointsActivated)
WebInspector.panels.scripts.toggleBreakpointsClicked();
},

_editLine: function(line, newContent, cancelEditingCallback)
{
var lines = [];
var textModel = this.sourceFrame.textModel;
for (var i = 0; i < textModel.linesCount; ++i) {
if (i === line)
lines.push(newContent);
else
lines.push(textModel.line(i));
}

var editData = {};
editData.sourceID = this._sourceIDForLine(line);
editData.content = lines.join("\n");
editData.line = line;
editData.linesCountToShift = newContent.split("\n").length - 1;

WebInspector.panels.scripts.editScriptSource(editData, this._editLineComplete.bind(this, editData), cancelEditingCallback);
},

_editLineComplete: function(editData, newContent)
{
this.resource.setContent(newContent, this._revertEditLine.bind(this, editData));
},

_revertEditLine: function(editData, contentToRevertTo)
{
var newEditData = {};
newEditData.sourceID = editData.sourceID;
newEditData.content = editData.content;
newEditData.line = editData.line;
newEditData.linesCountToShift = -editData.linesCountToShift;
WebInspector.panels.scripts.editScriptSource(newEditData, this._editLineComplete.bind(this, newEditData));
},

_sourceIDForLine: function(line)
{
var sourceID = null;
var closestStartingLine = 0;
var scripts = this.resource.scripts;
for (var i = 0; i < scripts.length; ++i) {
var script = scripts[i];
if (script.startingLine <= line && script.startingLine >= closestStartingLine) {
closestStartingLine = script.startingLine;
sourceID = script.sourceID;
}
}
return sourceID;
},




searchCanceled: function()
{
this._currentSearchResultIndex = -1;
this._searchResults = [];
this.sourceFrame.clearMarkedRange();
delete this._delayedFindSearchMatches;
},

performSearch: function(query, finishedCallback)
{

this.searchCanceled();

this._searchFinishedCallback = finishedCallback;

function findSearchMatches(query, finishedCallback)
{
this._searchResults = this.sourceFrame.findSearchMatches(query);
if (this._searchResults)
finishedCallback(this, this._searchResults.length);
}

if (!this._sourceFrameSetup) {

this._delayedFindSearchMatches = findSearchMatches.bind(this, query, finishedCallback);
this.setupSourceFrameIfNeeded();
return;
}

findSearchMatches.call(this, query, finishedCallback);
},

jumpToFirstSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
this._currentSearchResultIndex = 0;
this._jumpToSearchResult(this._currentSearchResultIndex);
},

jumpToLastSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
this._currentSearchResultIndex = (this._searchResults.length - 1);
this._jumpToSearchResult(this._currentSearchResultIndex);
},

jumpToNextSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
if (++this._currentSearchResultIndex >= this._searchResults.length)
this._currentSearchResultIndex = 0;
this._jumpToSearchResult(this._currentSearchResultIndex);
},

jumpToPreviousSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
if (--this._currentSearchResultIndex < 0)
this._currentSearchResultIndex = (this._searchResults.length - 1);
this._jumpToSearchResult(this._currentSearchResultIndex);
},

showingFirstSearchResult: function()
{
return (this._currentSearchResultIndex === 0);
},

showingLastSearchResult: function()
{
return (this._searchResults && this._currentSearchResultIndex === (this._searchResults.length - 1));
},

revealLine: function(lineNumber)
{
this.setupSourceFrameIfNeeded();
this.sourceFrame.revealLine(lineNumber);
},

highlightLine: function(lineNumber)
{
this.setupSourceFrameIfNeeded();
this.sourceFrame.highlightLine(lineNumber);
},

addMessage: function(msg)
{
this.sourceFrame.addMessage(msg);
},

clearMessages: function()
{
this.sourceFrame.clearMessages();
},

_jumpToSearchResult: function(index)
{
var foundRange = this._searchResults[index];
if (!foundRange)
return;

this.sourceFrame.markAndRevealRange(foundRange);
},

_sourceFrameSetupFinished: function()
{
this._sourceFrameSetup = true;
this.resize();
if (this._delayedFindSearchMatches) {
this._delayedFindSearchMatches();
delete this._delayedFindSearchMatches;
}
}
}

WebInspector.SourceView.prototype.__proto__ = WebInspector.ResourceView.prototype;





WebInspector.FontView = function(resource)
{
WebInspector.ResourceView.call(this, resource);

this.element.addStyleClass("font");
}

WebInspector.FontView.prototype = {
hasContent: function()
{
return true;
},

_createContentIfNeeded: function()
{
if (this.fontPreviewElement)
return;

var uniqueFontName = "WebInspectorFontPreview" + this.resource.identifier;

this.fontStyleElement = document.createElement("style");
this.fontStyleElement.textContent = "@font-face { font-family: \"" + uniqueFontName + "\"; src: url(" + this.resource.url + "); }";
document.head.appendChild(this.fontStyleElement);

this.fontPreviewElement = document.createElement("div");
this.element.appendChild(this.fontPreviewElement);

this.fontPreviewElement.style.setProperty("font-family", uniqueFontName, null);
this.fontPreviewElement.innerHTML = "ABCDEFGHIJKLM<br>NOPQRSTUVWXYZ<br>abcdefghijklm<br>nopqrstuvwxyz<br>1234567890";
this._lineCount = this.fontPreviewElement.getElementsByTagName("br").length + 1;

this.updateFontPreviewSize();
},

show: function(parentElement)
{
WebInspector.ResourceView.prototype.show.call(this, parentElement);
this._createContentIfNeeded();
this.updateFontPreviewSize();
},

resize: function()
{
this.updateFontPreviewSize();
WebInspector.ResourceView.prototype.resize.call(this);
},

updateFontPreviewSize: function()
{
if (!this.fontPreviewElement || !this.visible)
return;

const measureFontSize = 50;
this.fontPreviewElement.style.setProperty("font-size", measureFontSize + "px", null);
this.fontPreviewElement.style.setProperty("position", "absolute", null);
this.fontPreviewElement.style.removeProperty("height");

const height = this.fontPreviewElement.offsetHeight;
const width = this.fontPreviewElement.offsetWidth;


const containerWidth = this.element.offsetWidth - 50;

if (!height || !width || !containerWidth) {
this.fontPreviewElement.style.removeProperty("font-size");
this.fontPreviewElement.style.removeProperty("position");
return;
}

var realLineHeight = Math.floor(height / this._lineCount);
var fontSizeLineRatio = measureFontSize / realLineHeight;
var widthRatio = containerWidth / width;
var finalFontSize = Math.floor(realLineHeight * widthRatio * fontSizeLineRatio) - 2;

this.fontPreviewElement.style.setProperty("font-size", finalFontSize + "px", null);
this.fontPreviewElement.style.setProperty("height", this.fontPreviewElement.offsetHeight + "px", null);
this.fontPreviewElement.style.removeProperty("position");
}
}

WebInspector.FontView.prototype.__proto__ = WebInspector.ResourceView.prototype;





WebInspector.ImageView = function(resource)
{
WebInspector.ResourceView.call(this, resource);

this.element.addStyleClass("image");
}

WebInspector.ImageView.prototype = {
hasContent: function()
{
return true;
},

show: function(parentElement)
{
WebInspector.ResourceView.prototype.show.call(this, parentElement);
this._createContentIfNeeded();
},

_createContentIfNeeded: function()
{
if (this._container)
return;

var imageContainer = document.createElement("div");
imageContainer.className = "image";
this.element.appendChild(imageContainer);

var imagePreviewElement = document.createElement("img");
imagePreviewElement.addStyleClass("resource-image-view");
imageContainer.appendChild(imagePreviewElement);

this._container = document.createElement("div");
this._container.className = "info";
this.element.appendChild(this._container);

var imageNameElement = document.createElement("h1");
imageNameElement.className = "title";
imageNameElement.textContent = this.resource.displayName;
this._container.appendChild(imageNameElement);

var infoListElement = document.createElement("dl");
infoListElement.className = "infoList";

function onResourceContent(element, content)
{
imagePreviewElement.setAttribute("src", this.resource.contentURL);
}
this.resource.requestContent(onResourceContent.bind(this));


function onImageLoad()
{
var content = this.resource.content;
if (content)
var resourceSize = this._base64ToSize(content);
else
var resourceSize = this.resource.resourceSize;

var imageProperties = [
{ name: WebInspector.UIString("Dimensions"), value: WebInspector.UIString("%d × %d", imagePreviewElement.naturalWidth, imagePreviewElement.naturalHeight) },
{ name: WebInspector.UIString("File size"), value: Number.bytesToString(resourceSize, WebInspector.UIString) },
{ name: WebInspector.UIString("MIME type"), value: this.resource.mimeType }
];

infoListElement.removeChildren();
for (var i = 0; i < imageProperties.length; ++i) {
var dt = document.createElement("dt");
dt.textContent = imageProperties[i].name;
infoListElement.appendChild(dt);
var dd = document.createElement("dd");
dd.textContent = imageProperties[i].value;
infoListElement.appendChild(dd);
}
this._container.appendChild(infoListElement);
}
imagePreviewElement.addEventListener("load", onImageLoad.bind(this), false);
},

_base64ToSize: function(content)
{
if (!content.length)
return 0;
var size = (content.length || 0) * 3 / 4;
if (content.length > 0 && content[content.length - 1] === "=")
size--;
if (content.length > 1 && content[content.length - 2] === "=")
size--;
return size;
}
}

WebInspector.ImageView.prototype.__proto__ = WebInspector.ResourceView.prototype;





WebInspector.DatabaseTableView = function(database, tableName)
{
WebInspector.View.call(this);

this.database = database;
this.tableName = tableName;

this.element.addStyleClass("storage-view");
this.element.addStyleClass("table");

this.refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
this.refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
}

WebInspector.DatabaseTableView.prototype = {
show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);
this.update();
},

get statusBarItems()
{
return [this.refreshButton.element];
},

update: function()
{
this.database.executeSql("SELECT * FROM " + this.tableName, this._queryFinished.bind(this), this._queryError.bind(this));
},

_queryFinished: function(columnNames, values)
{
this.element.removeChildren();

var dataGrid = WebInspector.panels.resources.dataGridForResult(columnNames, values);
if (!dataGrid) {
var emptyMsgElement = document.createElement("div");
emptyMsgElement.className = "storage-empty-view";
emptyMsgElement.textContent = WebInspector.UIString("The “%s”\ntable is empty.", this.tableName);
this.element.appendChild(emptyMsgElement);
return;
}

this.element.appendChild(dataGrid.element);
dataGrid.autoSizeColumns(5);
},

_queryError: function(error)
{
this.element.removeChildren();

var errorMsgElement = document.createElement("div");
errorMsgElement.className = "storage-table-error";
errorMsgElement.textContent = WebInspector.UIString("An error occurred trying to\nread the “%s” table.", this.tableName);
this.element.appendChild(errorMsgElement);
},

_refreshButtonClicked: function(event)
{
this.update();
}
}

WebInspector.DatabaseTableView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.DatabaseQueryView = function(database)
{
WebInspector.View.call(this);

this.database = database;

this.element.addStyleClass("storage-view");
this.element.addStyleClass("query");
this.element.addStyleClass("monospace");
this.element.tabIndex = 0;

this.element.addEventListener("selectstart", this._selectStart.bind(this), false);

this.promptElement = document.createElement("div");
this.promptElement.className = "database-query-prompt";
this.promptElement.appendChild(document.createElement("br"));
this.promptElement.addEventListener("keydown", this._promptKeyDown.bind(this), true);
this.element.appendChild(this.promptElement);

this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), " ");
}

WebInspector.DatabaseQueryView.prototype = {
show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);

function moveBackIfOutside()
{
if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
this.prompt.moveCaretToEndOfPrompt();
}

setTimeout(moveBackIfOutside.bind(this), 0);
},

completions: function(wordRange, bestMatchOnly, completionsReadyCallback)
{
var prefix = wordRange.toString().toLowerCase();
if (!prefix.length)
return;

var results = [];

function accumulateMatches(textArray)
{
if (bestMatchOnly && results.length)
return;
for (var i = 0; i < textArray.length; ++i) {
var text = textArray[i].toLowerCase();
if (text.length < prefix.length)
continue;
if (text.indexOf(prefix) !== 0)
continue;
results.push(textArray[i]);
if (bestMatchOnly)
return;
}
}

function tableNamesCallback(tableNames)
{
accumulateMatches(tableNames.map(function(name) { return name + " " }));
accumulateMatches(["SELECT ", "FROM ", "WHERE ", "LIMIT ", "DELETE FROM ", "CREATE ", "DROP ", "TABLE ", "INDEX ", "UPDATE ", "INSERT INTO ", "VALUES ("]);

completionsReadyCallback(results);
}
this.database.getTableNames(tableNamesCallback);
},

_promptKeyDown: function(event)
{
if (isEnterKey(event)) {
this._enterKeyPressed(event);
return;
}
},

_selectStart: function(event)
{
if (this._selectionTimeout)
clearTimeout(this._selectionTimeout);

this.prompt.clearAutoComplete();

function moveBackIfOutside()
{
delete this._selectionTimeout;
if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
this.prompt.moveCaretToEndOfPrompt();
this.prompt.autoCompleteSoon();
}

this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
},

_enterKeyPressed: function(event)
{
event.preventDefault();
event.stopPropagation();

this.prompt.clearAutoComplete(true);

var query = this.prompt.text;
if (!query.length)
return;

this.prompt.history.push(query);
this.prompt.historyOffset = 0;
this.prompt.text = "";

this.database.executeSql(query, this._queryFinished.bind(this, query), this._queryError.bind(this, query));
},

_queryFinished: function(query, columnNames, values)
{
var dataGrid = WebInspector.panels.resources.dataGridForResult(columnNames, values);
var trimmedQuery = query.trim();

if (dataGrid) {
dataGrid.element.addStyleClass("inline");
this._appendQueryResult(trimmedQuery, dataGrid.element);
dataGrid.autoSizeColumns(5);            
}

if (trimmedQuery.match(/^create /i) || trimmedQuery.match(/^drop table /i))
WebInspector.panels.resources.updateDatabaseTables(this.database);
},

_queryError: function(query, error)
{
if (error.message)
var message = error.message;
else if (error.code == 2)
var message = WebInspector.UIString("Database no longer has expected version.");
else
var message = WebInspector.UIString("An unexpected error %s occurred.", error.code);

this._appendQueryResult(query, message, "error");
},

_appendQueryResult: function(query, result, resultClassName)
{
var element = document.createElement("div");
element.className = "database-user-query";

var commandTextElement = document.createElement("span");
commandTextElement.className = "database-query-text";
commandTextElement.textContent = query;
element.appendChild(commandTextElement);

var resultElement = document.createElement("div");
resultElement.className = "database-query-result";

if (resultClassName)
resultElement.addStyleClass(resultClassName);

if (typeof result === "string" || result instanceof String)
resultElement.textContent = result;
else if (result && result.nodeName)
resultElement.appendChild(result);

if (resultElement.childNodes.length)
element.appendChild(resultElement);

this.element.insertBefore(element, this.promptElement);
this.promptElement.scrollIntoView(false);
}
}

WebInspector.DatabaseQueryView.prototype.__proto__ = WebInspector.View.prototype;





WebInspector.ScriptView = function(script)
{
WebInspector.View.call(this);

this.element.addStyleClass("script-view");

this.script = script;

this._frameNeedsSetup = true;
this._sourceFrameSetup = false;
var canEditScripts = WebInspector.panels.scripts.canEditScripts();
this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this));
}

WebInspector.ScriptView.prototype = {
show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);
this.setupSourceFrameIfNeeded();
this.sourceFrame.visible = true;
this.resize();
},

setupSourceFrameIfNeeded: function()
{
if (!this._frameNeedsSetup)
return;
delete this._frameNeedsSetup;

this.attach();

if (this.script.source)
this._sourceFrameSetupFinished();
else
InspectorBackend.getScriptSource(this.script.sourceID, this._didGetScriptSource.bind(this));
},

_didGetScriptSource: function(source)
{
this.script.source = source || WebInspector.UIString("<source is not available>");
this._sourceFrameSetupFinished();
},

_sourceFrameSetupFinished: function()
{
this.sourceFrame.setContent("text/javascript", this._prependWhitespace(this.script.source));
this._sourceFrameSetup = true;
},

_prependWhitespace: function(content) {
var prefix = "";
for (var i = 0; i < this.script.startingLine - 1; ++i)
prefix += "\n";
return prefix + content;
},

attach: function()
{
if (!this.element.parentNode)
document.getElementById("script-resource-views").appendChild(this.element);
},

_continueToLine: function(line)
{
var scriptsPanel = WebInspector.panels.scripts;
if (scriptsPanel)
scriptsPanel.continueToLine(this.script.sourceID, line);
},

_addBreakpoint: function(line)
{
WebInspector.breakpointManager.setBreakpoint(this.script.sourceID, this.script.sourceURL, line, true, "");
if (!WebInspector.panels.scripts.breakpointsActivated)
WebInspector.panels.scripts.toggleBreakpointsClicked();
},

_editLineComplete: function(newBody)
{
this.script.source = newBody;
this.sourceFrame.updateContent(this._prependWhitespace(newBody));
},

_sourceIDForLine: function(line)
{
return this.script.sourceID;
},




hide: WebInspector.SourceView.prototype.hide,
revealLine: WebInspector.SourceView.prototype.revealLine,
highlightLine: WebInspector.SourceView.prototype.highlightLine,
addMessage: WebInspector.SourceView.prototype.addMessage,
clearMessages: WebInspector.SourceView.prototype.clearMessages,
searchCanceled: WebInspector.SourceView.prototype.searchCanceled,
performSearch: WebInspector.SourceView.prototype.performSearch,
jumpToFirstSearchResult: WebInspector.SourceView.prototype.jumpToFirstSearchResult,
jumpToLastSearchResult: WebInspector.SourceView.prototype.jumpToLastSearchResult,
jumpToNextSearchResult: WebInspector.SourceView.prototype.jumpToNextSearchResult,
jumpToPreviousSearchResult: WebInspector.SourceView.prototype.jumpToPreviousSearchResult,
showingFirstSearchResult: WebInspector.SourceView.prototype.showingFirstSearchResult,
showingLastSearchResult: WebInspector.SourceView.prototype.showingLastSearchResult,
_jumpToSearchResult: WebInspector.SourceView.prototype._jumpToSearchResult,
_editLine: WebInspector.SourceView.prototype._editLine,
resize: WebInspector.SourceView.prototype.resize
}

WebInspector.ScriptView.prototype.__proto__ = WebInspector.View.prototype;






WebInspector.ProfileDataGridNode = function(profileView, profileNode, owningTree, hasChildren)
{
this.profileView = profileView;
this.profileNode = profileNode;

WebInspector.DataGridNode.call(this, null, hasChildren);

this.addEventListener("populate", this._populate, this);

this.tree = owningTree;

this.childrenByCallUID = {};
this.lastComparator = null;

this.callUID = profileNode.callUID;
this.selfTime = profileNode.selfTime;
this.totalTime = profileNode.totalTime;
this.functionName = profileNode.functionName;
this.numberOfCalls = profileNode.numberOfCalls;
this.url = profileNode.url;
}

WebInspector.ProfileDataGridNode.prototype = {
get data()
{
function formatMilliseconds(time)
{
return Number.secondsToString(time / 1000, WebInspector.UIString, !Preferences.samplingCPUProfiler);
}

var data = {};

data["function"] = this.functionName;
data["calls"] = this.numberOfCalls;

if (this.profileView.showSelfTimeAsPercent)
data["self"] = WebInspector.UIString("%.2f%%", this.selfPercent);
else
data["self"] = formatMilliseconds(this.selfTime);

if (this.profileView.showTotalTimeAsPercent)
data["total"] = WebInspector.UIString("%.2f%%", this.totalPercent);
else
data["total"] = formatMilliseconds(this.totalTime);

if (this.profileView.showAverageTimeAsPercent)
data["average"] = WebInspector.UIString("%.2f%%", this.averagePercent);
else
data["average"] = formatMilliseconds(this.averageTime);

return data;
},

createCell: function(columnIdentifier)
{
var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);

if (columnIdentifier === "self" && this._searchMatchedSelfColumn)
cell.addStyleClass("highlight");
else if (columnIdentifier === "total" && this._searchMatchedTotalColumn)
cell.addStyleClass("highlight");
else if (columnIdentifier === "average" && this._searchMatchedAverageColumn)
cell.addStyleClass("highlight");
else if (columnIdentifier === "calls" && this._searchMatchedCallsColumn)
cell.addStyleClass("highlight");

if (columnIdentifier !== "function")
return cell;

if (this.profileNode._searchMatchedFunctionColumn)
cell.addStyleClass("highlight");

if (this.profileNode.url) {
var lineNumber;
if (this.profileNode.lineNumber > 0)
lineNumber = this.profileNode.lineNumber;
var urlElement = WebInspector.linkifyResourceAsNode(this.profileNode.url, "scripts", lineNumber, "profile-node-file");
cell.insertBefore(urlElement, cell.firstChild);
}

return cell;
},

select: function(supressSelectedEvent)
{
WebInspector.DataGridNode.prototype.select.call(this, supressSelectedEvent);
this.profileView._dataGridNodeSelected(this);
},

deselect: function(supressDeselectedEvent)
{
WebInspector.DataGridNode.prototype.deselect.call(this, supressDeselectedEvent);
this.profileView._dataGridNodeDeselected(this);
},

sort: function(  comparator,   force)
{
var gridNodeGroups = [[this]];

for (var gridNodeGroupIndex = 0; gridNodeGroupIndex < gridNodeGroups.length; ++gridNodeGroupIndex) {
var gridNodes = gridNodeGroups[gridNodeGroupIndex];
var count = gridNodes.length;

for (var index = 0; index < count; ++index) {
var gridNode = gridNodes[index];



if (!force && (!gridNode.expanded || gridNode.lastComparator === comparator)) {
if (gridNode.children.length)
gridNode.shouldRefreshChildren = true;
continue;
}

gridNode.lastComparator = comparator;

var children = gridNode.children;
var childCount = children.length;

if (childCount) {
children.sort(comparator);

for (var childIndex = 0; childIndex < childCount; ++childIndex)
children[childIndex]._recalculateSiblings(childIndex);

gridNodeGroups.push(children);
}
}
}
},

insertChild: function(  profileDataGridNode, index)
{
WebInspector.DataGridNode.prototype.insertChild.call(this, profileDataGridNode, index);

this.childrenByCallUID[profileDataGridNode.callUID] = profileDataGridNode;
},

removeChild: function(  profileDataGridNode)
{
WebInspector.DataGridNode.prototype.removeChild.call(this, profileDataGridNode);

delete this.childrenByCallUID[profileDataGridNode.callUID];
},

removeChildren: function(  profileDataGridNode)
{
WebInspector.DataGridNode.prototype.removeChildren.call(this);

this.childrenByCallUID = {};
},

findChild: function(  node)
{
if (!node)
return null;
return this.childrenByCallUID[node.callUID];
},

get averageTime()
{
return this.selfTime / Math.max(1, this.numberOfCalls);
},

get averagePercent()
{
return this.averageTime / this.tree.totalTime * 100.0;
},

get selfPercent()
{
return this.selfTime / this.tree.totalTime * 100.0;
},

get totalPercent()
{
return this.totalTime / this.tree.totalTime * 100.0;
},

get _parent()
{
return this.parent !== this.dataGrid ? this.parent : this.tree;
},

_populate: function(event)
{
this._sharedPopulate();

if (this._parent) {
var currentComparator = this._parent.lastComparator;

if (currentComparator)
this.sort(currentComparator, true);
}

if (this.removeEventListener)
this.removeEventListener("populate", this._populate, this);
},



_save: function()
{
if (this._savedChildren)
return;

this._savedSelfTime = this.selfTime;
this._savedTotalTime = this.totalTime;
this._savedNumberOfCalls = this.numberOfCalls;

this._savedChildren = this.children.slice();
},



_restore: function()
{
if (!this._savedChildren)
return;

this.selfTime = this._savedSelfTime;
this.totalTime = this._savedTotalTime;
this.numberOfCalls = this._savedNumberOfCalls;

this.removeChildren();

var children = this._savedChildren;
var count = children.length;

for (var index = 0; index < count; ++index) {
children[index]._restore();
this.appendChild(children[index]);
}
},

_merge: function(child, shouldAbsorb)
{
this.selfTime += child.selfTime;

if (!shouldAbsorb) {
this.totalTime += child.totalTime;
this.numberOfCalls += child.numberOfCalls;
}

var children = this.children.slice();

this.removeChildren();

var count = children.length;

for (var index = 0; index < count; ++index) {
if (!shouldAbsorb || children[index] !== child)
this.appendChild(children[index]);
}

children = child.children.slice();
count = children.length;

for (var index = 0; index < count; ++index) {
var orphanedChild = children[index],
existingChild = this.childrenByCallUID[orphanedChild.callUID];

if (existingChild)
existingChild._merge(orphanedChild, false);
else
this.appendChild(orphanedChild);
}
}
}

WebInspector.ProfileDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;

WebInspector.ProfileDataGridTree = function(profileView, profileNode)
{
this.tree = this;
this.children = [];

this.profileView = profileView;

this.totalTime = profileNode.totalTime;
this.lastComparator = null;

this.childrenByCallUID = {};
}

WebInspector.ProfileDataGridTree.prototype = {
get expanded()
{
return true;
},

appendChild: function(child)
{
this.insertChild(child, this.children.length);
},

insertChild: function(child, index)
{
this.children.splice(index, 0, child);
this.childrenByCallUID[child.callUID] = child;
},

removeChildren: function()
{
this.children = [];
this.childrenByCallUID = {};
},

findChild: WebInspector.ProfileDataGridNode.prototype.findChild,
sort: WebInspector.ProfileDataGridNode.prototype.sort,

_save: function()
{
if (this._savedChildren)
return;

this._savedTotalTime = this.totalTime;
this._savedChildren = this.children.slice();
},

restore: function()
{
if (!this._savedChildren)
return;

this.children = this._savedChildren;
this.totalTime = this._savedTotalTime;

var children = this.children;
var count = children.length;

for (var index = 0; index < count; ++index)
children[index]._restore();

this._savedChildren = null;
}
}

WebInspector.ProfileDataGridTree.propertyComparators = [{}, {}];

WebInspector.ProfileDataGridTree.propertyComparator = function(  property,   isAscending)
{
var comparator = this.propertyComparators[(isAscending ? 1 : 0)][property];

if (!comparator) {
if (isAscending) {
comparator = function(lhs, rhs)
{
if (lhs[property] < rhs[property])
return -1;

if (lhs[property] > rhs[property])
return 1;

return 0;
}
} else {
comparator = function(lhs, rhs)
{
if (lhs[property] > rhs[property])
return -1;

if (lhs[property] < rhs[property])
return 1;

return 0;
}
}

this.propertyComparators[(isAscending ? 1 : 0)][property] = comparator;
}

return comparator;
}











WebInspector.BottomUpProfileDataGridNode = function(  profileView,   profileNode,   owningTree)
{
WebInspector.ProfileDataGridNode.call(this, profileView, profileNode, owningTree, this._willHaveChildren(profileNode));

this._remainingNodeInfos = [];
}

WebInspector.BottomUpProfileDataGridNode.prototype = {
_takePropertiesFromProfileDataGridNode: function(  profileDataGridNode)
{
this._save();

this.selfTime = profileDataGridNode.selfTime;
this.totalTime = profileDataGridNode.totalTime;
this.numberOfCalls = profileDataGridNode.numberOfCalls;
},


_keepOnlyChild: function(  child)
{
this._save();

this.removeChildren();
this.appendChild(child);
},

_exclude: function(aCallUID)
{
if (this._remainingNodeInfos)
this._populate();

this._save();

var children = this.children;
var index = this.children.length;

while (index--)
children[index]._exclude(aCallUID);

var child = this.childrenByCallUID[aCallUID];

if (child)
this._merge(child, true);
},

_restore: function()
{
WebInspector.ProfileDataGridNode.prototype._restore();

if (!this.children.length)
this.hasChildren = this._willHaveChildren();
},

_merge: function(  child,   shouldAbsorb)
{
this.selfTime -= child.selfTime;

WebInspector.ProfileDataGridNode.prototype._merge.call(this, child, shouldAbsorb);
},

_sharedPopulate: function()
{
var remainingNodeInfos = this._remainingNodeInfos;
var count = remainingNodeInfos.length;

for (var index = 0; index < count; ++index) {
var nodeInfo = remainingNodeInfos[index];
var ancestor = nodeInfo.ancestor;
var focusNode = nodeInfo.focusNode;
var child = this.findChild(ancestor);


if (child) {
var totalTimeAccountedFor = nodeInfo.totalTimeAccountedFor;

child.selfTime += focusNode.selfTime;
child.numberOfCalls += focusNode.numberOfCalls;

if (!totalTimeAccountedFor)
child.totalTime += focusNode.totalTime;
} else {


var child = new WebInspector.BottomUpProfileDataGridNode(this.profileView, ancestor, this.tree);

if (ancestor !== focusNode) {

child.selfTime = focusNode.selfTime;
child.totalTime = focusNode.totalTime;
child.numberOfCalls = focusNode.numberOfCalls;
}

this.appendChild(child);
}

var parent = ancestor.parent;
if (parent && parent.parent) {
nodeInfo.ancestor = parent;
child._remainingNodeInfos.push(nodeInfo);
}
}

delete this._remainingNodeInfos;
},

_willHaveChildren: function(profileNode)
{
profileNode = profileNode || this.profileNode;


return !!(profileNode.parent && profileNode.parent.parent);
}
}

WebInspector.BottomUpProfileDataGridNode.prototype.__proto__ = WebInspector.ProfileDataGridNode.prototype;

WebInspector.BottomUpProfileDataGridTree = function(  aProfileView,   aProfileNode)
{
WebInspector.ProfileDataGridTree.call(this, aProfileView, aProfileNode);


var profileNodeUIDs = 0;
var profileNodeGroups = [[], [aProfileNode]];
var visitedProfileNodesForCallUID = {};

this._remainingNodeInfos = [];

for (var profileNodeGroupIndex = 0; profileNodeGroupIndex < profileNodeGroups.length; ++profileNodeGroupIndex) {
var parentProfileNodes = profileNodeGroups[profileNodeGroupIndex];
var profileNodes = profileNodeGroups[++profileNodeGroupIndex];
var count = profileNodes.length;

for (var index = 0; index < count; ++index) {
var profileNode = profileNodes[index];

if (!profileNode.UID)
profileNode.UID = ++profileNodeUIDs;

if (profileNode.head && profileNode !== profileNode.head) {

var visitedNodes = visitedProfileNodesForCallUID[profileNode.callUID];
var totalTimeAccountedFor = false;

if (!visitedNodes) {
visitedNodes = {}
visitedProfileNodesForCallUID[profileNode.callUID] = visitedNodes;
} else {


var parentCount = parentProfileNodes.length;
for (var parentIndex = 0; parentIndex < parentCount; ++parentIndex) {
if (visitedNodes[parentProfileNodes[parentIndex].UID]) {
totalTimeAccountedFor = true;
break;
}
}
}

visitedNodes[profileNode.UID] = true;

this._remainingNodeInfos.push({ ancestor:profileNode, focusNode:profileNode, totalTimeAccountedFor:totalTimeAccountedFor });
}

var children = profileNode.children;
if (children.length) {
profileNodeGroups.push(parentProfileNodes.concat([profileNode]))
profileNodeGroups.push(children);
}
}
}


WebInspector.BottomUpProfileDataGridNode.prototype._populate.call(this);

return this;
}

WebInspector.BottomUpProfileDataGridTree.prototype = {

focus: function(  profileDataGridNode)
{
if (!profileDataGridNode)
return;

this._save();

var currentNode = profileDataGridNode;
var focusNode = profileDataGridNode;

while (currentNode.parent && (currentNode instanceof WebInspector.ProfileDataGridNode)) {
currentNode._takePropertiesFromProfileDataGridNode(profileDataGridNode);

focusNode = currentNode;
currentNode = currentNode.parent;

if (currentNode instanceof WebInspector.ProfileDataGridNode)
currentNode._keepOnlyChild(focusNode);
}

this.children = [focusNode];
this.totalTime = profileDataGridNode.totalTime;
},

exclude: function(  profileDataGridNode)
{
if (!profileDataGridNode)
return;

this._save();

var excludedCallUID = profileDataGridNode.callUID;
var excludedTopLevelChild = this.childrenByCallUID[excludedCallUID];



if (excludedTopLevelChild)
this.children.remove(excludedTopLevelChild);

var children = this.children;
var count = children.length;

for (var index = 0; index < count; ++index)
children[index]._exclude(excludedCallUID);

if (this.lastComparator)
this.sort(this.lastComparator, true);
},

_sharedPopulate: WebInspector.BottomUpProfileDataGridNode.prototype._sharedPopulate
}

WebInspector.BottomUpProfileDataGridTree.prototype.__proto__ = WebInspector.ProfileDataGridTree.prototype;






WebInspector.TopDownProfileDataGridNode = function(  profileView,   profileNode,   owningTree)
{
var hasChildren = (profileNode.children && profileNode.children.length);

WebInspector.ProfileDataGridNode.call(this, profileView, profileNode, owningTree, hasChildren);

this._remainingChildren = profileNode.children;
}

WebInspector.TopDownProfileDataGridNode.prototype = {
_sharedPopulate: function()
{
var children = this._remainingChildren;
var childrenLength = children.length;

for (var i = 0; i < childrenLength; ++i)
this.appendChild(new WebInspector.TopDownProfileDataGridNode(this.profileView, children[i], this.tree));

this._remainingChildren = null;
},

_exclude: function(aCallUID)
{
if (this._remainingChildren)
this._populate();

this._save();

var children = this.children;
var index = this.children.length;

while (index--)
children[index]._exclude(aCallUID);

var child = this.childrenByCallUID[aCallUID];

if (child)
this._merge(child, true);
}
}

WebInspector.TopDownProfileDataGridNode.prototype.__proto__ = WebInspector.ProfileDataGridNode.prototype;

WebInspector.TopDownProfileDataGridTree = function(  profileView,   profileNode)
{
WebInspector.ProfileDataGridTree.call(this, profileView, profileNode);

this._remainingChildren = profileNode.children;

WebInspector.TopDownProfileDataGridNode.prototype._populate.call(this);
}

WebInspector.TopDownProfileDataGridTree.prototype = {
focus: function(  profileDataGrideNode)
{
if (!profileDataGrideNode)
return;

this._save();
profileDataGrideNode.savePosition();

this.children = [profileDataGrideNode];
this.totalTime = profileDataGrideNode.totalTime;
},

exclude: function(  profileDataGrideNode)
{
if (!profileDataGrideNode)
return;

this._save();

var excludedCallUID = profileDataGrideNode.callUID;

WebInspector.TopDownProfileDataGridNode.prototype._exclude.call(this, excludedCallUID);

if (this.lastComparator)
this.sort(this.lastComparator, true);
},

restore: function()
{
if (!this._savedChildren)
return;

this.children[0].restorePosition();

WebInspector.ProfileDataGridTree.prototype.restore.call(this);
},

_merge: WebInspector.TopDownProfileDataGridNode.prototype._merge,

_sharedPopulate: WebInspector.TopDownProfileDataGridNode.prototype._sharedPopulate
}

WebInspector.TopDownProfileDataGridTree.prototype.__proto__ = WebInspector.ProfileDataGridTree.prototype;







WebInspector.CPUProfileView = function(profile)
{
WebInspector.View.call(this);

this.element.addStyleClass("profile-view");

this.showSelfTimeAsPercent = true;
this.showTotalTimeAsPercent = true;
this.showAverageTimeAsPercent = true;

var columns = { "self": { title: WebInspector.UIString("Self"), width: "72px", sort: "descending", sortable: true },
"total": { title: WebInspector.UIString("Total"), width: "72px", sortable: true },
"average": { title: WebInspector.UIString("Average"), width: "72px", sortable: true },
"calls": { title: WebInspector.UIString("Calls"), width: "54px", sortable: true },
"function": { title: WebInspector.UIString("Function"), disclosure: true, sortable: true } };

if (Preferences.samplingCPUProfiler) {
delete columns.average;
delete columns.calls;
}

this.dataGrid = new WebInspector.DataGrid(columns);
this.dataGrid.addEventListener("sorting changed", this._sortData, this);
this.dataGrid.element.addEventListener("mousedown", this._mouseDownInDataGrid.bind(this), true);
this.element.appendChild(this.dataGrid.element);

this.viewSelectElement = document.createElement("select");
this.viewSelectElement.className = "status-bar-item";
this.viewSelectElement.addEventListener("change", this._changeView.bind(this), false);
this.view = "Heavy";

var heavyViewOption = document.createElement("option");
heavyViewOption.label = WebInspector.UIString("Heavy (Bottom Up)");
var treeViewOption = document.createElement("option");
treeViewOption.label = WebInspector.UIString("Tree (Top Down)");
this.viewSelectElement.appendChild(heavyViewOption);
this.viewSelectElement.appendChild(treeViewOption);

this.percentButton = new WebInspector.StatusBarButton("", "percent-time-status-bar-item");
this.percentButton.addEventListener("click", this._percentClicked.bind(this), false);

this.focusButton = new WebInspector.StatusBarButton(WebInspector.UIString("Focus selected function."), "focus-profile-node-status-bar-item");
this.focusButton.disabled = true;
this.focusButton.addEventListener("click", this._focusClicked.bind(this), false);

this.excludeButton = new WebInspector.StatusBarButton(WebInspector.UIString("Exclude selected function."), "exclude-profile-node-status-bar-item");
this.excludeButton.disabled = true;
this.excludeButton.addEventListener("click", this._excludeClicked.bind(this), false);

this.resetButton = new WebInspector.StatusBarButton(WebInspector.UIString("Restore all functions."), "reset-profile-status-bar-item");
this.resetButton.visible = false;
this.resetButton.addEventListener("click", this._resetClicked.bind(this), false);

this.profile = profile;

var self = this;
function profileCallback(profile)
{
self.profile.head = profile.head;
self._assignParentsInProfile();

self.profileDataGridTree = self.bottomUpProfileDataGridTree;
self.profileDataGridTree.sort(WebInspector.ProfileDataGridTree.propertyComparator("selfTime", false));

self.refresh();

self._updatePercentButton();
}

InspectorBackend.getProfile(this.profile.typeId, this.profile.uid, profileCallback);
}

WebInspector.CPUProfileView.prototype = {
get statusBarItems()
{
return [this.viewSelectElement, this.percentButton.element, this.focusButton.element, this.excludeButton.element, this.resetButton.element];
},

get profile()
{
return this._profile;
},

set profile(profile)
{
this._profile = profile;
},

get bottomUpProfileDataGridTree()
{
if (!this._bottomUpProfileDataGridTree)
this._bottomUpProfileDataGridTree = new WebInspector.BottomUpProfileDataGridTree(this, this.profile.head);
return this._bottomUpProfileDataGridTree;
},

get topDownProfileDataGridTree()
{
if (!this._topDownProfileDataGridTree)
this._topDownProfileDataGridTree = new WebInspector.TopDownProfileDataGridTree(this, this.profile.head);
return this._topDownProfileDataGridTree;
},

get currentTree()
{
return this._currentTree;
},

set currentTree(tree)
{
this._currentTree = tree;
this.refresh();
},

get topDownTree()
{
if (!this._topDownTree) {
this._topDownTree = WebInspector.TopDownTreeFactory.create(this.profile.head);
this._sortProfile(this._topDownTree);
}

return this._topDownTree;
},

get bottomUpTree()
{
if (!this._bottomUpTree) {
this._bottomUpTree = WebInspector.BottomUpTreeFactory.create(this.profile.head);
this._sortProfile(this._bottomUpTree);
}

return this._bottomUpTree;
},

show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);
this.dataGrid.updateWidths();
},

hide: function()
{
WebInspector.View.prototype.hide.call(this);
this._currentSearchResultIndex = -1;
},

resize: function()
{
if (this.dataGrid)
this.dataGrid.updateWidths();
},

refresh: function()
{
var selectedProfileNode = this.dataGrid.selectedNode ? this.dataGrid.selectedNode.profileNode : null;

this.dataGrid.removeChildren();

var children = this.profileDataGridTree.children;
var count = children.length;

for (var index = 0; index < count; ++index)
this.dataGrid.appendChild(children[index]);

if (selectedProfileNode)
selectedProfileNode.selected = true;
},

refreshVisibleData: function()
{
var child = this.dataGrid.children[0];
while (child) {
child.refresh();
child = child.traverseNextNode(false, null, true);
}
},

refreshShowAsPercents: function()
{
this._updatePercentButton();
this.refreshVisibleData();
},

searchCanceled: function()
{
if (this._searchResults) {
for (var i = 0; i < this._searchResults.length; ++i) {
var profileNode = this._searchResults[i].profileNode;

delete profileNode._searchMatchedSelfColumn;
delete profileNode._searchMatchedTotalColumn;
delete profileNode._searchMatchedCallsColumn;
delete profileNode._searchMatchedFunctionColumn;

profileNode.refresh();
}
}

delete this._searchFinishedCallback;
this._currentSearchResultIndex = -1;
this._searchResults = [];
},

performSearch: function(query, finishedCallback)
{

this.searchCanceled();

query = query.trim();

if (!query.length)
return;

this._searchFinishedCallback = finishedCallback;

var greaterThan = (query.indexOf(">") === 0);
var lessThan = (query.indexOf("<") === 0);
var equalTo = (query.indexOf("=") === 0 || ((greaterThan || lessThan) && query.indexOf("=") === 1));
var percentUnits = (query.lastIndexOf("%") === (query.length - 1));
var millisecondsUnits = (query.length > 2 && query.lastIndexOf("ms") === (query.length - 2));
var secondsUnits = (!millisecondsUnits && query.lastIndexOf("s") === (query.length - 1));

var queryNumber = parseFloat(query);
if (greaterThan || lessThan || equalTo) {
if (equalTo && (greaterThan || lessThan))
queryNumber = parseFloat(query.substring(2));
else
queryNumber = parseFloat(query.substring(1));
}

var queryNumberMilliseconds = (secondsUnits ? (queryNumber * 1000) : queryNumber);


if (!isNaN(queryNumber) && !(greaterThan || lessThan))
equalTo = true;

function matchesQuery(  profileDataGridNode)
{
delete profileDataGridNode._searchMatchedSelfColumn;
delete profileDataGridNode._searchMatchedTotalColumn;
delete profileDataGridNode._searchMatchedAverageColumn;
delete profileDataGridNode._searchMatchedCallsColumn;
delete profileDataGridNode._searchMatchedFunctionColumn;

if (percentUnits) {
if (lessThan) {
if (profileDataGridNode.selfPercent < queryNumber)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalPercent < queryNumber)
profileDataGridNode._searchMatchedTotalColumn = true;
if (profileDataGridNode.averagePercent < queryNumberMilliseconds)
profileDataGridNode._searchMatchedAverageColumn = true;
} else if (greaterThan) {
if (profileDataGridNode.selfPercent > queryNumber)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalPercent > queryNumber)
profileDataGridNode._searchMatchedTotalColumn = true;
if (profileDataGridNode.averagePercent < queryNumberMilliseconds)
profileDataGridNode._searchMatchedAverageColumn = true;
}

if (equalTo) {
if (profileDataGridNode.selfPercent == queryNumber)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalPercent == queryNumber)
profileDataGridNode._searchMatchedTotalColumn = true;
if (profileDataGridNode.averagePercent < queryNumberMilliseconds)
profileDataGridNode._searchMatchedAverageColumn = true;
}
} else if (millisecondsUnits || secondsUnits) {
if (lessThan) {
if (profileDataGridNode.selfTime < queryNumberMilliseconds)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalTime < queryNumberMilliseconds)
profileDataGridNode._searchMatchedTotalColumn = true;
if (profileDataGridNode.averageTime < queryNumberMilliseconds)
profileDataGridNode._searchMatchedAverageColumn = true;
} else if (greaterThan) {
if (profileDataGridNode.selfTime > queryNumberMilliseconds)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalTime > queryNumberMilliseconds)
profileDataGridNode._searchMatchedTotalColumn = true;
if (profileDataGridNode.averageTime > queryNumberMilliseconds)
profileDataGridNode._searchMatchedAverageColumn = true;
}

if (equalTo) {
if (profileDataGridNode.selfTime == queryNumberMilliseconds)
profileDataGridNode._searchMatchedSelfColumn = true;
if (profileDataGridNode.totalTime == queryNumberMilliseconds)
profileDataGridNode._searchMatchedTotalColumn = true;
if (profileDataGridNode.averageTime == queryNumberMilliseconds)
profileDataGridNode._searchMatchedAverageColumn = true;
}
} else {
if (equalTo && profileDataGridNode.numberOfCalls == queryNumber)
profileDataGridNode._searchMatchedCallsColumn = true;
if (greaterThan && profileDataGridNode.numberOfCalls > queryNumber)
profileDataGridNode._searchMatchedCallsColumn = true;
if (lessThan && profileDataGridNode.numberOfCalls < queryNumber)
profileDataGridNode._searchMatchedCallsColumn = true;
}

if (profileDataGridNode.functionName.hasSubstring(query, true) || profileDataGridNode.url.hasSubstring(query, true))
profileDataGridNode._searchMatchedFunctionColumn = true;

if (profileDataGridNode._searchMatchedSelfColumn ||
profileDataGridNode._searchMatchedTotalColumn ||
profileDataGridNode._searchMatchedAverageColumn ||
profileDataGridNode._searchMatchedCallsColumn ||
profileDataGridNode._searchMatchedFunctionColumn)
{
profileDataGridNode.refresh();
return true;
}

return false;
}

var current = this.profileDataGridTree.children[0];

while (current) {
if (matchesQuery(current)) {
this._searchResults.push({ profileNode: current });
}

current = current.traverseNextNode(false, null, false);
}

finishedCallback(this, this._searchResults.length);
},

jumpToFirstSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
this._currentSearchResultIndex = 0;
this._jumpToSearchResult(this._currentSearchResultIndex);
},

jumpToLastSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
this._currentSearchResultIndex = (this._searchResults.length - 1);
this._jumpToSearchResult(this._currentSearchResultIndex);
},

jumpToNextSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
if (++this._currentSearchResultIndex >= this._searchResults.length)
this._currentSearchResultIndex = 0;
this._jumpToSearchResult(this._currentSearchResultIndex);
},

jumpToPreviousSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
if (--this._currentSearchResultIndex < 0)
this._currentSearchResultIndex = (this._searchResults.length - 1);
this._jumpToSearchResult(this._currentSearchResultIndex);
},

showingFirstSearchResult: function()
{
return (this._currentSearchResultIndex === 0);
},

showingLastSearchResult: function()
{
return (this._searchResults && this._currentSearchResultIndex === (this._searchResults.length - 1));
},

_jumpToSearchResult: function(index)
{
var searchResult = this._searchResults[index];
if (!searchResult)
return;

var profileNode = searchResult.profileNode;
profileNode.reveal();
profileNode.select();
},

_changeView: function(event)
{
if (!event || !this.profile)
return;

if (event.target.selectedIndex == 1 && this.view == "Heavy") {
this.profileDataGridTree = this.topDownProfileDataGridTree;
this._sortProfile();
this.view = "Tree";
} else if (event.target.selectedIndex == 0 && this.view == "Tree") {
this.profileDataGridTree = this.bottomUpProfileDataGridTree;
this._sortProfile();
this.view = "Heavy";
}

if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
return;




this._searchFinishedCallback(this, -this._searchResults.length);
this.performSearch(this.currentQuery, this._searchFinishedCallback);
},

_percentClicked: function(event)
{
var currentState = this.showSelfTimeAsPercent && this.showTotalTimeAsPercent && this.showAverageTimeAsPercent;
this.showSelfTimeAsPercent = !currentState;
this.showTotalTimeAsPercent = !currentState;
this.showAverageTimeAsPercent = !currentState;
this.refreshShowAsPercents();
},

_updatePercentButton: function()
{
if (this.showSelfTimeAsPercent && this.showTotalTimeAsPercent && this.showAverageTimeAsPercent) {
this.percentButton.title = WebInspector.UIString("Show absolute total and self times.");
this.percentButton.toggled = true;
} else {
this.percentButton.title = WebInspector.UIString("Show total and self times as percentages.");
this.percentButton.toggled = false;
}
},

_focusClicked: function(event)
{
if (!this.dataGrid.selectedNode)
return;

this.resetButton.visible = true;
this.profileDataGridTree.focus(this.dataGrid.selectedNode);
this.refresh();
this.refreshVisibleData();
},

_excludeClicked: function(event)
{
var selectedNode = this.dataGrid.selectedNode

if (!selectedNode)
return;

selectedNode.deselect();

this.resetButton.visible = true;
this.profileDataGridTree.exclude(selectedNode);
this.refresh();
this.refreshVisibleData();
},

_resetClicked: function(event)
{
this.resetButton.visible = false;
this.profileDataGridTree.restore();
this.refresh();
this.refreshVisibleData();
},

_dataGridNodeSelected: function(node)
{
this.focusButton.disabled = false;
this.excludeButton.disabled = false;
},

_dataGridNodeDeselected: function(node)
{
this.focusButton.disabled = true;
this.excludeButton.disabled = true;
},

_sortData: function(event)
{
this._sortProfile(this.profile);
},

_sortProfile: function()
{
var sortAscending = this.dataGrid.sortOrder === "ascending";
var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
var sortProperty = {
"average": "averageTime",
"self": "selfTime",
"total": "totalTime",
"calls": "numberOfCalls",
"function": "functionName"
}[sortColumnIdentifier];

this.profileDataGridTree.sort(WebInspector.ProfileDataGridTree.propertyComparator(sortProperty, sortAscending));

this.refresh();
},

_mouseDownInDataGrid: function(event)
{
if (event.detail < 2)
return;

var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
if (!cell || (!cell.hasStyleClass("total-column") && !cell.hasStyleClass("self-column") && !cell.hasStyleClass("average-column")))
return;

if (cell.hasStyleClass("total-column"))
this.showTotalTimeAsPercent = !this.showTotalTimeAsPercent;
else if (cell.hasStyleClass("self-column"))
this.showSelfTimeAsPercent = !this.showSelfTimeAsPercent;
else if (cell.hasStyleClass("average-column"))
this.showAverageTimeAsPercent = !this.showAverageTimeAsPercent;

this.refreshShowAsPercents();

event.preventDefault();
event.stopPropagation();
},

_assignParentsInProfile: function()
{
var head = this.profile.head;
head.parent = null;
head.head = null;
var nodesToTraverse = [ { parent: head, children: head.children } ];
while (nodesToTraverse.length > 0) {
var pair = nodesToTraverse.shift();
var parent = pair.parent;
var children = pair.children;
var length = children.length;
for (var i = 0; i < length; ++i) {
children[i].head = head;
children[i].parent = parent;
if (children[i].children.length > 0)
nodesToTraverse.push({ parent: children[i], children: children[i].children });
}
}
}
}

WebInspector.CPUProfileView.prototype.__proto__ = WebInspector.View.prototype;

WebInspector.CPUProfileType = function()
{
WebInspector.ProfileType.call(this, WebInspector.CPUProfileType.TypeId, WebInspector.UIString("CPU PROFILES"));
this._recording = false;
}

WebInspector.CPUProfileType.TypeId = "CPU";

WebInspector.CPUProfileType.prototype = {
get buttonTooltip()
{
return this._recording ? WebInspector.UIString("Stop profiling.") : WebInspector.UIString("Start profiling.");
},

get buttonStyle()
{
return this._recording ? "record-profile-status-bar-item status-bar-item toggled-on" : "record-profile-status-bar-item status-bar-item";
},

buttonClicked: function()
{
this._recording = !this._recording;

if (this._recording)
InspectorBackend.startProfiling();
else
InspectorBackend.stopProfiling();
},

get welcomeMessage()
{
return WebInspector.UIString("Control CPU profiling by pressing the %s button on the status bar.");
},

setRecordingProfile: function(isProfiling)
{
this._recording = isProfiling;
},

createSidebarTreeElementForProfile: function(profile)
{
return new WebInspector.ProfileSidebarTreeElement(profile, WebInspector.UIString("Profile %d"), "profile-sidebar-tree-item");
},

createView: function(profile)
{
return new WebInspector.CPUProfileView(profile);
}
}

WebInspector.CPUProfileType.prototype.__proto__ = WebInspector.ProfileType.prototype;





WebInspector.HeapSnapshotView = function(parent, profile)
{
WebInspector.View.call(this);

this.element.addStyleClass("heap-snapshot-view");

this.parent = parent;
this.parent.addEventListener("profile added", this._updateBaseOptions, this);

this.showCountAsPercent = false;
this.showSizeAsPercent = false;
this.showCountDeltaAsPercent = false;
this.showSizeDeltaAsPercent = false;

this.categories = {
code: new WebInspector.ResourceCategory("code", WebInspector.UIString("Code"), "rgb(255,121,0)"),
data: new WebInspector.ResourceCategory("data", WebInspector.UIString("Objects"), "rgb(47,102,236)")
};

var summaryContainer = document.createElement("div");
summaryContainer.id = "heap-snapshot-summary-container";

this.countsSummaryBar = new WebInspector.SummaryBar(this.categories);
this.countsSummaryBar.element.className = "heap-snapshot-summary";
this.countsSummaryBar.calculator = new WebInspector.HeapSummaryCountCalculator();
var countsLabel = document.createElement("div");
countsLabel.className = "heap-snapshot-summary-label";
countsLabel.textContent = WebInspector.UIString("Count");
this.countsSummaryBar.element.appendChild(countsLabel);
summaryContainer.appendChild(this.countsSummaryBar.element);

this.sizesSummaryBar = new WebInspector.SummaryBar(this.categories);
this.sizesSummaryBar.element.className = "heap-snapshot-summary";
this.sizesSummaryBar.calculator = new WebInspector.HeapSummarySizeCalculator();
var sizesLabel = document.createElement("label");
sizesLabel.className = "heap-snapshot-summary-label";
sizesLabel.textContent = WebInspector.UIString("Size");
this.sizesSummaryBar.element.appendChild(sizesLabel);
summaryContainer.appendChild(this.sizesSummaryBar.element);

this.element.appendChild(summaryContainer);

var columns = {
cons: { title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true },
count: { title: WebInspector.UIString("Count"), width: "54px", sortable: true },
size: { title: WebInspector.UIString("Size"), width: "72px", sort: "descending", sortable: true },

countDelta: { title: WebInspector.UIString("\xb1 Count"), width: "72px", sortable: true },
sizeDelta: { title: WebInspector.UIString("\xb1 Size"), width: "72px", sortable: true }
};

this.dataGrid = new WebInspector.DataGrid(columns);
this.dataGrid.addEventListener("sorting changed", this._sortData, this);
this.dataGrid.element.addEventListener("mousedown", this._mouseDownInDataGrid.bind(this), true);
this.element.appendChild(this.dataGrid.element);

this.profile = profile;

this.baseSelectElement = document.createElement("select");
this.baseSelectElement.className = "status-bar-item";
this.baseSelectElement.addEventListener("change", this._changeBase.bind(this), false);
this._updateBaseOptions();

this.percentButton = new WebInspector.StatusBarButton("", "percent-time-status-bar-item status-bar-item");
this.percentButton.addEventListener("click", this._percentClicked.bind(this), false);

this._loadProfile(this.profile, profileCallback.bind(this));

function profileCallback(profile)
{
var list = this._getProfiles();
var profileIndex;
for (var i = 0; i < list.length; ++i)
if (list[i].uid === profile.uid) {
profileIndex = i;
break;
}
if (profileIndex > 0)
this.baseSelectElement.selectedIndex = profileIndex - 1;
else
this.baseSelectElement.selectedIndex = profileIndex;
this._resetDataGridList(resetCompleted.bind(this));
}

function resetCompleted()
{
this.refresh();
this._updatePercentButton();
}
}

WebInspector.HeapSnapshotView.prototype = {
get statusBarItems()
{
return [this.baseSelectElement, this.percentButton.element];
},

get profile()
{
return this._profile;
},

set profile(profile)
{
this._profile = profile;
},

show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);
this.dataGrid.updateWidths();
},

hide: function()
{
WebInspector.View.prototype.hide.call(this);
this._currentSearchResultIndex = -1;
},

resize: function()
{
if (this.dataGrid)
this.dataGrid.updateWidths();
},

refresh: function()
{
this.dataGrid.removeChildren();

var children = this.snapshotDataGridList.children;
var count = children.length;
for (var index = 0; index < count; ++index)
this.dataGrid.appendChild(children[index]);

this._updateSummaryGraph();
},

refreshShowAsPercents: function()
{
this._updatePercentButton();
this.refreshVisibleData();
},

_deleteSearchMatchedFlags: function(node)
{
delete node._searchMatchedConsColumn;
delete node._searchMatchedCountColumn;
delete node._searchMatchedSizeColumn;
delete node._searchMatchedCountDeltaColumn;
delete node._searchMatchedSizeDeltaColumn;
},

searchCanceled: function()
{
if (this._searchResults) {
for (var i = 0; i < this._searchResults.length; ++i) {
var profileNode = this._searchResults[i].profileNode;
this._deleteSearchMatchedFlags(profileNode);
profileNode.refresh();
}
}

delete this._searchFinishedCallback;
this._currentSearchResultIndex = -1;
this._searchResults = [];
},

performSearch: function(query, finishedCallback)
{

this.searchCanceled();

query = query.trim();

if (!query.length)
return;

this._searchFinishedCallback = finishedCallback;

var helper = WebInspector.HeapSnapshotView.SearchHelper;

var operationAndNumber = helper.parseOperationAndNumber(query);
var operation = operationAndNumber[0];
var queryNumber = operationAndNumber[1];

var percentUnits = helper.percents.test(query);
var megaBytesUnits = helper.megaBytes.test(query);
var kiloBytesUnits = helper.kiloBytes.test(query);
var bytesUnits = helper.bytes.test(query);

var queryNumberBytes = (megaBytesUnits ? (queryNumber * 1024 * 1024) : (kiloBytesUnits ? (queryNumber * 1024) : queryNumber));

function matchesQuery(heapSnapshotDataGridNode)
{
WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags(heapSnapshotDataGridNode);

if (percentUnits) {
heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.countPercent, queryNumber);
heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.sizePercent, queryNumber);
heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDeltaPercent, queryNumber);
heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDeltaPercent, queryNumber);
} else if (megaBytesUnits || kiloBytesUnits || bytesUnits) {
heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.size, queryNumberBytes);
heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDelta, queryNumberBytes);
} else {
heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.count, queryNumber);
heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDelta, queryNumber);
}

if (heapSnapshotDataGridNode.constructorName.hasSubstring(query, true))
heapSnapshotDataGridNode._searchMatchedConsColumn = true;

if (heapSnapshotDataGridNode._searchMatchedConsColumn ||
heapSnapshotDataGridNode._searchMatchedCountColumn ||
heapSnapshotDataGridNode._searchMatchedSizeColumn ||
heapSnapshotDataGridNode._searchMatchedCountDeltaColumn ||
heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn) {
heapSnapshotDataGridNode.refresh();
return true;
}

return false;
}

var current = this.snapshotDataGridList.children[0];
var depth = 0;
var info = {};




const maxDepth = 2;

while (current) {
if (matchesQuery(current))
this._searchResults.push({ profileNode: current });
current = current.traverseNextNode(false, null, (depth >= maxDepth), info);
depth += info.depthChange;
}

finishedCallback(this, this._searchResults.length);
},


jumpToFirstSearchResult: WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult,
jumpToLastSearchResult: WebInspector.CPUProfileView.prototype.jumpToLastSearchResult,
jumpToNextSearchResult: WebInspector.CPUProfileView.prototype.jumpToNextSearchResult,
jumpToPreviousSearchResult: WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult,
showingFirstSearchResult: WebInspector.CPUProfileView.prototype.showingFirstSearchResult,
showingLastSearchResult: WebInspector.CPUProfileView.prototype.showingLastSearchResult,
_jumpToSearchResult: WebInspector.CPUProfileView.prototype._jumpToSearchResult,

refreshVisibleData: function()
{
var child = this.dataGrid.children[0];
while (child) {
child.refresh();
child = child.traverseNextNode(false, null, true);
}
this._updateSummaryGraph();
},

_changeBase: function()
{
if (this.baseSnapshot.uid === this._getProfiles()[this.baseSelectElement.selectedIndex].uid)
return;

this._resetDataGridList(resetCompleted.bind(this));

function resetCompleted() {
this.refresh();

if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
return;




this._searchFinishedCallback(this, -this._searchResults.length);
this.performSearch(this.currentQuery, this._searchFinishedCallback);
}
},

_createSnapshotDataGridList: function()
{
if (this._snapshotDataGridList)
delete this._snapshotDataGridList;

this._snapshotDataGridList = new WebInspector.HeapSnapshotDataGridList(this, this.baseSnapshot.entries, this.profile.entries);
return this._snapshotDataGridList;
},

_getProfiles: function()
{
return WebInspector.panels.profiles.getProfiles(WebInspector.HeapSnapshotProfileType.TypeId);
},

_loadProfile: function(profile, callback)
{
if (profile._loaded) {
callback(profile);
return;
}

InspectorBackend.getProfile(profile.typeId, profile.uid, loadedCallback.bind(this));

function loadedCallback(loadedSnapshot) {
profile.children = loadedSnapshot.head.children;
profile.entries = loadedSnapshot.head.entries;
profile.lowlevels = loadedSnapshot.head.lowlevels;
this._prepareProfile(profile);
profile._loaded = true;
this.parent.updateProfile(profile);
callback(profile);
}
},

_mouseDownInDataGrid: function(event)
{
if (event.detail < 2)
return;

var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
if (!cell || (!cell.hasStyleClass("count-column") && !cell.hasStyleClass("size-column") && !cell.hasStyleClass("countDelta-column") && !cell.hasStyleClass("sizeDelta-column")))
return;

if (cell.hasStyleClass("count-column"))
this.showCountAsPercent = !this.showCountAsPercent;
else if (cell.hasStyleClass("size-column"))
this.showSizeAsPercent = !this.showSizeAsPercent;
else if (cell.hasStyleClass("countDelta-column"))
this.showCountDeltaAsPercent = !this.showCountDeltaAsPercent;
else if (cell.hasStyleClass("sizeDelta-column"))
this.showSizeDeltaAsPercent = !this.showSizeDeltaAsPercent;

this.refreshShowAsPercents();

event.preventDefault();
event.stopPropagation();
},

get _isShowingAsPercent()
{
return this.showCountAsPercent && this.showSizeAsPercent && this.showCountDeltaAsPercent && this.showSizeDeltaAsPercent;
},

_percentClicked: function(event)
{
var currentState = this._isShowingAsPercent;
this.showCountAsPercent = !currentState;
this.showSizeAsPercent = !currentState;
this.showCountDeltaAsPercent = !currentState;
this.showSizeDeltaAsPercent = !currentState;
this.refreshShowAsPercents();
},

_prepareProfile: function(profile)
{
for (var profileEntry in profile.entries)
profile.entries[profileEntry].retainers = {};
profile.clusters = {};

for (var addr in profile.children) {
var retainer = profile.children[addr];
var retainerId = retainer.constructorName + ':' + addr;
for (var childAddr in retainer) {
if (childAddr === 'constructorName') continue;
var item = retainer[childAddr];
var itemId = item.constructorName + ':' + childAddr;
if ((item.constructorName === 'Object' || item.constructorName === 'Array')) {
if (!(itemId in profile.clusters))
profile.clusters[itemId] = { constructorName: itemId, retainers: {} };
mergeRetainers(profile.clusters[itemId], item);
}
mergeRetainers(profile.entries[item.constructorName], item);
}
}

function mergeRetainers(entry, item)
{
if (!(retainer.constructorName in entry.retainers))
entry.retainers[retainer.constructorName] = { constructorName: retainer.constructorName, count: 0, clusters: {} };
var retainerEntry = entry.retainers[retainer.constructorName];
retainerEntry.count += item.count;
if (retainer.constructorName === 'Object' || retainer.constructorName === 'Array')
retainerEntry.clusters[retainerId] = true;
}
},

_resetDataGridList: function(callback)
{
this._loadProfile(this._getProfiles()[this.baseSelectElement.selectedIndex], profileLoaded.bind(this));

function profileLoaded(profile)
{
this.baseSnapshot = profile;
var lastComparator = WebInspector.HeapSnapshotDataGridList.propertyComparator("size", false);
if (this.snapshotDataGridList)
lastComparator = this.snapshotDataGridList.lastComparator;
this.snapshotDataGridList = this._createSnapshotDataGridList();
this.snapshotDataGridList.sort(lastComparator, true);
callback();
}
},

_sortData: function()
{
var sortAscending = this.dataGrid.sortOrder === "ascending";
var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
var sortProperty = {
cons: ["cons", null],
count: ["count", null],
size: ["size", "count"],
countDelta: this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null],
sizeDelta: this.showSizeDeltaAsPercent ? ["sizeDeltaPercent", "countDeltaPercent"] : ["sizeDelta", "sizeDeltaPercent"]
}[sortColumnIdentifier];

this.snapshotDataGridList.sort(WebInspector.HeapSnapshotDataGridList.propertyComparator(sortProperty[0], sortProperty[1], sortAscending));

this.refresh();
},

_updateBaseOptions: function()
{
var list = this._getProfiles();

if (this.baseSelectElement.length === list.length)
return;

for (var i = this.baseSelectElement.length, n = list.length; i < n; ++i) {
var baseOption = document.createElement("option");
var title = list[i].title;
if (!title.indexOf(UserInitiatedProfileName))
title = WebInspector.UIString("Snapshot %d", title.substring(UserInitiatedProfileName.length + 1));
baseOption.label = WebInspector.UIString("Compared to %s", title);
this.baseSelectElement.appendChild(baseOption);
}
},

_updatePercentButton: function()
{
if (this._isShowingAsPercent) {
this.percentButton.title = WebInspector.UIString("Show absolute counts and sizes.");
this.percentButton.toggled = true;
} else {
this.percentButton.title = WebInspector.UIString("Show counts and sizes as percentages.");
this.percentButton.toggled = false;
}
},

_updateSummaryGraph: function()
{
this.countsSummaryBar.calculator.showAsPercent = this._isShowingAsPercent;
this.countsSummaryBar.update(this.profile.lowlevels);

this.sizesSummaryBar.calculator.showAsPercent = this._isShowingAsPercent;
this.sizesSummaryBar.update(this.profile.lowlevels);
}
};

WebInspector.HeapSnapshotView.prototype.__proto__ = WebInspector.View.prototype;

WebInspector.HeapSnapshotView.SearchHelper = {

operations: {
LESS: function (a, b) { return a !== null && a < b; },
LESS_OR_EQUAL: function (a, b) { return a !== null && a <= b; },
EQUAL: function (a, b) { return a !== null && a === b; },
GREATER_OR_EQUAL: function (a, b) { return a !== null && a >= b; },
GREATER: function (a, b) { return a !== null && a > b; }
},

operationParsers: {
LESS: /^<(\d+)/,
LESS_OR_EQUAL: /^<=(\d+)/,
GREATER_OR_EQUAL: /^>=(\d+)/,
GREATER: /^>(\d+)/
},

parseOperationAndNumber: function(query)
{
var operations = WebInspector.HeapSnapshotView.SearchHelper.operations;
var parsers = WebInspector.HeapSnapshotView.SearchHelper.operationParsers;
for (var operation in parsers) {
var match = query.match(parsers[operation]);
if (match !== null)
return [operations[operation], parseFloat(match[1])];
}
return [operations.EQUAL, parseFloat(query)];
},

percents: /%$/,

megaBytes: /MB$/i,

kiloBytes: /KB$/i,

bytes: /B$/i
}

WebInspector.HeapSummaryCalculator = function(lowLevelField)
{
this.total = 1;
this.lowLevelField = lowLevelField;
}

WebInspector.HeapSummaryCalculator.prototype = {
computeSummaryValues: function(lowLevels)
{
var highLevels = { data: 0, code: 0 };
this.total = 0;
for (var item in lowLevels) {
var highItem = this._highFromLow(item);
if (highItem) {
var value = lowLevels[item][this.lowLevelField];
highLevels[highItem] += value;
this.total += value;
}
}
var result = { categoryValues: highLevels };
if (!this.showAsPercent)
result.total = this.total;
return result;
},

formatValue: function(value)
{
if (this.showAsPercent)
return WebInspector.UIString("%.2f%%", value / this.total * 100.0);
else
return this._valueToString(value);
},

get showAsPercent()
{
return this._showAsPercent;
},

set showAsPercent(x)
{
this._showAsPercent = x;
}
}

WebInspector.HeapSummaryCountCalculator = function()
{
WebInspector.HeapSummaryCalculator.call(this, "count");
}

WebInspector.HeapSummaryCountCalculator.prototype = {
_highFromLow: function(type)
{
if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code";
if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/)) return "data";
return null;
},

_valueToString: function(value)
{
return value.toString();
}
}

WebInspector.HeapSummaryCountCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype;

WebInspector.HeapSummarySizeCalculator = function()
{
WebInspector.HeapSummaryCalculator.call(this, "size");
}

WebInspector.HeapSummarySizeCalculator.prototype = {
_highFromLow: function(type)
{
if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE")
return "code";
if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/) || type.match(/_ARRAY_TYPE$/))
return "data";
return null;
},

_valueToString: Number.bytesToString
}

WebInspector.HeapSummarySizeCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype;

WebInspector.HeapSnapshotDataGridNodeWithRetainers = function(owningTree)
{
this.tree = owningTree;

WebInspector.DataGridNode.call(this, null, this._hasRetainers);

this.addEventListener("populate", this._populate, this);
};

WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = {
isEmptySet: function(set)
{
for (var x in set)
return false;
return true;
},

get _hasRetainers()
{
return !this.isEmptySet(this.retainers);
},

get _parent()
{

return this.parent !== this.dataGrid ? this.parent : this.tree;
},

_populate: function(event)
{
function appendDiffEntry(baseItem, snapshotItem)
{
this.appendChild(new WebInspector.HeapSnapshotDataGridRetainerNode(this.snapshotView, baseItem, snapshotItem, this.tree));
}

this.produceDiff(this.baseRetainers, this.retainers, appendDiffEntry.bind(this));

if (this._parent) {
var currentComparator = this._parent.lastComparator;
if (currentComparator)
this.sort(currentComparator, true);
}

this.removeEventListener("populate", this._populate, this);
},

produceDiff: function(baseEntries, currentEntries, callback)
{
for (var item in currentEntries)
callback(baseEntries[item], currentEntries[item]);

for (item in baseEntries) {
if (!(item in currentEntries))
callback(baseEntries[item], null);
}
},

sort: function(comparator, force) {
if (!force && this.lastComparator === comparator)
return;

this.children.sort(comparator);
var childCount = this.children.length;
for (var childIndex = 0; childIndex < childCount; ++childIndex)
this.children[childIndex]._recalculateSiblings(childIndex);
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
if (!force && (!child.expanded || child.lastComparator === comparator))
continue;
child.sort(comparator, force);
}
this.lastComparator = comparator;
},

signForDelta: function(delta) {
if (delta === 0)
return "";
if (delta > 0)
return "+";
else
return "\u2212";  
},

showDeltaAsPercent: function(value)
{
if (value === Number.POSITIVE_INFINITY)
return WebInspector.UIString("new");
else if (value === Number.NEGATIVE_INFINITY)
return WebInspector.UIString("deleted");
if (value > 1000.0)
return WebInspector.UIString("%s >1000%%", this.signForDelta(value));
return WebInspector.UIString("%s%.2f%%", this.signForDelta(value), Math.abs(value));
},

getTotalCount: function()
{
if (!this._count) {
this._count = 0;
for (var i = 0, n = this.children.length; i < n; ++i)
this._count += this.children[i].count;
}
return this._count;
},

getTotalSize: function()
{
if (!this._size) {
this._size = 0;
for (var i = 0, n = this.children.length; i < n; ++i)
this._size += this.children[i].size;
}
return this._size;
},

get countPercent()
{
return this.count / this._parent.getTotalCount() * 100.0;
},

get sizePercent()
{
return this.size / this._parent.getTotalSize() * 100.0;
},

get countDeltaPercent()
{
if (this.baseCount > 0) {
if (this.count > 0)
return this.countDelta / this.baseCount * 100.0;
else
return Number.NEGATIVE_INFINITY;
} else
return Number.POSITIVE_INFINITY;
},

get sizeDeltaPercent()
{
if (this.baseSize > 0) {
if (this.size > 0)
return this.sizeDelta / this.baseSize * 100.0;
else
return Number.NEGATIVE_INFINITY;
} else
return Number.POSITIVE_INFINITY;
},

get data()
{
var data = {};

data["cons"] = this.constructorName;

if (this.snapshotView.showCountAsPercent)
data["count"] = WebInspector.UIString("%.2f%%", this.countPercent);
else
data["count"] = this.count;

if (this.size !== null) {
if (this.snapshotView.showSizeAsPercent)
data["size"] = WebInspector.UIString("%.2f%%", this.sizePercent);
else
data["size"] = Number.bytesToString(this.size);
} else
data["size"] = "";

if (this.snapshotView.showCountDeltaAsPercent)
data["countDelta"] = this.showDeltaAsPercent(this.countDeltaPercent);
else
data["countDelta"] = WebInspector.UIString("%s%d", this.signForDelta(this.countDelta), Math.abs(this.countDelta));

if (this.sizeDelta !== null) {
if (this.snapshotView.showSizeDeltaAsPercent)
data["sizeDelta"] = this.showDeltaAsPercent(this.sizeDeltaPercent);
else
data["sizeDelta"] = WebInspector.UIString("%s%s", this.signForDelta(this.sizeDelta), Number.bytesToString(Math.abs(this.sizeDelta)));
} else
data["sizeDelta"] = "";

return data;
},

createCell: function(columnIdentifier)
{
var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);

if ((columnIdentifier === "cons" && this._searchMatchedConsColumn) ||
(columnIdentifier === "count" && this._searchMatchedCountColumn) ||
(columnIdentifier === "size" && this._searchMatchedSizeColumn) ||
(columnIdentifier === "countDelta" && this._searchMatchedCountDeltaColumn) ||
(columnIdentifier === "sizeDelta" && this._searchMatchedSizeDeltaColumn))
cell.addStyleClass("highlight");

return cell;
}
};

WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.__proto__ = WebInspector.DataGridNode.prototype;

WebInspector.HeapSnapshotDataGridNode = function(snapshotView, baseEntry, snapshotEntry, owningTree)
{
this.snapshotView = snapshotView;

if (!snapshotEntry)
snapshotEntry = { constructorName: baseEntry.constructorName, count: 0, size: 0, retainers: {} };
this.constructorName = snapshotEntry.constructorName;
this.count = snapshotEntry.count;
this.size = snapshotEntry.size;
this.retainers = snapshotEntry.retainers;

if (!baseEntry)
baseEntry = { count: 0, size: 0, retainers: {} };
this.baseCount = baseEntry.count;
this.countDelta = this.count - this.baseCount;
this.baseSize = baseEntry.size;
this.sizeDelta = this.size - this.baseSize;
this.baseRetainers = baseEntry.retainers;

WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
};

WebInspector.HeapSnapshotDataGridNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;

WebInspector.HeapSnapshotDataGridList = function(snapshotView, baseEntries, snapshotEntries)
{
this.tree = this;
this.snapshotView = snapshotView;
this.children = [];
this.lastComparator = null;
this.populateChildren(baseEntries, snapshotEntries);
};

WebInspector.HeapSnapshotDataGridList.prototype = {
appendChild: function(child)
{
this.insertChild(child, this.children.length);
},

insertChild: function(child, index)
{
this.children.splice(index, 0, child);
},

removeChildren: function()
{
this.children = [];
},

populateChildren: function(baseEntries, snapshotEntries)
{
function appendListEntry(baseItem, snapshotItem)
{
this.appendChild(new WebInspector.HeapSnapshotDataGridNode(this.snapshotView, baseItem, snapshotItem, this));
}
this.produceDiff(baseEntries, snapshotEntries, appendListEntry.bind(this));
},

produceDiff: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.produceDiff,
sort: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.sort,
getTotalCount: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalCount,
getTotalSize: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalSize
};

WebInspector.HeapSnapshotDataGridList.propertyComparators = [{}, {}];

WebInspector.HeapSnapshotDataGridList.propertyComparator = function(property, property2, isAscending)
{
var propertyHash = property + "#" + property2;
var comparator = this.propertyComparators[(isAscending ? 1 : 0)][propertyHash];
if (!comparator) {
comparator = function(lhs, rhs) {
var l = lhs[property], r = rhs[property];
if ((l === null || r === null) && property2 !== null)
l = lhs[property2], r = rhs[property2];
var result = l < r ? -1 : (l > r ? 1 : 0);
return isAscending ? result : -result;
};
this.propertyComparators[(isAscending ? 1 : 0)][propertyHash] = comparator;
}
return comparator;
};

WebInspector.HeapSnapshotDataGridRetainerNode = function(snapshotView, baseEntry, snapshotEntry, owningTree)
{
this.snapshotView = snapshotView;

if (!snapshotEntry)
snapshotEntry = { constructorName: baseEntry.constructorName, count: 0, clusters: {} };
this.constructorName = snapshotEntry.constructorName;
this.count = snapshotEntry.count;
this.retainers = this._calculateRetainers(this.snapshotView.profile, snapshotEntry.clusters);

if (!baseEntry)
baseEntry = { count: 0, clusters: {} };
this.baseCount = baseEntry.count;
this.countDelta = this.count - this.baseCount;
this.baseRetainers = this._calculateRetainers(this.snapshotView.baseSnapshot, baseEntry.clusters);

this.size = null;
this.sizeDelta = null;

WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
}

WebInspector.HeapSnapshotDataGridRetainerNode.prototype = {
get sizePercent()
{
return null;
},

get sizeDeltaPercent()
{
return null;
},

_calculateRetainers: function(snapshot, clusters)
{
var retainers = {};
if (this.isEmptySet(clusters)) {
if (this.constructorName in snapshot.entries)
return snapshot.entries[this.constructorName].retainers;
} else {











for (var clusterName in clusters) {
if (clusterName in snapshot.clusters) {
var clusterRetainers = snapshot.clusters[clusterName].retainers;
for (var clusterRetainer in clusterRetainers) {
var clusterRetainerEntry = clusterRetainers[clusterRetainer];
if (!(clusterRetainer in retainers))
retainers[clusterRetainer] = { constructorName: clusterRetainerEntry.constructorName, count: 0, clusters: {} };
retainers[clusterRetainer].count += clusterRetainerEntry.count;
for (var clusterRetainerCluster in clusterRetainerEntry.clusters)
retainers[clusterRetainer].clusters[clusterRetainerCluster] = true;
}
}
}
}
return retainers;
}
};

WebInspector.HeapSnapshotDataGridRetainerNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;


WebInspector.HeapSnapshotProfileType = function()
{
WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.TypeId, WebInspector.UIString("HEAP SNAPSHOTS"));
}

WebInspector.HeapSnapshotProfileType.TypeId = "HEAP";

WebInspector.HeapSnapshotProfileType.prototype = {
get buttonTooltip()
{
return WebInspector.UIString("Take heap snapshot.");
},

get buttonStyle()
{
return "heap-snapshot-status-bar-item status-bar-item";
},

buttonClicked: function()
{
InspectorBackend.takeHeapSnapshot();
},

get welcomeMessage()
{
return WebInspector.UIString("Get a heap snapshot by pressing the %s button on the status bar.");
},

createSidebarTreeElementForProfile: function(profile)
{
return new WebInspector.ProfileSidebarTreeElement(profile, WebInspector.UIString("Snapshot %d"), "heap-snapshot-sidebar-tree-item");
},

createView: function(profile)
{
return new WebInspector.HeapSnapshotView(WebInspector.panels.profiles, profile);
}
}

WebInspector.HeapSnapshotProfileType.prototype.__proto__ = WebInspector.ProfileType.prototype;





WebInspector.DOMNode = function(doc, payload) {
this.ownerDocument = doc;

this.id = payload.id;
this.nodeType = payload.nodeType;
this.nodeName = payload.nodeName;
this.localName = payload.localName;
this._nodeValue = payload.nodeValue;
this.textContent = this.nodeValue;

this.attributes = [];
this._attributesMap = {};
if (payload.attributes)
this._setAttributesPayload(payload.attributes);

this._childNodeCount = payload.childNodeCount;
this.children = null;

this.nextSibling = null;
this.prevSibling = null;
this.firstChild = null;
this.lastChild = null;
this.parentNode = null;

if (payload.children)
this._setChildrenPayload(payload.children);

this._computedStyle = null;
this.style = null;
this._matchedCSSRules = [];

this.breakpoints = {};

if (this.nodeType === Node.ELEMENT_NODE) {

if (!this.ownerDocument.documentElement && this.nodeName === "HTML")
this.ownerDocument.documentElement = this;
if (!this.ownerDocument.body && this.nodeName === "BODY")
this.ownerDocument.body = this;
if (payload.documentURL)
this.documentURL = payload.documentURL;
} else if (this.nodeType === Node.DOCUMENT_TYPE_NODE) {
this.publicId = payload.publicId;
this.systemId = payload.systemId;
this.internalSubset = payload.internalSubset;
} else if (this.nodeType === Node.DOCUMENT_NODE) {
this.documentURL = payload.documentURL;
} else if (this.nodeType === Node.ATTRIBUTE_NODE) {
this.name = payload.name;
this.value = payload.value;
}
}

WebInspector.DOMNode.prototype = {
hasAttributes: function()
{
return this.attributes.length > 0;
},

hasChildNodes: function()
{
return this._childNodeCount > 0;
},

get nodeValue() {
return this._nodeValue;
},

set nodeValue(value) {
if (this.nodeType != Node.TEXT_NODE)
return;
this.ownerDocument._domAgent.setTextNodeValueAsync(this, value, function() {});
},

getAttribute: function(name)
{
var attr = this._attributesMap[name];
return attr ? attr.value : undefined;
},

setAttribute: function(name, value)
{
var self = this;
var callback = function()
{
var attr = self._attributesMap[name];
if (attr)
attr.value = value;
else
attr = self._addAttribute(name, value);
};
this.ownerDocument._domAgent.setAttributeAsync(this, name, value, callback);
},

removeAttribute: function(name)
{
var self = this;
var callback = function()
{
delete self._attributesMap[name];
for (var i = 0;  i < self.attributes.length; ++i) {
if (self.attributes[i].name == name) {
self.attributes.splice(i, 1);
break;
}
}
};
this.ownerDocument._domAgent.removeAttributeAsync(this, name, callback);
},

path: function()
{
var path = [];
var node = this;
while (node && "index" in node && node.nodeName.length) {
path.push([node.index, node.nodeName]);
node = node.parentNode;
}
path.reverse();
return path.join(",");
},

_setAttributesPayload: function(attrs)
{
this.attributes = [];
this._attributesMap = {};
for (var i = 0; i < attrs.length; i += 2)
this._addAttribute(attrs[i], attrs[i + 1]);
},

_insertChild: function(prev, payload)
{
var node = new WebInspector.DOMNode(this.ownerDocument, payload);
if (!prev) {
if (!this.children) {

this.children = [ node ];
} else
this.children.unshift(node);
} else
this.children.splice(this.children.indexOf(prev) + 1, 0, node);
this._renumber();
return node;
},

removeChild_: function(node)
{
this.children.splice(this.children.indexOf(node), 1);
node.parentNode = null;
this._renumber();
},

_setChildrenPayload: function(payloads)
{
this.children = [];
for (var i = 0; i < payloads.length; ++i) {
var payload = payloads[i];
var node = new WebInspector.DOMNode(this.ownerDocument, payload);
this.children.push(node);
}
this._renumber();
},

_renumber: function()
{
this._childNodeCount = this.children.length;
if (this._childNodeCount == 0) {
this.firstChild = null;
this.lastChild = null;
return;
}
this.firstChild = this.children[0];
this.lastChild = this.children[this._childNodeCount - 1];
for (var i = 0; i < this._childNodeCount; ++i) {
var child = this.children[i];
child.index = i;
child.nextSibling = i + 1 < this._childNodeCount ? this.children[i + 1] : null;
child.prevSibling = i - 1 >= 0 ? this.children[i - 1] : null;
child.parentNode = this;
}
},

_addAttribute: function(name, value)
{
var attr = {
"name": name,
"value": value,
"_node": this
};
this._attributesMap[name] = attr;
this.attributes.push(attr);
}
}

WebInspector.DOMDocument = function(domAgent, defaultView, payload)
{
WebInspector.DOMNode.call(this, this, payload);
this._listeners = {};
this._domAgent = domAgent;
this.defaultView = defaultView;
}

WebInspector.DOMDocument.prototype = {

addEventListener: function(name, callback)
{
var listeners = this._listeners[name];
if (!listeners) {
listeners = [];
this._listeners[name] = listeners;
}
listeners.push(callback);
},

removeEventListener: function(name, callback)
{
var listeners = this._listeners[name];
if (!listeners)
return;

var index = listeners.indexOf(callback);
if (index != -1)
listeners.splice(index, 1);
},

_fireDomEvent: function(name, event)
{
var listeners = this._listeners[name];
if (!listeners)
return;

for (var i = 0; i < listeners.length; ++i) {
var listener = listeners[i];
listener.call(this, event);
}
}
}

WebInspector.DOMDocument.prototype.__proto__ = WebInspector.DOMNode.prototype;


WebInspector.DOMWindow = function(domAgent)
{
this._domAgent = domAgent;
}

WebInspector.DOMWindow.prototype = {
get document()
{
return this._domAgent.document;
},

get Node()
{
return WebInspector.DOMNode;
},

get Element()
{
return WebInspector.DOMNode;
},

Object: function()
{
}
}

WebInspector.DOMAgent = function() {
this._window = new WebInspector.DOMWindow(this);
this._idToDOMNode = null;
this.document = null;
}

WebInspector.DOMAgent.prototype = {
get domWindow()
{
return this._window;
},

getChildNodesAsync: function(parent, callback)
{
var children = parent.children;
if (children) {
callback(children);
return;
}
function mycallback() {
callback(parent.children);
}
InspectorBackend.getChildNodes(parent.id, mycallback);
},

setAttributeAsync: function(node, name, value, callback)
{
var mycallback = this._didApplyDomChange.bind(this, node, callback);
InspectorBackend.setAttribute(node.id, name, value, mycallback);
},

removeAttributeAsync: function(node, name, callback)
{
var mycallback = this._didApplyDomChange.bind(this, node, callback);
InspectorBackend.removeAttribute(node.id, name, mycallback);
},

setTextNodeValueAsync: function(node, text, callback)
{
var mycallback = this._didApplyDomChange.bind(this, node, callback);
InspectorBackend.setTextNodeValue(node.id, text, mycallback);
},

_didApplyDomChange: function(node, callback, success)
{
if (!success)
return;
callback();

var elem = WebInspector.panels.elements.treeOutline.findTreeElement(node);
if (elem)
elem.updateTitle();
},

_attributesUpdated: function(nodeId, attrsArray)
{
var node = this._idToDOMNode[nodeId];
node._setAttributesPayload(attrsArray);
var event = {target: node};
this.document._fireDomEvent("DOMAttrModified", event);
},

_characterDataModified: function(nodeId, newValue)
{
var node = this._idToDOMNode[nodeId];
node._nodeValue = newValue;
node.textContent = newValue;
var event = { target : node };
this.document._fireDomEvent("DOMCharacterDataModified", event);
},

nodeForId: function(nodeId)
{
return this._idToDOMNode[nodeId];
},

_setDocument: function(payload)
{
this._idToDOMNode = {};
if (payload && "id" in payload) {
this.document = new WebInspector.DOMDocument(this, this._window, payload);
this._idToDOMNode[payload.id] = this.document;
this._bindNodes(this.document.children);
WebInspector.breakpointManager.restoreDOMBreakpoints();
} else
this.document = null;
WebInspector.panels.elements.setDocument(this.document);
},

_setDetachedRoot: function(payload)
{
var root = new WebInspector.DOMNode(this.document, payload);
this._idToDOMNode[payload.id] = root;
},

_setChildNodes: function(parentId, payloads)
{
var parent = this._idToDOMNode[parentId];
parent._setChildrenPayload(payloads);
this._bindNodes(parent.children);
},

_bindNodes: function(children)
{
for (var i = 0; i < children.length; ++i) {
var child = children[i];
this._idToDOMNode[child.id] = child;
if (child.children)
this._bindNodes(child.children);
}
},

_childNodeCountUpdated: function(nodeId, newValue)
{
var node = this._idToDOMNode[nodeId];
node._childNodeCount = newValue;
var outline = WebInspector.panels.elements.treeOutline;
var treeElement = outline.findTreeElement(node);
if (treeElement)
treeElement.hasChildren = newValue;
},

_childNodeInserted: function(parentId, prevId, payload)
{
var parent = this._idToDOMNode[parentId];
var prev = this._idToDOMNode[prevId];
var node = parent._insertChild(prev, payload);
this._idToDOMNode[node.id] = node;
var event = { target : node, relatedNode : parent };
this.document._fireDomEvent("DOMNodeInserted", event);
},

_childNodeRemoved: function(parentId, nodeId)
{
var parent = this._idToDOMNode[parentId];
var node = this._idToDOMNode[nodeId];
parent.removeChild_(node);
var event = { target : node, relatedNode : parent };
this.document._fireDomEvent("DOMNodeRemoved", event);
delete this._idToDOMNode[nodeId];
this._removeBreakpoints(node);
},

_removeBreakpoints: function(node)
{
for (var type in node.breakpoints)
node.breakpoints[type].remove();
if (!node.children)
return;
for (var i = 0; i < node.children.length; ++i)
this._removeBreakpoints(node.children[i]);
}
}

WebInspector.ApplicationCache = {}

WebInspector.ApplicationCache.getApplicationCachesAsync = function(callback)
{
function mycallback(applicationCaches)
{

if (applicationCaches)
callback(applicationCaches);
}

InspectorBackend.getApplicationCaches(mycallback);
}

WebInspector.Cookies = {}

WebInspector.Cookies.getCookiesAsync = function(callback)
{
function mycallback(cookies, cookiesString)
{
if (cookiesString)
callback(WebInspector.Cookies.buildCookiesFromString(cookiesString), false);
else
callback(cookies, true);
}

InspectorBackend.getCookies(mycallback);
}

WebInspector.Cookies.buildCookiesFromString = function(rawCookieString)
{
var rawCookies = rawCookieString.split(/;\s*/);
var cookies = [];

if (!(/^\s*$/.test(rawCookieString))) {
for (var i = 0; i < rawCookies.length; ++i) {
var cookie = rawCookies[i];
var delimIndex = cookie.indexOf("=");
var name = cookie.substring(0, delimIndex);
var value = cookie.substring(delimIndex + 1);
var size = name.length + value.length;
cookies.push({ name: name, value: value, size: size });
}
}

return cookies;
}

WebInspector.Cookies.cookieMatchesResourceURL = function(cookie, resourceURL)
{
var url = resourceURL.asParsedURL();
if (!url || !this.cookieDomainMatchesResourceDomain(cookie.domain, url.host))
return false;
return (url.path.indexOf(cookie.path) === 0
&& (!cookie.port || url.port == cookie.port)
&& (!cookie.secure || url.scheme === "https"));
}

WebInspector.Cookies.cookieDomainMatchesResourceDomain = function(cookieDomain, resourceDomain)
{
if (cookieDomain.charAt(0) !== '.')
return resourceDomain === cookieDomain;
return !!resourceDomain.match(new RegExp("^([^\\.]+\\.)?" + cookieDomain.substring(1).escapeForRegExp() + "$"), "i");
}

WebInspector.EventListeners = {}

WebInspector.EventListeners.getEventListenersForNodeAsync = function(node, callback)
{
if (!node)
return;
InspectorBackend.getEventListenersForNode(node.id, callback);
}

WebInspector.attributesUpdated = function()
{
this.domAgent._attributesUpdated.apply(this.domAgent, arguments);
}

WebInspector.characterDataModified = function()
{
this.domAgent._characterDataModified.apply(this.domAgent, arguments);
}

WebInspector.setDocument = function()
{
this.domAgent._setDocument.apply(this.domAgent, arguments);
}

WebInspector.setDetachedRoot = function()
{
this.domAgent._setDetachedRoot.apply(this.domAgent, arguments);
}

WebInspector.setChildNodes = function()
{
this.domAgent._setChildNodes.apply(this.domAgent, arguments);
}

WebInspector.childNodeCountUpdated = function()
{
this.domAgent._childNodeCountUpdated.apply(this.domAgent, arguments);
}

WebInspector.childNodeInserted = function()
{
this.domAgent._childNodeInserted.apply(this.domAgent, arguments);
}

WebInspector.childNodeRemoved = function()
{
this.domAgent._childNodeRemoved.apply(this.domAgent, arguments);
}





var injectedScriptConstructor = (function (InjectedScriptHost, inspectedWindow, injectedScriptId) {

var InjectedScript = function()
{
this._lastBoundObjectId = 1;
this._idToWrappedObject = {};
this._objectGroups = {};
}

InjectedScript.prototype = {
wrapObjectForConsole: function(object, canAccessInspectedWindow)
{
if (canAccessInspectedWindow)
return this._wrapObject(object, "console");
var result = {};
result.type = typeof object;
result.description = this._toString(object);
return result;
},

_wrapObject: function(object, objectGroupName, abbreviate)
{
try {
var objectId;
if (typeof object === "object" || typeof object === "function" || this._isHTMLAllCollection(object)) {
var id = this._lastBoundObjectId++;
this._idToWrappedObject[id] = object;

var group = this._objectGroups[objectGroupName];
if (!group) {
group = [];
this._objectGroups[objectGroupName] = group;
}
group.push(id);
objectId = this._serializeObjectId(id, objectGroupName);
}
return InjectedScript.RemoteObject.fromObject(object, objectId, abbreviate);
} catch (e) {
return InjectedScript.RemoteObject.fromObject("[ Exception: " + e.toString() + " ]");
}
},

_serializeObjectId: function(id, groupName)
{
return injectedScriptId + ":" + id + ":" + groupName;
},

_parseObjectId: function(objectId)
{
var tokens = objectId.split(":");
var parsedObjectId = {};
parsedObjectId.id = parseInt(tokens[1]);
parsedObjectId.groupName = tokens[2];
return parsedObjectId;
},

releaseWrapperObjectGroup: function(objectGroupName)
{
var group = this._objectGroups[objectGroupName];
if (!group)
return;
for (var i = 0; i < group.length; i++)
delete this._idToWrappedObject[group[i]];
delete this._objectGroups[objectGroupName];
},

dispatch: function(methodName, args)
{
var argsArray = eval("(" + args + ")");
var result = this[methodName].apply(this, argsArray);
if (typeof result === "undefined") {
inspectedWindow.console.error("Web Inspector error: InjectedScript.%s returns undefined", methodName);
result = null;
}
return result;
},

getPrototypes: function(nodeId)
{
this.releaseWrapperObjectGroup("prototypes");
var node = this._nodeForId(nodeId);
if (!node)
return false;

var result = [];
var prototype = node;
do {
result.push(this._wrapObject(prototype, "prototypes"));
prototype = prototype.__proto__;
} while (prototype)
return result;
},

getProperties: function(objectId, ignoreHasOwnProperty, abbreviate)
{
var parsedObjectId = this._parseObjectId(objectId);
var object = this._objectForId(parsedObjectId);
if (!this._isDefined(object))
return false;
var properties = [];

var propertyNames = ignoreHasOwnProperty ? this._getPropertyNames(object) : Object.getOwnPropertyNames(object);
if (!ignoreHasOwnProperty && object.__proto__)
propertyNames.push("__proto__");


for (var i = 0; i < propertyNames.length; ++i) {
var propertyName = propertyNames[i];

var property = {};
property.name = propertyName + "";
var isGetter = object["__lookupGetter__"] && object.__lookupGetter__(propertyName);
if (!isGetter) {
try {
property.value = this._wrapObject(object[propertyName], parsedObjectId.groupName, abbreviate);
} catch(e) {
property.value = new InjectedScript.RemoteObject.fromException(e);
}
} else {

property.value = new InjectedScript.RemoteObject.fromObject("\u2014"); 
property.isGetter = true;
}
properties.push(property);
}
return properties;
},

setPropertyValue: function(objectId, propertyName, expression)
{
var parsedObjectId = this._parseObjectId(objectId);
var object = this._objectForId(parsedObjectId);
if (!this._isDefined(object))
return false;

var expressionLength = expression.length;
if (!expressionLength) {
delete object[propertyName];
return !(propertyName in object);
}

try {






var result = inspectedWindow.eval("(" + expression + ")");

object[propertyName] = result;
return true;
} catch(e) {
try {
var result = inspectedWindow.eval("\"" + expression.replace(/"/g, "\\\"") + "\"");
object[propertyName] = result;
return true;
} catch(e) {
return false;
}
}
},

_populatePropertyNames: function(object, resultSet)
{
for (var o = object; o; o = o.__proto__) {
try {
var names = Object.getOwnPropertyNames(o);
for (var i = 0; i < names.length; ++i)
resultSet[names[i]] = true;
} catch (e) {
}
}
},

_getPropertyNames: function(object, resultSet)
{
var propertyNameSet = {};
this._populatePropertyNames(object, propertyNameSet);
return Object.keys(propertyNameSet);
},

getCompletions: function(expression, includeInspectorCommandLineAPI, callFrameId)
{
var props = {};
try {
var expressionResult;

if (typeof callFrameId === "number") {
var callFrame = this._callFrameForId(callFrameId);
if (!callFrame)
return props;
if (expression)
expressionResult = this._evaluateOn(callFrame.evaluate, callFrame, expression, true);
else {

var scopeChain = callFrame.scopeChain;
for (var i = 0; i < scopeChain.length; ++i)
this._populatePropertyNames(scopeChain[i], props);
}
} else {
if (!expression)
expression = "this";
expressionResult = this._evaluateOn(inspectedWindow.eval, inspectedWindow, expression, false);
}
if (typeof expressionResult === "object")
this._populatePropertyNames(expressionResult, props);

if (includeInspectorCommandLineAPI) {
for (var prop in this._commandLineAPI)
props[prop] = true;
}
} catch(e) {
}
return props;
},

evaluate: function(expression, objectGroup)
{
return this._evaluateAndWrap(inspectedWindow.eval, inspectedWindow, expression, objectGroup, false);
},

_evaluateAndWrap: function(evalFunction, object, expression, objectGroup, isEvalOnCallFrame)
{
try {
return this._wrapObject(this._evaluateOn(evalFunction, object, expression, isEvalOnCallFrame), objectGroup);
} catch (e) {
return InjectedScript.RemoteObject.fromException(e);
}
},

_evaluateOn: function(evalFunction, object, expression, isEvalOnCallFrame)
{



inspectedWindow.console._commandLineAPI = this._commandLineAPI;


if (!isEvalOnCallFrame)
expression = "with (window) {\n" + expression + "\n} ";
expression = "with (window ? window.console._commandLineAPI : {}) {\n" + expression + "\n}";
var value = evalFunction.call(object, expression);

delete inspectedWindow.console._commandLineAPI;


if (this._type(value) === "error")
throw value.toString();

return value;
},

getNodeId: function(node)
{
return InjectedScriptHost.pushNodePathToFrontend(node, false, false);
},

callFrames: function()
{
var callFrame = InjectedScriptHost.currentCallFrame();
if (!callFrame)
return false;

injectedScript.releaseWrapperObjectGroup("backtrace");
var result = [];
var depth = 0;
do {
result.push(new InjectedScript.CallFrameProxy(depth++, callFrame));
callFrame = callFrame.caller;
} while (callFrame);
return result;
},

evaluateInCallFrame: function(callFrameId, code, objectGroup)
{
var callFrame = this._callFrameForId(callFrameId);
if (!callFrame)
return false;
return this._evaluateAndWrap(callFrame.evaluate, callFrame, code, objectGroup, true);
},

_callFrameForId: function(id)
{
var callFrame = InjectedScriptHost.currentCallFrame();
while (--id >= 0 && callFrame)
callFrame = callFrame.caller;
return callFrame;
},

_nodeForId: function(nodeId)
{
if (!nodeId)
return null;
return InjectedScriptHost.nodeForId(nodeId);
},

_objectForId: function(parsedObjectId)
{
return this._idToWrappedObject[parsedObjectId.id];
},

resolveNode: function(nodeId)
{
var node = this._nodeForId(nodeId);
if (!node)
return false;

return this._wrapObject(node, "prototype");
},

getNodeProperties: function(nodeId, properties)
{
var node = this._nodeForId(nodeId);
if (!node)
return false;
var result = {};
for (var i = 0; i < properties.length; ++i)
result[properties[i]] = node[properties[i]];
return result;
},

pushNodeToFrontend: function(objectId)
{
var parsedObjectId = this._parseObjectId(objectId);
var object = this._objectForId(parsedObjectId);
if (!object || this._type(object) !== "node")
return false;
return InjectedScriptHost.pushNodePathToFrontend(object, false, false);
},

evaluateOnSelf: function(funcBody, args)
{
var func = window.eval("(" + funcBody + ")");
return func.apply(this, args || []);
},

_isDefined: function(object)
{
return object || this._isHTMLAllCollection(object);
},

_isHTMLAllCollection: function(object)
{

return (typeof object === "undefined") && inspectedWindow.HTMLAllCollection && object instanceof inspectedWindow.HTMLAllCollection;
},

_type: function(obj)
{
if (obj === null)
return "null";

var type = typeof obj;
if (type !== "object" && type !== "function") {

if (this._isHTMLAllCollection(obj))
return "array";
return type;
}



if (!inspectedWindow.document)
return type;

if (obj instanceof inspectedWindow.Node)
return (obj.nodeType === undefined ? type : "node");
if (obj instanceof inspectedWindow.String)
return "string";
if (obj instanceof inspectedWindow.Array)
return "array";
if (obj instanceof inspectedWindow.Boolean)
return "boolean";
if (obj instanceof inspectedWindow.Number)
return "number";
if (obj instanceof inspectedWindow.Date)
return "date";
if (obj instanceof inspectedWindow.RegExp)
return "regexp";

if (isFinite(obj.length) && typeof obj.splice === "function")
return "array";
if (isFinite(obj.length) && typeof obj.callee === "function") 
return "array";
if (obj instanceof inspectedWindow.NodeList)
return "array";
if (obj instanceof inspectedWindow.HTMLCollection)
return "array";
if (obj instanceof inspectedWindow.Error)
return "error";
return type;
},

_describe: function(obj, abbreviated)
{
var type = this._type(obj);

switch (type) {
case "object":
case "node":
var result = InjectedScriptHost.internalConstructorName(obj);
if (result === "Object") {


var constructorName = obj.constructor && obj.constructor.name;
if (constructorName)
return constructorName;
}
return result;
case "array":
var className = InjectedScriptHost.internalConstructorName(obj);
if (typeof obj.length === "number")
className += "[" + obj.length + "]";
return className;
case "string":
if (!abbreviated)
return obj;
if (obj.length > 100)
return "\"" + obj.substring(0, 100) + "\u2026\"";
return "\"" + obj + "\"";
case "function":
var objectText = this._toString(obj);
if (abbreviated)
objectText = /.*/.exec(objectText)[0].replace(/ +$/g, "");
return objectText;
default:
return this._toString(obj);
}
},

_toString: function(obj)
{

return "" + obj;
},

_logEvent: function(event)
{
console.log(event.type, event);
},

_normalizeEventTypes: function(types)
{
if (typeof types === "undefined")
types = [ "mouse", "key", "load", "unload", "abort", "error", "select", "change", "submit", "reset", "focus", "blur", "resize", "scroll" ];
else if (typeof types === "string")
types = [ types ];

var result = [];
for (var i = 0; i < types.length; i++) {
if (types[i] === "mouse")
result.splice(0, 0, "mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout");
else if (types[i] === "key")
result.splice(0, 0, "keydown", "keyup", "keypress");
else
result.push(types[i]);
}
return result;
},

_inspectedNode: function(num)
{
var nodeId = InjectedScriptHost.inspectedNode(num);
return this._nodeForId(nodeId);
},

_bindToScript: function(func)
{
var args = Array.prototype.slice.call(arguments, 1);
function bound()
{
return func.apply(injectedScript, args.concat(Array.prototype.slice.call(arguments)));
}
bound.toString = function() {
return "bound: " + func;
};
return bound;
}
}

var injectedScript = new InjectedScript();

InjectedScript.RemoteObject = function(objectId, type, description, hasChildren)
{
this.objectId = objectId;
this.type = type;
this.description = description;
this.hasChildren = hasChildren;
}

InjectedScript.RemoteObject.fromException = function(e)
{
return new InjectedScript.RemoteObject(null, "error", e.toString());
}

InjectedScript.RemoteObject.fromObject = function(object, objectId, abbreviate)
{
var type = injectedScript._type(object);
var rawType = typeof object;
var hasChildren = (rawType === "object" && object !== null && (Object.getOwnPropertyNames(object).length || !!object.__proto__)) || rawType === "function";
var description = "";
try {
var description = injectedScript._describe(object, abbreviate);
return new InjectedScript.RemoteObject(objectId, type, description, hasChildren);
} catch (e) {
return InjectedScript.RemoteObject.fromException(e);
}
}

InjectedScript.CallFrameProxy = function(id, callFrame)
{
this.id = id;
this.type = callFrame.type;
this.functionName = (this.type === "function" ? callFrame.functionName : "");
this.sourceID = callFrame.sourceID;
this.line = callFrame.line;
this.scopeChain = this._wrapScopeChain(callFrame);
this.worldId = injectedScriptId;
}

InjectedScript.CallFrameProxy.prototype = {
_wrapScopeChain: function(callFrame)
{
const GLOBAL_SCOPE = 0;
const LOCAL_SCOPE = 1;
const WITH_SCOPE = 2;
const CLOSURE_SCOPE = 3;
const CATCH_SCOPE = 4;

var scopeChain = callFrame.scopeChain;
var scopeChainProxy = [];
var foundLocalScope = false;
for (var i = 0; i < scopeChain.length; i++) {
var scopeType = callFrame.scopeType(i);
var scopeObject = scopeChain[i];
var scopeObjectProxy = injectedScript._wrapObject(scopeObject, "backtrace", true);

switch(scopeType) {
case LOCAL_SCOPE: {
foundLocalScope = true;
scopeObjectProxy.isLocal = true;
scopeObjectProxy.thisObject = injectedScript._wrapObject(callFrame.thisObject, "backtrace", true);
break;
}
case CLOSURE_SCOPE: {
scopeObjectProxy.isClosure = true;
break;
}
case WITH_SCOPE:
case CATCH_SCOPE: {
if (foundLocalScope && scopeObject instanceof inspectedWindow.Element)
scopeObjectProxy.isElement = true;
else if (foundLocalScope && scopeObject instanceof inspectedWindow.Document)
scopeObjectProxy.isDocument = true;
else
scopeObjectProxy.isWithBlock = true;
break;
}
}
scopeChainProxy.push(scopeObjectProxy);
}
return scopeChainProxy;
}
}

function CommandLineAPI()
{
for (var i = 0; i < 5; ++i)
this.__defineGetter__("$" + i, injectedScript._bindToScript(injectedScript._inspectedNode, i));
}

CommandLineAPI.prototype = {


$: function()
{
return document.getElementById.apply(document, arguments)
},

$$: function()
{
return document.querySelectorAll.apply(document, arguments)
},

$x: function(xpath, context)
{
var nodes = [];
try {
var doc = context || document;
var results = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
var node;
while (node = results.iterateNext())
nodes.push(node);
} catch (e) {
}
return nodes;
},

dir: function()
{
return console.dir.apply(console, arguments)
},

dirxml: function()
{
return console.dirxml.apply(console, arguments)
},

keys: function(object)
{
return Object.keys(object);
},

values: function(object)
{
var result = [];
for (var key in object)
result.push(object[key]);
return result;
},

profile: function()
{
return console.profile.apply(console, arguments)
},

profileEnd: function()
{
return console.profileEnd.apply(console, arguments)
},

monitorEvents: function(object, types)
{
if (!object || !object.addEventListener || !object.removeEventListener)
return;
types = injectedScript._normalizeEventTypes(types);
for (var i = 0; i < types.length; ++i) {
object.removeEventListener(types[i], injectedScript._logEvent, false);
object.addEventListener(types[i], injectedScript._logEvent, false);
}
},

unmonitorEvents: function(object, types)
{
if (!object || !object.addEventListener || !object.removeEventListener)
return;
types = injectedScript._normalizeEventTypes(types);
for (var i = 0; i < types.length; ++i)
object.removeEventListener(types[i], injectedScript._logEvent, false);
},

inspect: function(object)
{
if (arguments.length === 0)
return;

inspectedWindow.console.log(object);
if (injectedScript._type(object) === "node")
InjectedScriptHost.pushNodePathToFrontend(object, false, true);
else {
switch (injectedScript._describe(object)) {
case "Database":
InjectedScriptHost.selectDatabase(object);
break;
case "Storage":
InjectedScriptHost.selectDOMStorage(object);
break;
}
}
},

copy: function(object)
{
if (injectedScript._type(object) === "node")
object = object.outerHTML;
InjectedScriptHost.copyText(object);
},

clear: function()
{
InjectedScriptHost.clearConsoleMessages();
}
}

injectedScript._commandLineAPI = new CommandLineAPI();
return injectedScript;
});





function InjectedScriptAccess(worldId) {
this._worldId = worldId;
}

InjectedScriptAccess.get = function(worldId)
{
if (typeof worldId === "number")
return new InjectedScriptAccess(worldId);

console.assert(false, "Access to injected script with no id");
}

InjectedScriptAccess.getForNode = function(node)
{

return InjectedScriptAccess.get(-node.id);
}

InjectedScriptAccess.getForObjectId = function(objectId)
{

var tokens = objectId.split(":");
return InjectedScriptAccess.get(parseInt(tokens[0]));
}

InjectedScriptAccess.getDefault = function()
{
return InjectedScriptAccess.get(0);
}

InjectedScriptAccess.prototype = {};

InjectedScriptAccess._installHandler = function(methodName, async)
{
InjectedScriptAccess.prototype[methodName] = function()
{
var allArgs = Array.prototype.slice.call(arguments);
var callback = allArgs[allArgs.length - 1];
var argsString = JSON.stringify(Array.prototype.slice.call(allArgs, 0, allArgs.length - 1));

function myCallback(result, isException)
{
if (!isException)
callback(result);
else
WebInspector.console.addMessage(WebInspector.ConsoleMessage.createTextMessage("Error dispatching: " + methodName));
}
InspectorBackend.dispatchOnInjectedScript(this._worldId, methodName, argsString, myCallback);
};
}





InjectedScriptAccess._installHandler("evaluate");
InjectedScriptAccess._installHandler("evaluateInCallFrame");
InjectedScriptAccess._installHandler("evaluateOnSelf");
InjectedScriptAccess._installHandler("getCompletions");
InjectedScriptAccess._installHandler("getProperties");
InjectedScriptAccess._installHandler("getPrototypes");
InjectedScriptAccess._installHandler("pushNodeToFrontend");
InjectedScriptAccess._installHandler("resolveNode");
InjectedScriptAccess._installHandler("getNodeProperties");
InjectedScriptAccess._installHandler("setPropertyValue");





WebInspector.TimelineAgent = function() {

}


WebInspector.TimelineAgent.RecordType = {
EventDispatch : 0,
Layout : 1,
RecalculateStyles : 2,
Paint : 3,
ParseHTML : 4,
TimerInstall : 5,
TimerRemove : 6,
TimerFire : 7,
XHRReadyStateChange : 8,
XHRLoad : 9,
EvaluateScript : 10,
MarkTimeline : 11,
ResourceSendRequest : 12,
ResourceReceiveResponse : 13,
ResourceFinish : 14,
FunctionCall : 15,
ResourceReceiveData: 16,
GCEvent : 17,
MarkDOMContentEventType : 18,
MarkLoadEventType : 19,
ScheduleResourceRequest : 20
};

WebInspector.addRecordToTimeline = function(record) {
if (WebInspector.panels.timeline)
WebInspector.panels.timeline.addRecordToTimeline(record);
}

WebInspector.timelineProfilerWasStarted = function() {
if (WebInspector.panels.timeline)
WebInspector.panels.timeline.timelineWasStarted();
}

WebInspector.timelineProfilerWasStopped = function() {
if (WebInspector.panels.timeline)
WebInspector.panels.timeline.timelineWasStopped();
}





WebInspector.TimelinePanel = function()
{
WebInspector.Panel.call(this, "timeline");

this.element.appendChild(this._createTopPane());
this.element.tabIndex = 0;

this._sidebarBackgroundElement = document.createElement("div");
this._sidebarBackgroundElement.className = "sidebar timeline-sidebar-background";
this.element.appendChild(this._sidebarBackgroundElement);

this._containerElement = document.createElement("div");
this._containerElement.id = "timeline-container";
this._containerElement.addEventListener("scroll", this._onScroll.bind(this), false);
this.element.appendChild(this._containerElement);

this.createSidebar(this._containerElement, this._containerElement);
var itemsTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("RECORDS"), {}, true);
itemsTreeElement.expanded = true;
this.sidebarTree.appendChild(itemsTreeElement);

this._sidebarListElement = document.createElement("div");
this.sidebarElement.appendChild(this._sidebarListElement);

this._containerContentElement = document.createElement("div");
this._containerContentElement.id = "resources-container-content";
this._containerElement.appendChild(this._containerContentElement);

this._timelineGrid = new WebInspector.TimelineGrid();
this._itemsGraphsElement = this._timelineGrid.itemsGraphsElement;
this._itemsGraphsElement.id = "timeline-graphs";
this._containerContentElement.appendChild(this._timelineGrid.element);

this._topGapElement = document.createElement("div");
this._topGapElement.className = "timeline-gap";
this._itemsGraphsElement.appendChild(this._topGapElement);

this._graphRowsElement = document.createElement("div");
this._itemsGraphsElement.appendChild(this._graphRowsElement);

this._bottomGapElement = document.createElement("div");
this._bottomGapElement.className = "timeline-gap";
this._itemsGraphsElement.appendChild(this._bottomGapElement);

this._expandElements = document.createElement("div");
this._expandElements.id = "orphan-expand-elements";
this._itemsGraphsElement.appendChild(this._expandElements);

this._rootRecord = this._createRootRecord();
this._sendRequestRecords = {};
this._scheduledResourceRequests = {};
this._timerRecords = {};

this._calculator = new WebInspector.TimelineCalculator();
this._calculator._showShortEvents = false;
var shortRecordThresholdTitle = Number.secondsToString(WebInspector.TimelinePanel.shortRecordThreshold, WebInspector.UIString);
this._showShortRecordsTitleText = WebInspector.UIString("Show the records that are shorter than %s", shortRecordThresholdTitle);
this._hideShortRecordsTitleText = WebInspector.UIString("Hide the records that are shorter than %s", shortRecordThresholdTitle);
this._createStatusbarButtons();

this._boundariesAreValid = true;
this._scrollTop = 0;

this._popoverHelper = new WebInspector.PopoverHelper(this._containerElement, this._getPopoverAnchor.bind(this), this._showPopover.bind(this), true);


this.toggleFilterButton.toggled = true;
this._calculator._showShortEvents = this.toggleFilterButton.toggled;
this._markTimelineRecords = [];
this._expandOffset = 15;
}


WebInspector.TimelinePanel.rowHeight = 18;
WebInspector.TimelinePanel.shortRecordThreshold = 0.015;

WebInspector.TimelinePanel.prototype = {
_createTopPane: function() {
var topPaneElement = document.createElement("div");
topPaneElement.id = "timeline-overview-panel";

this._topPaneSidebarElement = document.createElement("div");
this._topPaneSidebarElement.id = "timeline-overview-sidebar";

var overviewTreeElement = document.createElement("ol");
overviewTreeElement.className = "sidebar-tree";
this._topPaneSidebarElement.appendChild(overviewTreeElement);
topPaneElement.appendChild(this._topPaneSidebarElement);

var topPaneSidebarTree = new TreeOutline(overviewTreeElement);
var timelinesOverviewItem = new WebInspector.SidebarTreeElement("resources-time-graph-sidebar-item", WebInspector.UIString("Timelines"));
topPaneSidebarTree.appendChild(timelinesOverviewItem);
timelinesOverviewItem.onselect = this._timelinesOverviewItemSelected.bind(this);
timelinesOverviewItem.select(true);

var memoryOverviewItem = new WebInspector.SidebarTreeElement("resources-size-graph-sidebar-item", WebInspector.UIString("Memory"));
topPaneSidebarTree.appendChild(memoryOverviewItem);
memoryOverviewItem.onselect = this._memoryOverviewItemSelected.bind(this);

this._overviewPane = new WebInspector.TimelineOverviewPane(this.categories);
this._overviewPane.addEventListener("window changed", this._windowChanged, this);
this._overviewPane.addEventListener("filter changed", this._refresh, this);
topPaneElement.appendChild(this._overviewPane.element);

var separatorElement = document.createElement("div");
separatorElement.id = "timeline-overview-separator";
topPaneElement.appendChild(separatorElement);
return topPaneElement;
},

get toolbarItemLabel()
{
return WebInspector.UIString("Timeline");
},

get statusBarItems()
{
return [this.toggleFilterButton.element, this.toggleTimelineButton.element, this.clearButton.element, this._overviewPane.statusBarFilters];
},

get categories()
{
if (!this._categories) {
this._categories = {
loading: new WebInspector.TimelineCategory("loading", WebInspector.UIString("Loading"), "rgb(47,102,236)"),
scripting: new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), "rgb(157,231,119)"),
rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), "rgb(164,60,255)")
};
}
return this._categories;
},

get defaultFocusedElement()
{
return this.element;
},

get _recordStyles()
{
if (!this._recordStylesArray) {
var recordTypes = WebInspector.TimelineAgent.RecordType;
var recordStyles = {};
recordStyles[recordTypes.EventDispatch] = { title: WebInspector.UIString("Event"), category: this.categories.scripting };
recordStyles[recordTypes.Layout] = { title: WebInspector.UIString("Layout"), category: this.categories.rendering };
recordStyles[recordTypes.RecalculateStyles] = { title: WebInspector.UIString("Recalculate Style"), category: this.categories.rendering };
recordStyles[recordTypes.Paint] = { title: WebInspector.UIString("Paint"), category: this.categories.rendering };
recordStyles[recordTypes.ParseHTML] = { title: WebInspector.UIString("Parse"), category: this.categories.loading };
recordStyles[recordTypes.TimerInstall] = { title: WebInspector.UIString("Install Timer"), category: this.categories.scripting };
recordStyles[recordTypes.TimerRemove] = { title: WebInspector.UIString("Remove Timer"), category: this.categories.scripting };
recordStyles[recordTypes.TimerFire] = { title: WebInspector.UIString("Timer Fired"), category: this.categories.scripting };
recordStyles[recordTypes.XHRReadyStateChange] = { title: WebInspector.UIString("XHR Ready State Change"), category: this.categories.scripting };
recordStyles[recordTypes.XHRLoad] = { title: WebInspector.UIString("XHR Load"), category: this.categories.scripting };
recordStyles[recordTypes.EvaluateScript] = { title: WebInspector.UIString("Evaluate Script"), category: this.categories.scripting };
recordStyles[recordTypes.MarkTimeline] = { title: WebInspector.UIString("Mark"), category: this.categories.scripting };
recordStyles[recordTypes.ResourceSendRequest] = { title: WebInspector.UIString("Send Request"), category: this.categories.loading };
recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UIString("Receive Response"), category: this.categories.loading };
recordStyles[recordTypes.ResourceFinish] = { title: WebInspector.UIString("Finish Loading"), category: this.categories.loading };
recordStyles[recordTypes.FunctionCall] = { title: WebInspector.UIString("Function Call"), category: this.categories.scripting };
recordStyles[recordTypes.ResourceReceiveData] = { title: WebInspector.UIString("Receive Data"), category: this.categories.loading };
recordStyles[recordTypes.GCEvent] = { title: WebInspector.UIString("GC Event"), category: this.categories.scripting };
recordStyles[recordTypes.MarkDOMContentEventType] = { title: WebInspector.UIString("DOMContent event"), category: this.categories.scripting };
recordStyles[recordTypes.MarkLoadEventType] = { title: WebInspector.UIString("Load event"), category: this.categories.scripting };
recordStyles[recordTypes.ScheduleResourceRequest] = { title: WebInspector.UIString("Schedule Request"), category: this.categories.loading };
this._recordStylesArray = recordStyles;
}
return this._recordStylesArray;
},

_createStatusbarButtons: function()
{
this.toggleTimelineButton = new WebInspector.StatusBarButton(WebInspector.UIString("Record"), "record-profile-status-bar-item");
this.toggleTimelineButton.addEventListener("click", this._toggleTimelineButtonClicked.bind(this), false);

this.clearButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear"), "clear-status-bar-item");
this.clearButton.addEventListener("click", this._clearPanel.bind(this), false);

this.toggleFilterButton = new WebInspector.StatusBarButton(this._hideShortRecordsTitleText, "timeline-filter-status-bar-item");
this.toggleFilterButton.addEventListener("click", this._toggleFilterButtonClicked.bind(this), false);

this.recordsCounter = document.createElement("span");
this.recordsCounter.className = "timeline-records-counter";
},

_updateRecordsCounter: function()
{
this.recordsCounter.textContent = WebInspector.UIString("%d of %d captured records are visible", this._rootRecord._visibleRecordsCount, this._rootRecord._allRecordsCount);
},

_updateEventDividers: function()
{
this._timelineGrid.removeEventDividers();
var clientWidth = this._graphRowsElement.offsetWidth - this._expandOffset;
var dividers = [];
for (var i = 0; i < this._markTimelineRecords.length; ++i) {
var record = this._markTimelineRecords[i];
var positions = this._calculator.computeBarGraphWindowPosition(record, clientWidth);
var dividerPosition = Math.round(positions.left);
if (dividerPosition < 0 || dividerPosition >= clientWidth || dividers[dividerPosition])
continue;
var divider = this._createEventDivider(record);
divider.style.left = (dividerPosition + this._expandOffset) + "px";
dividers[dividerPosition] = divider;
}
this._timelineGrid.addEventDividers(dividers);
this._overviewPane.updateEventDividers(this._markTimelineRecords, this._createEventDivider.bind(this));
},

_createEventDivider: function(record)
{
var eventDivider = document.createElement("div");
eventDivider.className = "resources-event-divider";
var recordTypes = WebInspector.TimelineAgent.RecordType;

var eventDividerPadding = document.createElement("div");
eventDividerPadding.className = "resources-event-divider-padding";
eventDividerPadding.title = record.title;

if (record.type === recordTypes.MarkDOMContentEventType)
eventDivider.className += " resources-blue-divider";
else if (record.type === recordTypes.MarkLoadEventType)
eventDivider.className += " resources-red-divider";
else if (record.type === recordTypes.MarkTimeline) {
eventDivider.className += " resources-orange-divider";
eventDividerPadding.title = record.data.message;
}
eventDividerPadding.appendChild(eventDivider);
return eventDividerPadding;
},

_timelinesOverviewItemSelected: function(event) {
this._overviewPane.showTimelines();
},

_memoryOverviewItemSelected: function(event) {
this._overviewPane.showMemoryGraph(this._rootRecord.children);
},

_toggleTimelineButtonClicked: function()
{
if (this.toggleTimelineButton.toggled)
InspectorBackend.stopTimelineProfiler();
else {
this._clearPanel();
InspectorBackend.startTimelineProfiler();
}
},

_toggleFilterButtonClicked: function()
{
this.toggleFilterButton.toggled = !this.toggleFilterButton.toggled;
this._calculator._showShortEvents = this.toggleFilterButton.toggled;
this.toggleFilterButton.element.title = this._calculator._showShortEvents ? this._hideShortRecordsTitleText : this._showShortRecordsTitleText;
this._scheduleRefresh(true);
},

timelineWasStarted: function()
{
this.toggleTimelineButton.toggled = true;
},

timelineWasStopped: function()
{
this.toggleTimelineButton.toggled = false;
},

addRecordToTimeline: function(record)
{
if (record.type == WebInspector.TimelineAgent.RecordType.ResourceSendRequest && record.data.isMainResource) {
if (this._mainResourceIdentifier != record.data.identifier) {



this._mainResourceIdentifier = record.data.identifier;
this._clearPanel();
}
}
this._innerAddRecordToTimeline(record, this._rootRecord);
this._scheduleRefresh();
},

_findParentRecord: function(record)
{
var recordTypes = WebInspector.TimelineAgent.RecordType;
var parentRecord;
if (record.type === recordTypes.ResourceReceiveResponse ||
record.type === recordTypes.ResourceFinish ||
record.type === recordTypes.ResourceReceiveData)
parentRecord = this._sendRequestRecords[record.data.identifier];
else if (record.type === recordTypes.TimerFire)
parentRecord = this._timerRecords[record.data.timerId];
else if (record.type === recordTypes.ResourceSendRequest)
parentRecord = this._scheduledResourceRequests[record.data.url];
return parentRecord;
},

_innerAddRecordToTimeline: function(record, parentRecord)
{
var connectedToOldRecord = false;
var recordTypes = WebInspector.TimelineAgent.RecordType;
if (record.type === recordTypes.MarkDOMContentEventType || record.type === recordTypes.MarkLoadEventType)
parentRecord = null; 
else if (parentRecord === this._rootRecord) {
var newParentRecord = this._findParentRecord(record);
if (newParentRecord) {
parentRecord = newParentRecord;
connectedToOldRecord = true;
}
}

if (record.type == recordTypes.TimerFire && record.children && record.children.length) {
var childRecord = record.children[0];
if (childRecord.type === recordTypes.FunctionCall) {
record.data.scriptName = childRecord.data.scriptName;
record.data.scriptLine = childRecord.data.scriptLine;
record.children.shift();
record.children = childRecord.children.concat(record.children);
}
}

var formattedRecord = new WebInspector.TimelinePanel.FormattedRecord(record, parentRecord, this);

if (record.type === recordTypes.MarkDOMContentEventType || record.type === recordTypes.MarkLoadEventType) {
this._markTimelineRecords.push(formattedRecord);
return;
}

++this._rootRecord._allRecordsCount;
formattedRecord.collapsed = (parentRecord === this._rootRecord);

var childrenCount = record.children ? record.children.length : 0;
for (var i = 0; i < childrenCount; ++i)
this._innerAddRecordToTimeline(record.children[i], formattedRecord);

formattedRecord._calculateAggregatedStats(this.categories);

if (connectedToOldRecord) {
var record = formattedRecord;
do {
var parent = record.parent;
parent._cpuTime += formattedRecord._cpuTime;
if (parent._lastChildEndTime < record._lastChildEndTime)
parent._lastChildEndTime = record._lastChildEndTime;
for (var category in formattedRecord._aggregatedStats)
parent._aggregatedStats[category] += formattedRecord._aggregatedStats[category];
record = parent;
} while (record.parent);
} else
if (parentRecord !== this._rootRecord)
parentRecord._selfTime -= formattedRecord.endTime - formattedRecord.startTime;


if (record.type === recordTypes.MarkTimeline)
this._markTimelineRecords.push(formattedRecord);
},

setSidebarWidth: function(width)
{
WebInspector.Panel.prototype.setSidebarWidth.call(this, width);
this._sidebarBackgroundElement.style.width = width + "px";
this._topPaneSidebarElement.style.width = width + "px";
},

updateMainViewWidth: function(width)
{
this._containerContentElement.style.left = width + "px";
this._scheduleRefresh();
this._overviewPane.updateMainViewWidth(width);
},

resize: function()
{
this._closeRecordDetails();
this._scheduleRefresh();
},

_createRootRecord: function()
{
var rootRecord = {};
rootRecord.children = [];
rootRecord._visibleRecordsCount = 0;
rootRecord._allRecordsCount = 0;
rootRecord._aggregatedStats = {};
return rootRecord;
},

_clearPanel: function()
{
this._markTimelineRecords = [];
this._sendRequestRecords = {};
this._scheduledResourceRequests = {};
this._timerRecords = {};
this._rootRecord = this._createRootRecord();
this._boundariesAreValid = false;
this._overviewPane.reset();
this._adjustScrollPosition(0);
this._refresh();
this._closeRecordDetails();
},

show: function()
{
WebInspector.Panel.prototype.show.call(this);
if (typeof this._scrollTop === "number")
this._containerElement.scrollTop = this._scrollTop;
this._refresh();
WebInspector.drawer.currentPanelCounters = this.recordsCounter;
},

hide: function()
{
WebInspector.Panel.prototype.hide.call(this);
this._closeRecordDetails();
WebInspector.drawer.currentPanelCounters = null;
},

_onScroll: function(event)
{
this._closeRecordDetails();
var scrollTop = this._containerElement.scrollTop;
var dividersTop = Math.max(0, scrollTop);
this._timelineGrid.setScrollAndDividerTop(scrollTop, dividersTop);
this._scheduleRefresh(true);
},

_windowChanged: function()
{
this._closeRecordDetails();
this._scheduleRefresh();
},

_scheduleRefresh: function(preserveBoundaries)
{
this._closeRecordDetails();
this._boundariesAreValid &= preserveBoundaries;

if (!this.visible)
return;

if (preserveBoundaries)
this._refresh();
else
if (!this._refreshTimeout)
this._refreshTimeout = setTimeout(this._refresh.bind(this), 100);
},

_refresh: function()
{
if (this._refreshTimeout) {
clearTimeout(this._refreshTimeout);
delete this._refreshTimeout;
}

this._overviewPane.update(this._rootRecord.children, this._calculator._showShortEvents);
this._refreshRecords(!this._boundariesAreValid);
this._updateRecordsCounter();
if(!this._boundariesAreValid)
this._updateEventDividers();
this._boundariesAreValid = true;
},

_updateBoundaries: function()
{
this._calculator.reset();
this._calculator.windowLeft = this._overviewPane.windowLeft;
this._calculator.windowRight = this._overviewPane.windowRight;

for (var i = 0; i < this._rootRecord.children.length; ++i)
this._calculator.updateBoundaries(this._rootRecord.children[i]);

this._calculator.calculateWindow();
},

_addToRecordsWindow: function(record, recordsWindow, parentIsCollapsed)
{
if (!this._calculator._showShortEvents && !record.isLong())
return;
var percentages = this._calculator.computeBarGraphPercentages(record);
if (percentages.start < 100 && percentages.endWithChildren >= 0 && !record.category.hidden) {
++this._rootRecord._visibleRecordsCount;
++record.parent._invisibleChildrenCount;
if (!parentIsCollapsed)
recordsWindow.push(record);
}

var index = recordsWindow.length;
record._invisibleChildrenCount = 0;
for (var i = 0; i < record.children.length; ++i)
this._addToRecordsWindow(record.children[i], recordsWindow, parentIsCollapsed || record.collapsed);
record._visibleChildrenCount = recordsWindow.length - index;
},

_filterRecords: function()
{
var recordsInWindow = [];
this._rootRecord._visibleRecordsCount = 0;
for (var i = 0; i < this._rootRecord.children.length; ++i)
this._addToRecordsWindow(this._rootRecord.children[i], recordsInWindow);
return recordsInWindow;
},

_refreshRecords: function(updateBoundaries)
{
if (updateBoundaries)
this._updateBoundaries();

var recordsInWindow = this._filterRecords();


this._scrollTop = this._containerElement.scrollTop;
var visibleTop = this._scrollTop;
var visibleBottom = visibleTop + this._containerElement.clientHeight;

const rowHeight = WebInspector.TimelinePanel.rowHeight;


var startIndex = Math.max(0, Math.min(Math.floor(visibleTop / rowHeight) - 1, recordsInWindow.length - 1));
var endIndex = Math.min(recordsInWindow.length, Math.ceil(visibleBottom / rowHeight));


const top = (startIndex * rowHeight) + "px";
this._topGapElement.style.height = top;
this.sidebarElement.style.top = top;
this.sidebarResizeElement.style.top = top;
this._bottomGapElement.style.height = (recordsInWindow.length - endIndex) * rowHeight + "px";


var listRowElement = this._sidebarListElement.firstChild;
var width = this._graphRowsElement.offsetWidth;
this._itemsGraphsElement.removeChild(this._graphRowsElement);
var graphRowElement = this._graphRowsElement.firstChild;
var scheduleRefreshCallback = this._scheduleRefresh.bind(this, true);
this._itemsGraphsElement.removeChild(this._expandElements);
this._expandElements.removeChildren();

for (var i = 0; i < endIndex; ++i) {
var record = recordsInWindow[i];
var isEven = !(i % 2);

if (i < startIndex) {
var lastChildIndex = i + record._visibleChildrenCount;
if (lastChildIndex >= startIndex && lastChildIndex < endIndex) {
var expandElement = new WebInspector.TimelineExpandableElement(this._expandElements);
expandElement._update(record, i, this._calculator.computeBarGraphWindowPosition(record, width - this._expandOffset));
}
} else {
if (!listRowElement) {
listRowElement = new WebInspector.TimelineRecordListRow().element;
this._sidebarListElement.appendChild(listRowElement);
}
if (!graphRowElement) {
graphRowElement = new WebInspector.TimelineRecordGraphRow(this._itemsGraphsElement, scheduleRefreshCallback, rowHeight).element;
this._graphRowsElement.appendChild(graphRowElement);
}

listRowElement.row.update(record, isEven, this._calculator, visibleTop);
graphRowElement.row.update(record, isEven, this._calculator, width, this._expandOffset, i);

listRowElement = listRowElement.nextSibling;
graphRowElement = graphRowElement.nextSibling;
}
}


while (listRowElement) {
var nextElement = listRowElement.nextSibling;
listRowElement.row.dispose();
listRowElement = nextElement;
}
while (graphRowElement) {
var nextElement = graphRowElement.nextSibling;
graphRowElement.row.dispose();
graphRowElement = nextElement;
}

this._itemsGraphsElement.insertBefore(this._graphRowsElement, this._bottomGapElement);
this._itemsGraphsElement.appendChild(this._expandElements);
this.sidebarResizeElement.style.height = this.sidebarElement.clientHeight + "px";

var timelinePaddingLeft = this._calculator.windowLeft === 0 ? this._expandOffset : 0;
if (updateBoundaries)
this._timelineGrid.updateDividers(true, this._calculator, timelinePaddingLeft);
this._adjustScrollPosition((recordsInWindow.length + 1) * rowHeight);
},

_adjustScrollPosition: function(totalHeight)
{

if ((this._containerElement.scrollTop + this._containerElement.offsetHeight) > totalHeight + 1)
this._containerElement.scrollTop = (totalHeight - this._containerElement.offsetHeight);
},

_getPopoverAnchor: function(element)
{
return element.enclosingNodeOrSelfWithClass("timeline-graph-bar") || element.enclosingNodeOrSelfWithClass("timeline-tree-item");
},

_showPopover: function(anchor)
{
var record = anchor.row._record;
var popover = new WebInspector.Popover(record._generatePopupContent(this._calculator, this.categories));
popover.show(anchor);
return popover;
},

_closeRecordDetails: function()
{
this._popoverHelper.hidePopup();
}
}

WebInspector.TimelinePanel.prototype.__proto__ = WebInspector.Panel.prototype;

WebInspector.TimelineCategory = function(name, title, color)
{
this.name = name;
this.title = title;
this.color = color;
}

WebInspector.TimelineCalculator = function()
{
this.reset();
this.windowLeft = 0.0;
this.windowRight = 1.0;
}

WebInspector.TimelineCalculator.prototype = {
computeBarGraphPercentages: function(record)
{
var start = (record.startTime - this.minimumBoundary) / this.boundarySpan * 100;
var end = (record.startTime + record._selfTime - this.minimumBoundary) / this.boundarySpan * 100;
var endWithChildren = (record._lastChildEndTime - this.minimumBoundary) / this.boundarySpan * 100;
var cpuWidth = record._cpuTime / this.boundarySpan * 100;
return {start: start, end: end, endWithChildren: endWithChildren, cpuWidth: cpuWidth};
},

computeBarGraphWindowPosition: function(record, clientWidth)
{
const minWidth = 5;
const borderWidth = 4;
var workingArea = clientWidth - minWidth - borderWidth;
var percentages = this.computeBarGraphPercentages(record);
var left = percentages.start / 100 * workingArea;
var width = (percentages.end - percentages.start) / 100 * workingArea + minWidth;
var widthWithChildren =  (percentages.endWithChildren - percentages.start) / 100 * workingArea;
var cpuWidth = percentages.cpuWidth / 100 * workingArea + minWidth;
if (percentages.endWithChildren > percentages.end)
widthWithChildren += borderWidth + minWidth;
return {left: left, width: width, widthWithChildren: widthWithChildren, cpuWidth: cpuWidth};
},

calculateWindow: function()
{
this.minimumBoundary = this._absoluteMinimumBoundary + this.windowLeft * (this._absoluteMaximumBoundary - this._absoluteMinimumBoundary);
this.maximumBoundary = this._absoluteMinimumBoundary + this.windowRight * (this._absoluteMaximumBoundary - this._absoluteMinimumBoundary);
this.boundarySpan = this.maximumBoundary - this.minimumBoundary;
},

reset: function()
{
this._absoluteMinimumBoundary = -1;
this._absoluteMaximumBoundary = -1;
},

updateBoundaries: function(record)
{
var lowerBound = record.startTime;
if (this._absoluteMinimumBoundary === -1 || lowerBound < this._absoluteMinimumBoundary)
this._absoluteMinimumBoundary = lowerBound;

const minimumTimeFrame = 0.1;
const minimumDeltaForZeroSizeEvents = 0.01;
var upperBound = Math.max(record._lastChildEndTime + minimumDeltaForZeroSizeEvents, lowerBound + minimumTimeFrame);
if (this._absoluteMaximumBoundary === -1 || upperBound > this._absoluteMaximumBoundary)
this._absoluteMaximumBoundary = upperBound;
},

formatValue: function(value)
{
return Number.secondsToString(value + this.minimumBoundary - this._absoluteMinimumBoundary, WebInspector.UIString);
}
}


WebInspector.TimelineRecordListRow = function()
{
this.element = document.createElement("div");
this.element.row = this;
this.element.style.cursor = "pointer";
var iconElement = document.createElement("span");
iconElement.className = "timeline-tree-icon";
this.element.appendChild(iconElement);

this._typeElement = document.createElement("span");
this._typeElement.className = "type";
this.element.appendChild(this._typeElement);

var separatorElement = document.createElement("span");
separatorElement.className = "separator";
separatorElement.textContent = " ";

this._dataElement = document.createElement("span");
this._dataElement.className = "data dimmed";

this.element.appendChild(separatorElement);
this.element.appendChild(this._dataElement);
}

WebInspector.TimelineRecordListRow.prototype = {
update: function(record, isEven, calculator, offset)
{
this._record = record;
this._calculator = calculator;
this._offset = offset;

this.element.className = "timeline-tree-item timeline-category-" + record.category.name + (isEven ? " even" : "");
this._typeElement.textContent = record.title;

if (this._dataElement.firstChild)
this._dataElement.removeChildren();
if (record.details) {
var detailsContainer = document.createElement("span");
if (typeof record.details === "object") {
detailsContainer.appendChild(document.createTextNode("("));
detailsContainer.appendChild(record.details);
detailsContainer.appendChild(document.createTextNode(")"));
} else
detailsContainer.textContent = "(" + record.details + ")";
this._dataElement.appendChild(detailsContainer);
}
},

dispose: function()
{
this.element.parentElement.removeChild(this.element);
}
}

WebInspector.TimelineRecordGraphRow = function(graphContainer, scheduleRefresh)
{
this.element = document.createElement("div");
this.element.row = this;

this._barAreaElement = document.createElement("div");
this._barAreaElement.className = "timeline-graph-bar-area";
this.element.appendChild(this._barAreaElement);

this._barWithChildrenElement = document.createElement("div");
this._barWithChildrenElement.className = "timeline-graph-bar with-children";
this._barWithChildrenElement.row = this;
this._barAreaElement.appendChild(this._barWithChildrenElement);

this._barCpuElement = document.createElement("div");
this._barCpuElement.className = "timeline-graph-bar cpu"
this._barCpuElement.row = this;
this._barAreaElement.appendChild(this._barCpuElement);

this._barElement = document.createElement("div");
this._barElement.className = "timeline-graph-bar";
this._barElement.row = this;
this._barAreaElement.appendChild(this._barElement);

this._expandElement = new WebInspector.TimelineExpandableElement(graphContainer);
this._expandElement._element.addEventListener("click", this._onClick.bind(this));

this._scheduleRefresh = scheduleRefresh;
}

WebInspector.TimelineRecordGraphRow.prototype = {
update: function(record, isEven, calculator, clientWidth, expandOffset, index)
{
this._record = record;
this.element.className = "timeline-graph-side timeline-category-" + record.category.name + (isEven ? " even" : "");
var barPosition = calculator.computeBarGraphWindowPosition(record, clientWidth - expandOffset);
this._barWithChildrenElement.style.left = barPosition.left + expandOffset + "px";
this._barWithChildrenElement.style.width = barPosition.widthWithChildren + "px";
this._barElement.style.left = barPosition.left + expandOffset + "px";
this._barElement.style.width =  barPosition.width + "px";
this._barCpuElement.style.left = barPosition.left + expandOffset + "px";
this._barCpuElement.style.width = barPosition.cpuWidth + "px";
this._expandElement._update(record, index, barPosition);
},

_onClick: function(event)
{
this._record.collapsed = !this._record.collapsed;
this._scheduleRefresh();
},

dispose: function()
{
this.element.parentElement.removeChild(this.element);
this._expandElement._dispose();
}
}

WebInspector.TimelinePanel.FormattedRecord = function(record, parentRecord, panel)
{
var recordTypes = WebInspector.TimelineAgent.RecordType;
var style = panel._recordStyles[record.type];

this.parent = parentRecord;
if (parentRecord)
parentRecord.children.push(this);
this.category = style.category;
this.title = style.title;
this.startTime = record.startTime / 1000;
this.data = record.data;
this.type = record.type;
this.endTime = (typeof record.endTime !== "undefined") ? record.endTime / 1000 : this.startTime;
this._selfTime = this.endTime - this.startTime;
this._lastChildEndTime = this.endTime;
this.originalRecordForTests = record;
if (record.stackTrace && record.stackTrace.length)
this.stackTrace = record.stackTrace;
this.totalHeapSize = record.totalHeapSize;
this.usedHeapSize = record.usedHeapSize;


if (record.type === recordTypes.ResourceSendRequest) {
panel._sendRequestRecords[record.data.identifier] = this;
} else if (record.type === recordTypes.ScheduleResourceRequest) {
panel._scheduledResourceRequests[record.data.url] = this;
} else if (record.type === recordTypes.ResourceReceiveResponse) {
var sendRequestRecord = panel._sendRequestRecords[record.data.identifier];
if (sendRequestRecord) { 
record.data.url = sendRequestRecord.data.url;

sendRequestRecord.details = this._getRecordDetails(sendRequestRecord, panel._sendRequestRecords);
if (sendRequestRecord.parent !== panel._rootRecord && sendRequestRecord.parent.type === recordTypes.ScheduleResourceRequest)
sendRequestRecord.parent.details = this._getRecordDetails(sendRequestRecord, panel._sendRequestRecords);
}
} else if (record.type === recordTypes.ResourceReceiveData) {
var sendRequestRecord = panel._sendRequestRecords[record.data.identifier];
if (sendRequestRecord) 
record.data.url = sendRequestRecord.data.url;
} else if (record.type === recordTypes.ResourceFinish) {
var sendRequestRecord = panel._sendRequestRecords[record.data.identifier];
if (sendRequestRecord) 
record.data.url = sendRequestRecord.data.url;
} else if (record.type === recordTypes.TimerInstall) {
this.timeout = record.data.timeout;
this.singleShot = record.data.singleShot;
panel._timerRecords[record.data.timerId] = this;
} else if (record.type === recordTypes.TimerFire) {
var timerInstalledRecord = panel._timerRecords[record.data.timerId];
if (timerInstalledRecord) {
this.callSiteStackTrace = timerInstalledRecord.stackTrace;
this.timeout = timerInstalledRecord.timeout;
this.singleShot = timerInstalledRecord.singleShot;
}
}
this.details = this._getRecordDetails(record, panel._sendRequestRecords);
}

WebInspector.TimelinePanel.FormattedRecord.prototype = {
isLong: function()
{
return (this._lastChildEndTime - this.startTime) > WebInspector.TimelinePanel.shortRecordThreshold;
},

get children()
{
if (!this._children)
this._children = [];
return this._children;
},

_generateAggregatedInfo: function()
{
var cell = document.createElement("span");
cell.className = "timeline-aggregated-info";
for (var index in this._aggregatedStats) {
var label = document.createElement("div");
label.className = "timeline-aggregated-category timeline-" + index;
cell.appendChild(label);
var text = document.createElement("span");
text.textContent = Number.secondsToString(this._aggregatedStats[index] + 0.0001, WebInspector.UIString);
cell.appendChild(text);
}
return cell;
},

_generatePopupContent: function(calculator, categories)
{
var contentHelper = new WebInspector.TimelinePanel.PopupContentHelper(this.title);

if (this._children && this._children.length) {
contentHelper._appendTextRow(WebInspector.UIString("Self Time"), Number.secondsToString(this._selfTime + 0.0001, WebInspector.UIString));
contentHelper._appendElementRow(WebInspector.UIString("Aggregated Time"), this._generateAggregatedInfo());
}
var text = WebInspector.UIString("%s (at %s)", Number.secondsToString(this._lastChildEndTime - this.startTime, WebInspector.UIString),
calculator.formatValue(this.startTime - calculator.minimumBoundary));
contentHelper._appendTextRow(WebInspector.UIString("Duration"), text);

const recordTypes = WebInspector.TimelineAgent.RecordType;

switch (this.type) {
case recordTypes.GCEvent:
contentHelper._appendTextRow(WebInspector.UIString("Collected"), Number.bytesToString(this.data.usedHeapSizeDelta, WebInspector.UIString));
break;
case recordTypes.TimerInstall:
case recordTypes.TimerFire:
case recordTypes.TimerRemove:
contentHelper._appendTextRow(WebInspector.UIString("Timer ID"), this.data.timerId);
if (typeof this.timeout === "number") {
contentHelper._appendTextRow(WebInspector.UIString("Timeout"), Number.secondsToString(this.timeout / 1000, WebInspector.UIString));
contentHelper._appendTextRow(WebInspector.UIString("Repeats"), !this.singleShot);
}
break;
case recordTypes.FunctionCall:
contentHelper._appendLinkRow(WebInspector.UIString("Location"), this.data.scriptName, this.data.scriptLine);
break;
case recordTypes.ScheduleResourceRequest:
case recordTypes.ResourceSendRequest:
case recordTypes.ResourceReceiveResponse:
case recordTypes.ResourceReceiveData:
case recordTypes.ResourceFinish:
contentHelper._appendLinkRow(WebInspector.UIString("Resource"), this.data.url);
if (this.data.requestMethod)
contentHelper._appendTextRow(WebInspector.UIString("Request Method"), this.data.requestMethod);
if (typeof this.data.statusCode === "number")
contentHelper._appendTextRow(WebInspector.UIString("Status Code"), this.data.statusCode);
if (this.data.mimeType)
contentHelper._appendTextRow(WebInspector.UIString("MIME Type"), this.data.mimeType);
if (typeof this.data.expectedContentLength === "number" && this.data.expectedContentLength !== -1)
contentHelper._appendTextRow(WebInspector.UIString("Expected Content Length"), this.data.expectedContentLength);
break;
case recordTypes.EvaluateScript:
if (this.data && this.data.url)
contentHelper._appendLinkRow(WebInspector.UIString("Script"), this.data.url, this.data.lineNumber);
break;
case recordTypes.Paint:
contentHelper._appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("%d × %d", this.data.x, this.data.y));
contentHelper._appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", this.data.width, this.data.height));
case recordTypes.RecalculateStyles: 
break;
default:
if (this.details)
contentHelper._appendTextRow(WebInspector.UIString("Details"), this.details);
break;
}

if (this.data.scriptName && this.type !== recordTypes.FunctionCall)
contentHelper._appendLinkRow(WebInspector.UIString("Function Call"), this.data.scriptName, this.data.scriptLine);

if (this.usedHeapSize)
contentHelper._appendTextRow(WebInspector.UIString("Used Heap Size"), WebInspector.UIString("%s of %s", Number.bytesToString(this.usedHeapSize, WebInspector.UIString), Number.bytesToString(this.totalHeapSize, WebInspector.UIString)));

if (this.callSiteStackTrace && this.callSiteStackTrace.length)
contentHelper._appendStackTrace(WebInspector.UIString("Call Site stack"), this.callSiteStackTrace);

if (this.stackTrace)
contentHelper._appendStackTrace(WebInspector.UIString("Call Stack"), this.stackTrace);

return contentHelper._contentTable;
},

_getRecordDetails: function(record, sendRequestRecords)
{
switch (record.type) {
case WebInspector.TimelineAgent.RecordType.GCEvent:
return WebInspector.UIString("%s collected", Number.bytesToString(record.data.usedHeapSizeDelta, WebInspector.UIString));
case WebInspector.TimelineAgent.RecordType.TimerFire:
return record.data.scriptName ? WebInspector.linkifyResourceAsNode(record.data.scriptName, "scripts", record.data.scriptLine, "", "") : record.data.timerId;
case WebInspector.TimelineAgent.RecordType.FunctionCall:
return record.data.scriptName ? WebInspector.linkifyResourceAsNode(record.data.scriptName, "scripts", record.data.scriptLine, "", "") : null;
case WebInspector.TimelineAgent.RecordType.EventDispatch:
return record.data ? record.data.type : null;
case WebInspector.TimelineAgent.RecordType.Paint:
return record.data.width + "\u2009\u00d7\u2009" + record.data.height;
case WebInspector.TimelineAgent.RecordType.TimerInstall:
case WebInspector.TimelineAgent.RecordType.TimerRemove:
return this.stackTrace ? WebInspector.linkifyResourceAsNode(this.stackTrace[0].scriptName, "scripts", this.stackTrace[0].lineNumber, "", "") : record.data.timerId;
case WebInspector.TimelineAgent.RecordType.ParseHTML:
case WebInspector.TimelineAgent.RecordType.RecalculateStyles:
return this.stackTrace ? WebInspector.linkifyResourceAsNode(this.stackTrace[0].scriptName, "scripts", this.stackTrace[0].lineNumber, "", "") : null;
case WebInspector.TimelineAgent.RecordType.EvaluateScript:
return record.data.url ? WebInspector.linkifyResourceAsNode(record.data.url, "scripts", record.data.lineNumber, "", "") : null;
case WebInspector.TimelineAgent.RecordType.XHRReadyStateChange:
case WebInspector.TimelineAgent.RecordType.XHRLoad:
case WebInspector.TimelineAgent.RecordType.ScheduleResourceRequest:
case WebInspector.TimelineAgent.RecordType.ResourceSendRequest:
case WebInspector.TimelineAgent.RecordType.ResourceReceiveData:
case WebInspector.TimelineAgent.RecordType.ResourceReceiveResponse:
case WebInspector.TimelineAgent.RecordType.ResourceFinish:
return WebInspector.displayNameForURL(record.data.url);
case WebInspector.TimelineAgent.RecordType.MarkTimeline:
return record.data.message;
default:
return null;
}
},

_calculateAggregatedStats: function(categories)
{
this._aggregatedStats = {};
for (var category in categories)
this._aggregatedStats[category] = 0;
this._cpuTime = this._selfTime;

if (this._children) {
for (var index = this._children.length; index; --index) {
var child = this._children[index - 1];
this._aggregatedStats[child.category.name] += child._selfTime;
for (var category in categories)
this._aggregatedStats[category] += child._aggregatedStats[category];
}
for (var category in this._aggregatedStats)
this._cpuTime += this._aggregatedStats[category];
}
}
}

WebInspector.TimelinePanel.PopupContentHelper = function(title)
{
this._contentTable = document.createElement("table");;
var titleCell = this._createCell(WebInspector.UIString("%s - Details", title), "timeline-details-title");
titleCell.colSpan = 2;
var titleRow = document.createElement("tr");
titleRow.appendChild(titleCell);
this._contentTable.appendChild(titleRow);
}

WebInspector.TimelinePanel.PopupContentHelper.prototype = {
_createCell: function(content, styleName)
{
var text = document.createElement("label");
text.appendChild(document.createTextNode(content));
var cell = document.createElement("td");
cell.className = "timeline-details";
if (styleName)
cell.className += " " + styleName;
cell.textContent = content;
return cell;
},

_appendTextRow: function(title, content)
{
var row = document.createElement("tr");
row.appendChild(this._createCell(title, "timeline-details-row-title"));
row.appendChild(this._createCell(content, "timeline-details-row-data"));
this._contentTable.appendChild(row);
},

_appendElementRow: function(title, content, titleStyle)
{
var row = document.createElement("tr");
var titleCell = this._createCell(title, "timeline-details-row-title");
if (titleStyle)
titleCell.addStyleClass(titleStyle);
row.appendChild(titleCell);
var cell = document.createElement("td");
cell.className = "timeline-details";
cell.appendChild(content);
row.appendChild(cell);
this._contentTable.appendChild(row);
},

_appendLinkRow: function(title, scriptName, scriptLine)
{
var link = WebInspector.linkifyResourceAsNode(scriptName, "scripts", scriptLine, "timeline-details");
this._appendElementRow(title, link);
},

_appendStackTrace: function(title, stackTrace)
{
this._appendTextRow("", "");
var framesTable = document.createElement("table");
for (var i = 0; i < stackTrace.length; ++i) {
var stackFrame = stackTrace[i];
var row = document.createElement("tr");
row.className = "timeline-details";
row.appendChild(this._createCell(stackFrame.functionName ? stackFrame.functionName : WebInspector.UIString("(anonymous function)"), "timeline-function-name"));
row.appendChild(this._createCell(" @ "));
var linkCell = document.createElement("td");
linkCell.appendChild(WebInspector.linkifyResourceAsNode(stackFrame.scriptName, "scripts", stackFrame.lineNumber, "timeline-details"));
row.appendChild(linkCell);
framesTable.appendChild(row);
}
this._appendElementRow(title, framesTable, "timeline-stacktrace-title");
}
}

WebInspector.TimelineExpandableElement = function(container)
{
this._element = document.createElement("div");
this._element.className = "timeline-expandable";

var leftBorder = document.createElement("div");
leftBorder.className = "timeline-expandable-left";
this._element.appendChild(leftBorder);

container.appendChild(this._element);
}

WebInspector.TimelineExpandableElement.prototype = {
_update: function(record, index, barPosition)
{
const rowHeight = WebInspector.TimelinePanel.rowHeight;
if (record._visibleChildrenCount || record._invisibleChildrenCount) {
this._element.style.top = index * rowHeight + "px";
this._element.style.left = barPosition.left + "px";
this._element.style.width = Math.max(12, barPosition.width + 25) + "px";
if (!record.collapsed) {
this._element.style.height = (record._visibleChildrenCount + 1) * rowHeight + "px";
this._element.addStyleClass("timeline-expandable-expanded");
this._element.removeStyleClass("timeline-expandable-collapsed");
} else {
this._element.style.height = rowHeight + "px";
this._element.addStyleClass("timeline-expandable-collapsed");
this._element.removeStyleClass("timeline-expandable-expanded");
}
this._element.removeStyleClass("hidden");
} else
this._element.addStyleClass("hidden");
},

_dispose: function()
{
this._element.parentElement.removeChild(this._element);
}
}





WebInspector.TimelineOverviewPane = function(categories)
{
this._categories = categories;

this.statusBarFilters = document.createElement("div");
this.statusBarFilters.className = "status-bar-items";
for (var categoryName in this._categories) {
var category = this._categories[categoryName];
this.statusBarFilters.appendChild(this._createTimelineCategoryStatusBarCheckbox(category, this._onCheckboxClicked.bind(this, category)));
}

this._overviewGrid = new WebInspector.TimelineGrid();
this._overviewGrid.element.id = "timeline-overview-grid";
this._overviewGrid.itemsGraphsElement.id = "timeline-overview-timelines";
this._overviewGrid.element.addEventListener("mousedown", this._dragWindow.bind(this), true);

this._heapGraph = new WebInspector.HeapGraph();
this._heapGraph.element.id = "timeline-overview-memory";
this._overviewGrid.element.insertBefore(this._heapGraph.element, this._overviewGrid.itemsGraphsElement);

this.element = this._overviewGrid.element;

this._categoryGraphs = {};
var i = 0;
for (var category in this._categories) {
var categoryGraph = new WebInspector.TimelineCategoryGraph(this._categories[category], i++ % 2);
this._categoryGraphs[category] = categoryGraph;
this._overviewGrid.itemsGraphsElement.appendChild(categoryGraph.graphElement);
}
this._overviewGrid.setScrollAndDividerTop(0, 0);

this._overviewWindowElement = document.createElement("div");
this._overviewWindowElement.id = "timeline-overview-window";
this._overviewGrid.element.appendChild(this._overviewWindowElement);

this._overviewWindowBordersElement = document.createElement("div");
this._overviewWindowBordersElement.className = "timeline-overview-window-rulers";
this._overviewGrid.element.appendChild(this._overviewWindowBordersElement);

var overviewDividersBackground = document.createElement("div");
overviewDividersBackground.className = "timeline-overview-dividers-background";
this._overviewGrid.element.appendChild(overviewDividersBackground);

this._leftResizeElement = document.createElement("div");
this._leftResizeElement.className = "timeline-window-resizer";
this._leftResizeElement.style.left = 0;
this._overviewGrid.element.appendChild(this._leftResizeElement);

this._rightResizeElement = document.createElement("div");
this._rightResizeElement.className = "timeline-window-resizer timeline-window-resizer-right";
this._rightResizeElement.style.right = 0;
this._overviewGrid.element.appendChild(this._rightResizeElement);

this._overviewCalculator = new WebInspector.TimelineOverviewCalculator();

this.windowLeft = 0.0;
this.windowRight = 1.0;
}

WebInspector.TimelineOverviewPane.minSelectableSize = 12;

WebInspector.TimelineOverviewPane.prototype = {
showTimelines: function(event) {
this._heapGraph.hide();
this._overviewGrid.itemsGraphsElement.removeStyleClass("hidden");
},

showMemoryGraph: function(records) {
this._heapGraph.show();
this._heapGraph.update(records);
this._overviewGrid.itemsGraphsElement.addStyleClass("hidden");
},

_onCheckboxClicked: function (category, event) {
if (event.target.checked)
category.hidden = false;
else
category.hidden = true;
this._categoryGraphs[category.name].dimmed = !event.target.checked;
this.dispatchEventToListeners("filter changed");
},

_forAllRecords: function(recordsArray, callback)
{
if (!recordsArray)
return;
for (var i = 0; i < recordsArray.length; ++i) {
callback(recordsArray[i]);
this._forAllRecords(recordsArray[i].children, callback);
}
},

update: function(records, showShortEvents)
{
this._showShortEvents = showShortEvents;

var timelines = {};
for (var category in this._categories) {
timelines[category] = [];
this._categoryGraphs[category].clearChunks();
}


this._overviewCalculator.reset();
this._forAllRecords(records, this._overviewCalculator.updateBoundaries.bind(this._overviewCalculator));

function markTimeline(record)
{
if (!(this._showShortEvents || record.isLong()))
return;
var percentages = this._overviewCalculator.computeBarGraphPercentages(record);

var end = Math.round(percentages.end);
var categoryName = record.category.name;
for (var j = Math.round(percentages.start); j <= end; ++j)
timelines[categoryName][j] = true;
}
this._forAllRecords(records, markTimeline.bind(this));


for (var category in this._categories) {
var timeline = timelines[category];
window.timelineSaved = timeline;
var chunkStart = -1;
for (var j = 0; j < 101; ++j) {
if (timeline[j]) {
if (chunkStart === -1)
chunkStart = j;
} else {
if (chunkStart !== -1) {
this._categoryGraphs[category].addChunk(chunkStart, j);
chunkStart = -1;
}
}
}
if (chunkStart !== -1) {
this._categoryGraphs[category].addChunk(chunkStart, 100);
chunkStart = -1;
}
}

this._heapGraph.setSize(this._overviewGrid.element.offsetWidth, 60);
if (this._heapGraph.visible)
this._heapGraph.update(records);

this._overviewGrid.updateDividers(true, this._overviewCalculator);
},

updateEventDividers: function(records, dividerConstructor)
{
this._overviewGrid.removeEventDividers();
var dividers = [];
for (var i = 0; i < records.length; ++i) {
var record = records[i];
var positions = this._overviewCalculator.computeBarGraphPercentages(record);
var dividerPosition = Math.round(positions.start * 10);
if (dividers[dividerPosition])
continue;
var divider = dividerConstructor(record);
divider.style.left = positions.start + "%";
dividers[dividerPosition] = divider;
}
this._overviewGrid.addEventDividers(dividers);
},

updateMainViewWidth: function(width, records)
{
this._overviewGrid.element.style.left = width + "px";
this.statusBarFilters.style.left = Math.max(155, width) + "px";
},

reset: function()
{
this.windowLeft = 0.0;
this.windowRight = 1.0;
this._overviewWindowElement.style.left = "0%";
this._overviewWindowElement.style.width = "100%";
this._overviewWindowBordersElement.style.left = "0%";
this._overviewWindowBordersElement.style.right = "0%";
this._leftResizeElement.style.left = "0%";
this._rightResizeElement.style.left = "100%";
this._overviewCalculator.reset();
this._overviewGrid.updateDividers(true, this._overviewCalculator);
},

_resizeWindow: function(resizeElement, event)
{
WebInspector.elementDragStart(resizeElement, this._windowResizeDragging.bind(this, resizeElement), this._endWindowDragging.bind(this), event, "col-resize");
},

_windowResizeDragging: function(resizeElement, event)
{
if (resizeElement === this._leftResizeElement)
this._resizeWindowLeft(event.pageX - this._overviewGrid.element.offsetLeft);
else
this._resizeWindowRight(event.pageX - this._overviewGrid.element.offsetLeft);
event.preventDefault();
},

_dragWindow: function(event)
{
var node = event.target;
while (node) {
if (node === this._overviewGrid._dividersLabelBarElement) {
WebInspector.elementDragStart(this._overviewWindowElement, this._windowDragging.bind(this, event.pageX,
this._leftResizeElement.offsetLeft, this._rightResizeElement.offsetLeft), this._endWindowDragging.bind(this), event, "ew-resize");
break;
} else if (node === this._overviewGrid.element) {
var position = event.pageX - this._overviewGrid.element.offsetLeft;
this._overviewWindowSelector = new WebInspector.TimelinePanel.WindowSelector(this._overviewGrid.element, position, event);
WebInspector.elementDragStart(null, this._windowSelectorDragging.bind(this), this._endWindowSelectorDragging.bind(this), event, "col-resize");
break;
} else if (node === this._leftResizeElement || node === this._rightResizeElement) {
this._resizeWindow(node, event);
break;
}
node = node.parentNode;
}
},

_windowSelectorDragging: function(event)
{
this._overviewWindowSelector._updatePosition(event.pageX - this._overviewGrid.element.offsetLeft);
event.preventDefault();
},

_endWindowSelectorDragging: function(event)
{
WebInspector.elementDragEnd(event);
var window = this._overviewWindowSelector._close(event.pageX - this._overviewGrid.element.offsetLeft);
delete this._overviewWindowSelector;
if (window.end - window.start < WebInspector.TimelineOverviewPane.minSelectableSize)
if (this._overviewGrid.itemsGraphsElement.offsetWidth - window.end > WebInspector.TimelineOverviewPane.minSelectableSize)
window.end = window.start + WebInspector.TimelineOverviewPane.minSelectableSize;
else
window.start = window.end - WebInspector.TimelineOverviewPane.minSelectableSize;
this._setWindowPosition(window.start, window.end);
},

_windowDragging: function(startX, windowLeft, windowRight, event)
{
var delta = event.pageX - startX;
var start = windowLeft + delta;
var end = windowRight + delta;
var windowSize = windowRight - windowLeft;

if (start < 0) {
start = 0;
end = windowSize;
}

if (end > this._overviewGrid.element.clientWidth) {
end = this._overviewGrid.element.clientWidth;
start = end - windowSize;
}
this._setWindowPosition(start, end);

event.preventDefault();
},

_resizeWindowLeft: function(start)
{

if (start < 10)
start = 0;
else if (start > this._rightResizeElement.offsetLeft -  4)
start = this._rightResizeElement.offsetLeft - 4;
this._setWindowPosition(start, null);
},

_resizeWindowRight: function(end)
{

if (end > this._overviewGrid.element.clientWidth - 10)
end = this._overviewGrid.element.clientWidth;
else if (end < this._leftResizeElement.offsetLeft + WebInspector.TimelineOverviewPane.minSelectableSize)
end = this._leftResizeElement.offsetLeft + WebInspector.TimelineOverviewPane.minSelectableSize;
this._setWindowPosition(null, end);
},

_setWindowPosition: function(start, end)
{
const rulerAdjustment = 1 / this._overviewGrid.element.clientWidth;
if (typeof start === "number") {
this.windowLeft = start / this._overviewGrid.element.clientWidth;
this._leftResizeElement.style.left = this.windowLeft * 100 + "%";
this._overviewWindowElement.style.left = this.windowLeft * 100 + "%";
this._overviewWindowBordersElement.style.left = (this.windowLeft - rulerAdjustment) * 100 + "%";
}
if (typeof end === "number") {
this.windowRight = end / this._overviewGrid.element.clientWidth;
this._rightResizeElement.style.left = this.windowRight * 100 + "%";
}
this._overviewWindowElement.style.width = (this.windowRight - this.windowLeft) * 100 + "%";
this._overviewWindowBordersElement.style.right = (1 - this.windowRight + 2 * rulerAdjustment) * 100 + "%";
this.dispatchEventToListeners("window changed");
},

_endWindowDragging: function(event)
{
WebInspector.elementDragEnd(event);
},

_createTimelineCategoryStatusBarCheckbox: function(category, onCheckboxClicked)
{
var labelContainer = document.createElement("div");
labelContainer.addStyleClass("timeline-category-statusbar-item");
labelContainer.addStyleClass("timeline-category-" + category.name);
labelContainer.addStyleClass("status-bar-item");

var label = document.createElement("label");
var checkElement = document.createElement("input");
checkElement.type = "checkbox";
checkElement.className = "timeline-category-checkbox";
checkElement.checked = true;
checkElement.addEventListener("click", onCheckboxClicked);
label.appendChild(checkElement);

var typeElement = document.createElement("span");
typeElement.className = "type";
typeElement.textContent = category.title;
label.appendChild(typeElement);

labelContainer.appendChild(label);
return labelContainer;
}

}

WebInspector.TimelineOverviewPane.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.TimelineOverviewCalculator = function()
{
}

WebInspector.TimelineOverviewCalculator.prototype = {
computeBarGraphPercentages: function(record)
{
var start = (record.startTime - this.minimumBoundary) / this.boundarySpan * 100;
var end = (record.endTime - this.minimumBoundary) / this.boundarySpan * 100;
return {start: start, end: end};
},

reset: function()
{
delete this.minimumBoundary;
delete this.maximumBoundary;
},

updateBoundaries: function(record)
{
if (typeof this.minimumBoundary === "undefined" || record.startTime < this.minimumBoundary) {
this.minimumBoundary = record.startTime;
return true;
}
if (typeof this.maximumBoundary === "undefined" || record.endTime > this.maximumBoundary) {
this.maximumBoundary = record.endTime;
return true;
}
return false;
},

get boundarySpan()
{
return this.maximumBoundary - this.minimumBoundary;
},

formatValue: function(value)
{
return Number.secondsToString(value, WebInspector.UIString);
}
}


WebInspector.TimelineCategoryGraph = function(category, isEven)
{
this._category = category;

this._graphElement = document.createElement("div");
this._graphElement.className = "timeline-graph-side timeline-overview-graph-side" + (isEven ? " even" : "");

this._barAreaElement = document.createElement("div");
this._barAreaElement.className = "timeline-graph-bar-area timeline-category-" + category.name;
this._graphElement.appendChild(this._barAreaElement);
}

WebInspector.TimelineCategoryGraph.prototype = {
get graphElement()
{
return this._graphElement;
},

addChunk: function(start, end)
{
var chunk = document.createElement("div");
chunk.className = "timeline-graph-bar";
this._barAreaElement.appendChild(chunk);
chunk.style.setProperty("left", start + "%");
chunk.style.setProperty("width", (end - start) + "%");
},

clearChunks: function()
{
this._barAreaElement.removeChildren();
},

set dimmed(dimmed)
{
if (dimmed)
this._barAreaElement.removeStyleClass("timeline-category-" + this._category.name);
else
this._barAreaElement.addStyleClass("timeline-category-" + this._category.name);
}
}

WebInspector.TimelinePanel.WindowSelector = function(parent, position, event)
{
this._startPosition = position;
this._width = parent.offsetWidth;
this._windowSelector = document.createElement("div");
this._windowSelector.className = "timeline-window-selector";
this._windowSelector.style.left = this._startPosition + "px";
this._windowSelector.style.right = this._width - this._startPosition +  + "px";
parent.appendChild(this._windowSelector);
}

WebInspector.TimelinePanel.WindowSelector.prototype = {
_createSelectorElement: function(parent, left, width, height)
{
var selectorElement = document.createElement("div");
selectorElement.className = "timeline-window-selector";
selectorElement.style.left = left + "px";
selectorElement.style.width = width + "px";
selectorElement.style.top = "0px";
selectorElement.style.height = height + "px";
parent.appendChild(selectorElement);
return selectorElement;
},

_close: function(position)
{
position = Math.max(0, Math.min(position, this._width));
this._windowSelector.parentNode.removeChild(this._windowSelector);
return this._startPosition < position ? {start: this._startPosition, end: position} : {start: position, end: this._startPosition};
},

_updatePosition: function(position)
{
position = Math.max(0, Math.min(position, this._width));
if (position < this._startPosition) {
this._windowSelector.style.left = position + "px";
this._windowSelector.style.right = this._width - this._startPosition + "px";
} else {
this._windowSelector.style.left = this._startPosition + "px";
this._windowSelector.style.right = this._width - position + "px";
}
}
}

WebInspector.HeapGraph = function() {
this._canvas = document.createElement("canvas");

this._maxHeapSizeLabel = document.createElement("div");
this._maxHeapSizeLabel.addStyleClass("memory-graph-label");

this._element = document.createElement("div");
this._element.addStyleClass("hidden");
this._element.appendChild(this._canvas);
this._element.appendChild(this._maxHeapSizeLabel);
}

WebInspector.HeapGraph.prototype = {
get element() {

return this._element;
},

get visible() {
return !this.element.hasStyleClass("hidden");
},

show: function() {
this.element.removeStyleClass("hidden");
},

hide: function() {
this.element.addStyleClass("hidden");
},

setSize: function(w, h) {
this._canvas.width = w;
this._canvas.height = h - 5;
},

update: function(records)
{
if (!records.length)
return;

var maxTotalHeapSize = 0;
var minTime;
var maxTime;
this._forAllRecords(records, function(r) {
if (r.totalHeapSize && r.totalHeapSize > maxTotalHeapSize)
maxTotalHeapSize = r.totalHeapSize;

if (typeof minTime === "undefined" || r.startTime < minTime)
minTime = r.startTime;
if (typeof maxTime === "undefined" || r.endTime > maxTime)
maxTime = r.endTime;
});

var width = this._canvas.width;
var height = this._canvas.height;
var xFactor = width / (maxTime - minTime);
var yFactor = height / maxTotalHeapSize;

var histogram = new Array(width);
this._forAllRecords(records, function(r) {
if (!r.usedHeapSize)
return;
var x = Math.round((r.endTime - minTime) * xFactor);
var y = Math.round(r.usedHeapSize * yFactor);
histogram[x] = Math.max(histogram[x] || 0, y);
});

var ctx = this._canvas.getContext("2d");
this._clear(ctx);


height = height + 1;

ctx.beginPath();
var initialY = 0;
for (var k = 0; k < histogram.length; k++) {
if (histogram[k]) {
initialY = histogram[k];
break;
}
}
ctx.moveTo(0, height - initialY);

for (var x = 0; x < histogram.length; x++) {
if (!histogram[x])
continue;
ctx.lineTo(x, height - histogram[x]);
}

ctx.lineWidth = 0.5;
ctx.strokeStyle = "rgba(20,0,0,0.8)";
ctx.stroke();

ctx.fillStyle = "rgba(214,225,254, 0.8);";
ctx.lineTo(width, 60);
ctx.lineTo(0, 60);
ctx.lineTo(0, height - initialY);
ctx.fill();
ctx.closePath();

this._maxHeapSizeLabel.textContent = Number.bytesToString(maxTotalHeapSize);
},

_clear: function(ctx) {
ctx.fillStyle = "rgba(255,255,255,0.8)";
ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);
},

_forAllRecords: WebInspector.TimelineOverviewPane.prototype._forAllRecords
}





WebInspector.TestController = function(callId)
{
this._callId = callId;
this._waitUntilDone = false;
this.results = [];
}

WebInspector.TestController.prototype = {
waitUntilDone: function()
{
this._waitUntilDone = true;
},

notifyDone: function(result)
{
if (typeof result === "undefined" && this.results.length)
result = this.results;
var message = typeof result === "undefined" ? "\"<undefined>\"" : JSON.stringify(result);
InspectorBackend.didEvaluateForTestInFrontend(this._callId, message);
},

runAfterPendingDispatches: function(callback)
{
if (WebInspector.pendingDispatches === 0) {
callback();
return;
}
setTimeout(this.runAfterPendingDispatches.bind(this), 0, callback);
}
}

WebInspector.evaluateForTestInFrontend = function(callId, script)
{
var controller = new WebInspector.TestController(callId);
function invokeMethod()
{
try {
var result;
if (window[script] && typeof window[script] === "function")
result = window[script].call(WebInspector, controller);
else
result = window.eval(script);

if (!controller._waitUntilDone)
controller.notifyDone(result);
} catch (e) {
controller.notifyDone(e.toString());
}
}
controller.runAfterPendingDispatches(invokeMethod);
}





WebInspector.HelpScreen = function(title)
{
this._element = document.createElement("div");
this._element.className = "help-window-outer";
this._element.addEventListener("keydown", this._onKeyDown.bind(this), false);

var mainWindow = this._element.createChild("div", "help-window-main");
var captionWindow = mainWindow.createChild("div", "help-window-caption");
var closeButton = captionWindow.createChild("button", "help-close-button");
this.contentElement = mainWindow.createChild("div", "help-content");
this.contentElement.tabIndex = 0;
this.contentElement.addEventListener("blur", this._onBlur.bind(this), false);
captionWindow.createChild("h1", "help-window-title").innerText = title;

closeButton.innerText = "\u2716"; 
closeButton.addEventListener("click", this._hide.bind(this), false);
this._closeKeys = [
WebInspector.KeyboardShortcut.Keys.Enter.code,
WebInspector.KeyboardShortcut.Keys.Esc.code,
WebInspector.KeyboardShortcut.Keys.Space.code,
];
document.body.appendChild(this._element);
}

WebInspector.HelpScreen.prototype = {
show: function()
{
if (this._isShown)
return;

this._element.style.visibility = "visible";
this._isShown = true;
this._previousFocusElement = WebInspector.currentFocusElement;
WebInspector.currentFocusElement = this.contentElement;
},

_hide: function()
{
this._isShown = false;
this._element.style.visibility = "hidden";
WebInspector.currentFocusElement = this._previousFocusElement;
},

_onKeyDown: function(event)
{
if (this._isShown && this._closeKeys.indexOf(event.keyCode) >= 0) {
this._hide();
event.stopPropagation();
}
},

_onBlur: function()
{

if (this._isShown)
WebInspector.currentFocusElement = this.contentElement;
}
}





WebInspector.GoToLineDialog = function(view)
{
this._element = document.createElement("div");
this._element.className = "go-to-line-dialog";
this._element.addEventListener("keydown", this._onKeyDown.bind(this), false);
this._closeKeys = [
WebInspector.KeyboardShortcut.Keys.Enter.code,
WebInspector.KeyboardShortcut.Keys.Esc.code,
];

var dialogWindow = this._element;

dialogWindow.createChild("label").innerText = WebInspector.UIString("Go to line: ");

this._input = dialogWindow.createChild("input");
this._input.setAttribute("type", "text");
this._input.setAttribute("size", 6);
var linesCount = view.sourceFrame.textModel.linesCount;
if (linesCount)
this._input.setAttribute("title", WebInspector.UIString("1 - %d", linesCount));
var blurHandler = this._onBlur.bind(this);
this._input.addEventListener("blur", blurHandler, false);


var go = dialogWindow.createChild("button");
go.innerText = WebInspector.UIString("Go");
go.addEventListener("click", this._onClick.bind(this), false);
go.addEventListener("mousedown", function(e) {


this._input.removeEventListener("blur", blurHandler, false);
}.bind(this), false);

this._view = view;
view.element.appendChild(this._element);

this._previousFocusElement = WebInspector.currentFocusElement;
WebInspector.currentFocusElement = this._input;
this._input.select();
}

WebInspector.GoToLineDialog.show = function(sourceView)
{
if (this._instance)
return;
this._instance = new WebInspector.GoToLineDialog(sourceView);
}

WebInspector.GoToLineDialog.prototype = {
_hide: function()
{
if (this._isHiding)
return;
this._isHiding = true;

WebInspector.currentFocusElement = this._previousFocusElement;
WebInspector.GoToLineDialog._instance = null;
this._element.parentElement.removeChild(this._element);
},

_onBlur: function(event)
{
this._hide();
},

_onKeyDown: function(event)
{
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Tab.code) {
event.preventDefault();
return;
}

if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code)
this._highlightSelectedLine();

if (this._closeKeys.indexOf(event.keyCode) >= 0) {
this._hide();
event.stopPropagation();
}
},

_onClick: function(event)
{
this._highlightSelectedLine();
this._hide();
},

_highlightSelectedLine: function()
{
var value = this._input.value;
var lineNumber = parseInt(value, 10);
if (!isNaN(lineNumber) && lineNumber > 0) {
lineNumber = Math.min(lineNumber, this._view.sourceFrame.textModel.linesCount);
this._view.highlightLine(lineNumber);
}
}
};





WebInspector.ShortcutsHelp = function()
{
this._sections = {};
}

WebInspector.ShortcutsHelp.prototype = {
section: function(name)
{
var section = this._sections[name];
if (!section)
this._sections[name] = section = new WebInspector.ShortcutsSection(name);
return section;
},

show: function()
{
if (!this._helpScreen) {
this._helpScreen = new WebInspector.HelpScreen(WebInspector.UIString("Keyboard Shortcuts"));
this._buildTable(this._helpScreen.contentElement, 2);
}
this._helpScreen.show();
},

_buildTable: function(parent, nColumns)
{
var height = 0;
var orderedSections = [];
for (var section in this._sections) {
height += this._sections[section]._height;
orderedSections.push(this._sections[section])
}
function compareSections(a, b)
{
return a.order - b.order;
}
orderedSections = orderedSections.sort(compareSections);

const wrapAfter = height / nColumns;
var table = document.createElement("table");
table.className = "help-table";
var row = table.createChild("tr");



for (var section = 0; section < orderedSections.length;) {
var td = row.createChild("td");
td.style.width = (100 / nColumns) + "%";
var column = td.createChild("table");
for (var columnHeight = 0;
columnHeight < wrapAfter && section < orderedSections.length;
columnHeight += orderedSections[section]._height, section++) {
orderedSections[section].renderSection(column);
}
}
parent.appendChild(table);
}
};

WebInspector.shortcutsHelp = new WebInspector.ShortcutsHelp();

WebInspector.ShortcutsSection = function(name)
{
this.name = name;
this._lines = [];
this.order = ++WebInspector.ShortcutsSection._sequenceNumber;
};

WebInspector.ShortcutsSection._sequenceNumber = 0;

WebInspector.ShortcutsSection.prototype = {
addKey: function(key, description)
{
this.addLine(this._renderKey(key), description);
},

addRelatedKeys: function(keys, description)
{
this.addLine(this._renderSequence(keys,"/"), description);
},

addAlternateKeys: function(keys, description)
{
this.addLine(this._renderSequence(keys,WebInspector.UIString("or")), description);
},

addLine: function(htmlKey, description)
{
this._lines.push({ key: htmlKey, text: description })
},

renderSection: function(parent)
{
this._renderHeader(parent);

for (var line = 0; line < this._lines.length; ++line) {
var tr = parent.createChild("tr");
tr.createChild("td", "help-key-cell").innerHTML = this._lines[line].key + " : ";
tr.createChild("td").innerText = this._lines[line].text;
}
},

_renderHeader: function(parent)
{
var trHead = parent.createChild("tr");

trHead.createChild("th");
trHead.createChild("th").innerText = this.name;
},

_renderSequence: function(sequence, delimiter)
{
var delimiterHtml = '<span class="help-key-delimiter">' + delimiter.escapeHTML() + '</span>'
return sequence.map(this._renderKey).join(delimiterHtml);
},

_renderKey: function(key)
{
function renderLabel(label)
{
return '<span class="help-key monospace">' + label.escapeHTML() + '</span>';
}
return key.split(" + ").map(renderLabel).join('<span class="help-combine-keys">+</span>');
},

get _height()
{
return this._lines.length + 2; 
}
};








WebInspector.HAREntry = function(resource)
{
this._resource = resource;
}

WebInspector.HAREntry.prototype = {
build: function()
{
return {
pageref: this._resource.documentURL,
startedDateTime: new Date(this._resource.startTime * 1000),
time: WebInspector.HAREntry._toMilliseconds(this._resource.duration),
request: this._buildRequest(),
response: this._buildResponse(),

timings: this._buildTimings()
};
},

_buildRequest: function()
{
var res = {
method: this._resource.requestMethod,
url: this._resource.url,

headers: this._buildHeaders(this._resource.requestHeaders),
headersSize: -1, 
bodySize: -1 
};
if (this._resource.queryParameters)
res.queryString = this._buildParameters(this._resource.queryParameters);
if (this._resource.requestFormData)
res.postData = this._buildPostData();
if (this._resource.requestCookies)
res.cookies = this._buildCookies(this._resource.requestCookies);
return res;
},

_buildResponse: function()
{
var res = {
status: this._resource.statusCode,
statusText: this._resource.statusText,

headers: this._buildHeaders(this._resource.responseHeaders),
content: this._buildContent(),
redirectURL: this._resource.responseHeaderValue("Location") || "",
headersSize: -1, 
bodySize: this._resource.resourceSize
};
if (this._resource.responseCookies)
res.cookies = this._buildCookies(this._resource.responseCookies);
return res;
},

_buildContent: function()
{
return {
size: this._resource.resourceSize,

mimeType: this._resource.mimeType,

};
},

_buildTimings: function()
{
var waitForConnection = this._interval("connectStart", "connectEnd");
var blocked;
var connect;
var dns = this._interval("dnsStart", "dnsEnd");
var send = this._interval("sendStart", "sendEnd");
var ssl = this._interval("sslStart", "sslEnd");

if (ssl !== -1 && send !== -1)
send -= ssl;

if (this._resource.connectionReused) {
connect = -1;
blocked = waitForConnection;
} else {
blocked = 0;
connect = waitForConnection;
if (dns !== -1)
connect -= dns;
}

return {
blocked: blocked,
dns: dns,
connect: connect,
send: send,
wait: this._interval("sendEnd", "receiveHeadersEnd"),
receive: WebInspector.HAREntry._toMilliseconds(this._resource.receiveDuration),
ssl: ssl
};
},

_buildHeaders: function(headers)
{
var result = [];
for (var name in headers)
result.push({ name: name, value: headers[name] });
return result;
},

_buildPostData: function()
{
var res = {
mimeType: this._resource.requestHeaderValue("Content-Type"),
text: this._resource.requestFormData
};
if (this._resource.formParameters)
res.params = this._buildParameters(this._resource.formParameters);
return res;
},

_buildParameters: function(parameters)
{
return parameters.slice();
},

_buildCookies: function(cookies)
{
return cookies.map(this._buildCookie.bind(this));
},

_buildCookie: function(cookie)
{

return {
name: cookie.name,
value: cookie.value,
path: cookie.path,
domain: cookie.domain,
expires: cookie.expires(new Date(this._resource.startTime * 1000)),
httpOnly: cookie.httpOnly,
secure: cookie.secure
};
},

_interval: function(start, end)
{
var timing = this._resource.timing;
if (!timing)
return -1;
var startTime = timing[start];
return typeof startTime !== "number" || startTime === -1 ? -1 : Math.round(timing[end] - startTime);
}
}

WebInspector.HAREntry._toMilliseconds = function(time)
{
return time === -1 ? -1 : Math.round(time * 1000);
}

WebInspector.HARLog = function()
{
this.includeResourceIds = false;
}

WebInspector.HARLog.prototype = {
build: function()
{
var webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent);

return {
version: "1.2",
creator: {
name: "WebInspector",
version: webKitVersion ? webKitVersion[1] : "n/a"
},
pages: this._buildPages(),
entries: Object.keys(WebInspector.networkResources).map(this._convertResource.bind(this))
}
},

_buildPages: function()
{
return [
{
startedDateTime: new Date(WebInspector.mainResource.startTime * 1000),
id: WebInspector.mainResource.documentURL,
title: "",
pageTimings: this.buildMainResourceTimings()
}
];
},

buildMainResourceTimings: function()
{
return {
onContentLoad: this._pageEventTime(WebInspector.mainResourceDOMContentTime),
onLoad: this._pageEventTime(WebInspector.mainResourceLoadTime),
}
},

_convertResource: function(id)
{
var entry = (new WebInspector.HAREntry(WebInspector.networkResources[id])).build();
if (this.includeResourceIds)
entry._resourceId = id;
return entry;
},

_pageEventTime: function(time)
{
var startTime = WebInspector.mainResource.startTime;
if (time === -1 || startTime === -1)
return -1;
return WebInspector.HAREntry._toMilliseconds(time - startTime);
}
}












WebInspector.CookieParser = function()
{
}

WebInspector.CookieParser.prototype = {
get cookies()
{
return this._cookies;
},

parseCookie: function(cookieHeader)
{
if (!this._initialize(cookieHeader))
return;

for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) {
if (kv.key.charAt(0) === "$" && this._lastCookie)
this._lastCookie.addAttribute(kv.key.slice(1), kv.value);
else if (kv.key.toLowerCase() !== "$version" && typeof kv.value === "string")
this._addCookie(kv, WebInspector.Cookie.Type.Request);
this._advanceAndCheckCookieDelimiter();
}
this._flushCookie();
return this._cookies;
},

parseSetCookie: function(setCookieHeader)
{
if (!this._initialize(setCookieHeader))
return;
for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) {
if (this._lastCookie)
this._lastCookie.addAttribute(kv.key, kv.value);
else 
this._addCookie(kv, WebInspector.Cookie.Type.Response);
if (this._advanceAndCheckCookieDelimiter())
this._flushCookie();
}
this._flushCookie();
return this._cookies;
},

_initialize: function(headerValue)
{
this._input = headerValue;
if (typeof headerValue !== "string")
return false;
this._cookies = [];
this._lastCookie = null;
this._originalInputLength = this._input.length;
return true;
},

_flushCookie: function()
{
if (this._lastCookie)
this._lastCookie.size = this._originalInputLength - this._input.length - this._lastCookiePosition;
this._lastCookie = null;
},

_extractKeyValue: function()
{
if (!this._input || !this._input.length)
return null;





var keyValueMatch = /^[ \t]*([^\s=;]+)[ \t]*(?:=[ \t]*([^;\n]*))?/.exec(this._input);
        if (!keyValueMatch) {
            console.log("Failed parsing cookie header before: " + this._input);
            return null;
        }

        var result = {
            key: keyValueMatch[1],
            value: keyValueMatch[2] && keyValueMatch[2].trim(),
            position: this._originalInputLength - this._input.length
        };
        this._input = this._input.slice(keyValueMatch[0].length);
        return result;
    },

    _advanceAndCheckCookieDelimiter: function()
    {
        var match = /^\s*[\n;]\s*/.exec(this._input);
if (!match)
return false;
this._input = this._input.slice(match[0].length);
return match[0].match("\n") !== null;
},

_addCookie: function(keyValue, type)
{
if (this._lastCookie)
this._lastCookie.size = keyValue.position - this._lastCookiePosition;


this._lastCookie = keyValue.value ? new WebInspector.Cookie(keyValue.key, keyValue.value, type) :
new WebInspector.Cookie("", keyValue.key, type);
this._lastCookiePosition = keyValue.position;
this._cookies.push(this._lastCookie);
}
};

WebInspector.CookieParser.parseCookie = function(header)
{
return (new WebInspector.CookieParser()).parseCookie(header);
}

WebInspector.CookieParser.parseSetCookie = function(header)
{
return (new WebInspector.CookieParser()).parseSetCookie(header);
}

WebInspector.Cookie = function(name, value, type)
{
this.name = name;
this.value = value;
this.type = type;
this._attributes = {};
}

WebInspector.Cookie.prototype = {
get httpOnly()
{
return "httponly" in this._attributes;
},

get secure()
{
return "secure" in this._attributes;
},

get session()
{


return  !("expries" in this._attributes || "max-age" in this._attributes);
},

get path()
{
return this._attributes.path;
},

get domain()
{
return this._attributes.domain;
},

expires: function(requestDate)
{
return this._attributes.expires ? new Date(this._attributes.expires) :
(this._attributes["max-age"] ? new Date(requestDate.getTime() + 1000 * this._attributes["max-age"]) : null);
},

get attributes()
{
return this._attributes;
},

addAttribute: function(key, value)
{
this._attributes[key.toLowerCase()] = value;
}
}

WebInspector.Cookie.Type = {
Request: 0,
Response: 1
};







var context = {};  

(function () {
Preferences.ignoreWhitespace = false;
Preferences.samplingCPUProfiler = true;
Preferences.heapProfilerPresent = true;
Preferences.debuggerAlwaysEnabled = true;
Preferences.profilerAlwaysEnabled = true;
Preferences.canEditScriptSource = true;
Preferences.onlineDetectionEnabled = false;
Preferences.nativeInstrumentationEnabled = true;
Preferences.fileSystemEnabled = false;
Preferences.showTimingTab = true;
})();

var devtools = devtools || {};

devtools.domContentLoaded = function()
{
WebInspector.setAttachedWindow(WebInspector.queryParamsObject.docked === "true");
if (WebInspector.queryParamsObject.toolbar_color && WebInspector.queryParamsObject.text_color)
WebInspector.setToolbarColors(WebInspector.queryParamsObject.toolbar_color, WebInspector.queryParamsObject.text_color);
}
document.addEventListener("DOMContentLoaded", devtools.domContentLoaded, false);



(function InterceptProfilesPanelEvents()
{
var oldShow = WebInspector.ProfilesPanel.prototype.show;
WebInspector.ProfilesPanel.prototype.show = function()
{
this.enableToggleButton.visible = false;
oldShow.call(this);


WebInspector.ProfilesPanel.prototype.show = oldShow;
};
})();



WebInspector.UIString = function(string)
{
return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
};



(function()
{
var originalDragStart = WebInspector.elementDragStart;
WebInspector.elementDragStart = function(element)
{
if (element) {
var glassPane = document.createElement("div");
glassPane.style.cssText = "position:absolute;width:100%;height:100%;opacity:0;z-index:1";
glassPane.id = "glass-pane-for-drag";
element.parentElement.appendChild(glassPane);
}

originalDragStart.apply(this, arguments);
};

var originalDragEnd = WebInspector.elementDragEnd;
WebInspector.elementDragEnd = function()
{
originalDragEnd.apply(this, arguments);

var glassPane = document.getElementById("glass-pane-for-drag");
if (glassPane)
glassPane.parentElement.removeChild(glassPane);
};
})();







WebInspector.runAfterPendingDispatchesQueue = [];

WebInspector.TestController.prototype.runAfterPendingDispatches = function(callback)
{
WebInspector.runAfterPendingDispatchesQueue.push(callback);
};

WebInspector.queuesAreEmpty = function()
{
var copy = this.runAfterPendingDispatchesQueue.slice();
this.runAfterPendingDispatchesQueue = [];
for (var i = 0; i < copy.length; ++i)
copy[i].call(this);
};






WebInspector.setToolbarColors = function(backgroundColor, color)
{
if (!WebInspector._themeStyleElement) {
WebInspector._themeStyleElement = document.createElement("style");
document.head.appendChild(WebInspector._themeStyleElement);
}
WebInspector._themeStyleElement.textContent =
"#toolbar {\
             background-image: none !important;\
             background-color: " + backgroundColor + " !important;\
         }\
         \
         .toolbar-label {\
             color: " + color + " !important;\
             text-shadow: none;\
         }";
}

WebInspector.resetToolbarColors = function()
{
if (WebInspector._themeStyleElement)
WebInspector._themeStyleElement.textContent = "";

}





WebInspector.platformExtensionAPI = function(tabId)
{
function getTabId()
{
return tabId;
}
webInspector.inspectedWindow.__proto__.__defineGetter__("tabId", getTabId);
}

WebInspector.buildPlatformExtensionAPI = function()
{
return "(" + WebInspector.platformExtensionAPI + ")(" + WebInspector._inspectedTabId + ");";
}

WebInspector.setInspectedTabId = function(tabId)
{
WebInspector._inspectedTabId = tabId;
}








if (window.domAutomationController) {

var ___interactiveUiTestsMode = true;


TestSuite = function()
{
this.controlTaken_ = false;
this.timerId_ = -1;
};



TestSuite.prototype.fail = function(message)
{
if (this.controlTaken_)
this.reportFailure_(message);
else
throw message;
};



TestSuite.prototype.assertEquals = function(expected, actual, opt_message)
{
if (expected !== actual) {
var message = "Expected: '" + expected + "', but was '" + actual + "'";
if (opt_message)
message = opt_message + "(" + message + ")";
this.fail(message);
}
};



TestSuite.prototype.assertTrue = function(value, opt_message)
{
this.assertEquals(true, !!value, opt_message);
};



TestSuite.prototype.assertContains = function(string, substring)
{
if (string.indexOf(substring) === -1)
this.fail("Expected to: '" + string + "' to contain '" + substring + "'");
};



TestSuite.prototype.takeControl = function()
{
this.controlTaken_ = true;

var self = this;
this.timerId_ = setTimeout(function() {
self.reportFailure_("Timeout exceeded: 20 sec");
}, 20000);
};



TestSuite.prototype.releaseControl = function()
{
if (this.timerId_ !== -1) {
clearTimeout(this.timerId_);
this.timerId_ = -1;
}
this.reportOk_();
};



TestSuite.prototype.reportOk_ = function()
{
window.domAutomationController.send("[OK]");
};



TestSuite.prototype.reportFailure_ = function(error)
{
if (this.timerId_ !== -1) {
clearTimeout(this.timerId_);
this.timerId_ = -1;
}
window.domAutomationController.send("[FAILED] " + error);
};



TestSuite.prototype.runTest = function(testName)
{
try {
this[testName]();
if (!this.controlTaken_)
this.reportOk_();
} catch (e) {
this.reportFailure_(e);
}
};



TestSuite.prototype.showPanel = function(panelName)
{

var toolbar = document.getElementById("toolbar");
var button = toolbar.getElementsByClassName(panelName)[0];
button.click();
this.assertEquals(WebInspector.panels[panelName], WebInspector.currentPanel);
};



TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_sticky)
{
var orig = receiver[methodName];
if (typeof orig !== "function")
this.fail("Cannot find method to override: " + methodName);
var test = this;
receiver[methodName] = function(var_args) {
try {
var result = orig.apply(this, arguments);
} finally {
if (!opt_sticky)
receiver[methodName] = orig;
}

try {
override.apply(this, arguments);
} catch (e) {
test.fail("Exception in overriden method '" + methodName + "': " + e);
}
return result;
};
};






TestSuite.prototype.testEnableResourcesTab = function()
{
this.showPanel("resources");

var test = this;
this.addSniffer(WebInspector, "updateResource",
function(payload) {
test.assertEquals("simple_page.html", payload.lastPathComponent);
WebInspector.panels.resources.refresh();
WebInspector.panels.resources.revealAndSelectItem(WebInspector.resources[payload.id]);

test.releaseControl();
});



WebInspector.panels.resources._enableResourceTracking();


this.takeControl();
};



TestSuite.prototype.testProfilerTab = function()
{
this.showPanel("profiles");

var panel = WebInspector.panels.profiles;
var test = this;

function findDisplayedNode() {
var node = panel.visibleView.profileDataGridTree.children[0];
if (!node) {

window.setTimeout(findDisplayedNode, 100);
return;
}




while (node) {
if (node.functionName.indexOf("fib") !== -1)
test.releaseControl();
node = node.traverseNextNode(true, null, true);
}

test.fail();
}

function findVisibleView() {
if (!panel.visibleView) {
setTimeout(findVisibleView, 0);
return;
}
setTimeout(findDisplayedNode, 0);
}

findVisibleView();
this.takeControl();
};



TestSuite.prototype.testHeapProfiler = function()
{
this.showPanel("profiles");

var panel = WebInspector.panels.profiles;
var test = this;

function findDisplayedNode() {
var node = panel.visibleView.dataGrid.children[0];
if (!node) {

window.setTimeout(findDisplayedNode, 100);
return;
}



while (node) {
if (node.constructorName.indexOf("A") !== -1) {
test.releaseControl();
return;
}
node = node.traverseNextNode(false, null, true);
}

test.fail();
}

function findVisibleView() {
if (!panel.visibleView) {
setTimeout(findVisibleView, 0);
return;
}
setTimeout(findDisplayedNode, 0);
}

WebInspector.HeapSnapshotProfileType.prototype.buttonClicked();
findVisibleView();
this.takeControl();
};



TestSuite.prototype.testShowScriptsTab = function()
{
this.showPanel("scripts");
var test = this;

this._waitUntilScriptsAreParsed(["debugger_test_page.html"],
function() {
test.releaseControl();
});

this.takeControl();
};



TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function()
{
var test = this;
this.assertEquals(WebInspector.panels.elements, WebInspector.currentPanel, "Elements panel should be current one.");

this.addSniffer(WebInspector.panels.scripts, "reset", waitUntilScriptIsParsed);


test.evaluateInConsole_(
"window.location.reload(true);",
function(resultText) {});

function waitUntilScriptIsParsed() {
test.showPanel("scripts");
test._waitUntilScriptsAreParsed(["debugger_test_page.html"],
function() {
test.releaseControl();
});
}


this.takeControl();
};



TestSuite.prototype.testContentScriptIsPresent = function()
{
this.showPanel("scripts");
var test = this;

test._waitUntilScriptsAreParsed(
["page_with_content_script.html", "simple_content_script.js"],
function() {
test.releaseControl();
});


this.takeControl();
};



TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function()
{
var test = this;




var expectedScriptsCount = 2;
var parsedScripts = [];

this.showPanel("scripts");


function switchToElementsTab() {
test.showPanel("elements");
setTimeout(switchToScriptsTab, 0);
}

function switchToScriptsTab() {
test.showPanel("scripts");
setTimeout(checkScriptsPanel, 0);
}

function checkScriptsPanel() {
test.assertTrue(!!WebInspector.panels.scripts.visibleView, "No visible script view.");
test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html"]), "Some scripts are missing.");
checkNoDuplicates();
test.releaseControl();
}

function checkNoDuplicates() {
var scriptSelect = document.getElementById("scripts-files");
var options = scriptSelect.options;
for (var i = 0; i < options.length; i++) {
var scriptName = options[i].text;
for (var j = i + 1; j < options.length; j++)
test.assertTrue(scriptName !== options[j].text, "Found script duplicates: " + test.optionsToString_(options));
}
}

test._waitUntilScriptsAreParsed(
["debugger_test_page.html"],
function() {
checkNoDuplicates();
setTimeout(switchToElementsTab, 0);
});



this.takeControl();
};




TestSuite.prototype.testPauseWhenLoadingDevTools = function()
{
this.showPanel("scripts");
var test = this;

var expectations = {
functionsOnStack: ["callDebugger"],
lineNumber: 8,
lineText: "  debugger;"
};



if (WebInspector.currentPanel.paused) {
var callFrame = WebInspector.currentPanel.sidebarPanes.callstack.selectedCallFrame;
this.assertEquals(expectations.functionsOnStack[0], callFrame.functionName);
var callbackInvoked = false;
this._checkSourceFrameWhenLoaded(expectations, function() {
callbackInvoked = true;
if (test.controlTaken_)
test.releaseControl();
});
if (!callbackInvoked) {
test.takeControl();
}
return;
}

this._waitForScriptPause(
{
functionsOnStack: ["callDebugger"],
lineNumber: 8,
lineText: "  debugger;"
},
function() {
test.releaseControl();
});
this.takeControl();
};




TestSuite.prototype.testPauseWhenScriptIsRunning = function()
{
this.showPanel("scripts");
var test = this;

test.evaluateInConsole_(
'setTimeout("handleClick()" , 0)',
function(resultText) {
test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);
testScriptPauseAfterDelay();
});



function testScriptPauseAfterDelay() {
setTimeout(testScriptPause, 300);
}

function testScriptPause() {


WebInspector.panels.scripts.pauseButton.click();

test._waitForScriptPause(
{
functionsOnStack: ["handleClick", ""],
lineNumber: 5,
lineText: "  while(true) {"
},
function() {
test.releaseControl();
});
}

this.takeControl();
};



TestSuite.prototype.optionsToString_ = function(options)
{
var names = [];
for (var i = 0; i < options.length; i++)
names.push('"' + options[i].text + '"');
return names.join(",");
};



TestSuite.prototype.showMainPageScriptSource_ = function(scriptName, callback)
{
var test = this;

var scriptSelect = document.getElementById("scripts-files");
var options = scriptSelect.options;

test.assertTrue(options.length, "Scripts list is empty");


var scriptResource;
if (options[scriptSelect.selectedIndex].text === scriptName)
scriptResource = options[scriptSelect.selectedIndex].representedObject;
else {
var pageScriptIndex = -1;
for (var i = 0; i < options.length; i++) {
if (options[i].text === scriptName) {
pageScriptIndex = i;
break;
}
}
test.assertTrue(-1 !== pageScriptIndex, "Script with url " + scriptName + " not found among " + test.optionsToString_(options));
scriptResource = options[pageScriptIndex].representedObject;


WebInspector.currentPanel._showScriptOrResource(scriptResource);
test.assertEquals(pageScriptIndex, scriptSelect.selectedIndex, "Unexpected selected option index.");
}

test.assertTrue(scriptResource instanceof WebInspector.Resource,
"Unexpected resource class.");
test.assertTrue(!!scriptResource.url, "Resource URL is null.");
test.assertTrue(scriptResource.url.search(scriptName + "$") !== -1, "Main HTML resource should be selected.");

var scriptsPanel = WebInspector.panels.scripts;

var view = scriptsPanel.visibleView;
test.assertTrue(view instanceof WebInspector.SourceView);

if (!view.sourceFrame._loaded) {
test.addSniffer(view, "_sourceFrameSetupFinished", function(event) {
callback(view, scriptResource.url);
});
} else
callback(view, scriptResource.url);
};



TestSuite.prototype.evaluateInConsole_ = function(code, callback)
{
WebInspector.showConsole();
WebInspector.console.prompt.text = code;
WebInspector.console.promptElement.dispatchEvent( TestSuite.createKeyEvent("Enter"));

this.addSniffer(WebInspector.ConsoleView.prototype, "addMessage",
function(commandResult) {
callback(commandResult.toMessageElement().textContent);
});
};



TestSuite.prototype.testCompletionOnPause = function()
{
this.showPanel("scripts");
var test = this;
this._executeCodeWhenScriptsAreParsed("handleClick()", ["completion_on_pause.html"]);

this._waitForScriptPause(
{
functionsOnStack: ["innerFunction", "handleClick", ""],
lineNumber: 9,
lineText: "    debugger;"
},
showConsole);

function showConsole() {
if (WebInspector.currentFocusElement === WebInspector.console.promptElement)
testLocalsCompletion();
else {
test.addSniffer(WebInspector.console, "afterShow", testLocalsCompletion);
WebInspector.showConsole();
}
}

function testLocalsCompletion() {
checkCompletions("th", ["parameter1", "closureLocal", "p", "createClosureLocal"], testThisCompletion);
}

function testThisCompletion() {
checkCompletions("this.", ["field1", "field2", "m"], testFieldCompletion);
}

function testFieldCompletion() {
checkCompletions("this.field1.", ["id", "name"], function() { test.releaseControl(); });
}

function checkCompletions(expression, expectedProperties, callback) {
test.addSniffer(WebInspector.console, "_reportCompletions",
function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result, isException) {
test.assertTrue(!isException, "Exception while collecting completions");
for (var i = 0; i < expectedProperties.length; i++) {
var name = expectedProperties[i];
test.assertTrue(result[name], "Name " + name + " not found among the completions: " + JSON.stringify(result));
}
setTimeout(callback, 0);
});
WebInspector.console.prompt.text = expression;
WebInspector.console.prompt.autoCompleteSoon();
}

this.takeControl();
};



TestSuite.prototype._checkExecutionLine = function(sourceFrame, lineNumber, lineContent)
{
this.assertEquals(lineNumber, sourceFrame.executionLine, "Unexpected execution line number.");
this.assertEquals(lineContent, sourceFrame._textModel.line(lineNumber - 1), "Unexpected execution line text.");
}



TestSuite.prototype._scriptsAreParsed = function(expected)
{
var scriptSelect = document.getElementById("scripts-files");
var options = scriptSelect.options;


var missing = expected.slice(0);
for (var i = 0 ; i < options.length; i++) {
for (var j = 0; j < missing.length; j++) {
if (options[i].text.search(missing[j]) !== -1) {
missing.splice(j, 1);
break;
}
}
}
return missing.length === 0;
};



TestSuite.prototype._waitForScriptPause = function(expectations, callback)
{
var test = this;

test.addSniffer(
WebInspector,
"pausedScript",
function(details) {
var callFrames = details.callFrames;
var functionsOnStack = [];
for (var i = 0; i < callFrames.length; i++)
functionsOnStack.push(callFrames[i].functionName);

test.assertEquals(expectations.functionsOnStack.join(","), functionsOnStack.join(","), "Unexpected stack.");



test._checkSourceFrameWhenLoaded(expectations, callback);
});
};



TestSuite.prototype._checkSourceFrameWhenLoaded = function(expectations, callback)
{
var test = this;

var frame = WebInspector.currentPanel.visibleView.sourceFrame;
if (frame._loaded)
checkExecLine();
else {
setTimeout(function() {
test._checkSourceFrameWhenLoaded(expectations, callback);
}, 100);
}
function checkExecLine() {
test._checkExecutionLine(frame, expectations.lineNumber, expectations.lineText);
callback();
}
};



TestSuite.prototype._executeCodeWhenScriptsAreParsed = function(code, expectedScripts)
{
var test = this;

function executeFunctionInInspectedPage() {


test.evaluateInConsole_(
'setTimeout("' + code + '" , 0)',
function(resultText) {
test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText + ". Code: " + code);
});
}

test._waitUntilScriptsAreParsed(expectedScripts, executeFunctionInInspectedPage);
};



TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, callback)
{
var test = this;

function waitForAllScripts() {
if (test._scriptsAreParsed(expectedScripts))
callback();
else
test.addSniffer(WebInspector, "parsedScriptSource", waitForAllScripts);
}

waitForAllScripts();
};



TestSuite.prototype._hookGetPropertiesCallback = function(hook, code)
{
var accessor = InjectedScriptAccess.prototype;
var orig = accessor.getProperties;
accessor.getProperties = function(objectProxy, ignoreHasOwnProperty, abbreviate, callback) {
orig.call(this, objectProxy, ignoreHasOwnProperty, abbreviate,
function() {
callback.apply(this, arguments);
hook();
});
};
try {
code();
} finally {
accessor.getProperties = orig;
}
};



TestSuite.prototype.testPauseInEval = function()
{
this.showPanel("scripts");

var test = this;

var pauseButton = document.getElementById("scripts-pause");
pauseButton.click();

devtools.tools.evaluateJavaScript("fib(10)");

this.addSniffer(WebInspector, "pausedScript",
function() {
test.releaseControl();
});

test.takeControl();
};



TestSuite.createKeyEvent = function(keyIdentifier)
{
var evt = document.createEvent("KeyboardEvent");
evt.initKeyboardEvent("keydown", true  , true  , null  , keyIdentifier, "");
return evt;
};



var uiTests = {};



uiTests.runAllTests = function()
{

for (var name in TestSuite.prototype) {
if (name.substring(0, 4) === "test" && typeof TestSuite.prototype[name] === "function")
uiTests.runTest(name);
}
};



uiTests.runTest = function(name)
{
if (uiTests._populatedInterface)
new TestSuite().runTest(name);
else
uiTests._pendingTestName = name;
};

(function() {

function runTests()
{
uiTests._populatedInterface = true;
var name = uiTests._pendingTestName;
delete uiTests._pendingTestName;
if (name)
new TestSuite().runTest(name);
}

var oldShowElementsPanel = WebInspector.showElementsPanel;
WebInspector.showElementsPanel = function()
{
oldShowElementsPanel.call(this);
runTests();
}

var oldShowPanel = WebInspector.showPanel;
WebInspector.showPanel = function(name)
{
oldShowPanel.call(this, name);
runTests();
}

})();

}

