




Object.isEmpty = function(obj)
{
for (var i in obj)
return false;
return true;
}

Object.values = function(obj)
{
var keys = Object.keys(obj);
var result = [];

for (var i = 0; i < keys.length; ++i)
result.push(obj[keys[i]]);
return result;
}

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

String.prototype.findAll = function(string)
{
var matches = [];
var i = this.indexOf(string);
while (i !== -1) {
matches.push(i);
i = this.indexOf(string, i + string.length);
}
return matches;
}

String.prototype.lineEndings = function()
{
if (!this._lineEndings) {
this._lineEndings = this.findAll("\n");
this._lineEndings.push(this.length);
}
return this._lineEndings;
}

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 String(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.regexSpecialCharacters = function()
{
return "^[]{}()\\.$*+?|-,";
}

String.prototype.escapeForRegExp = function()
{
return this.escapeCharacters(String.regexSpecialCharacters);
}

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.trimMiddle = function(maxLength)
{
if (this.length <= maxLength)
return String(this);
var leftHalf = maxLength >> 1;
var rightHalf = maxLength - leftHalf - 1;
return this.substr(0, leftHalf) + "\u2026" + this.substr(this.length - rightHalf, rightHalf);
}

String.prototype.trimEnd = function(maxLength)
{
if (this.length <= maxLength)
return String(this);
return this.substr(0, maxLength - 1) + "\u2026";
}

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;
}

String.prototype.toTitleCase = function()
{
return this.substring(0, 1).toUpperCase() + this.substring(1);
}


String.prototype.compareTo = function(other)
{
if (this > other)
return 1;
if (this < other)
return -1;
return 0;
}


function sanitizeHref(href)
{
return href && href.trim().toLowerCase().startsWith("javascript:") ? "" : href;
}

String.prototype.removeURLFragment = function()
{
var fragmentIndex = this.indexOf("#");
if (fragmentIndex == -1)
fragmentIndex = this.length;
return this.substring(0, fragmentIndex);
}

String.prototype.startsWith = function(substring)
{
return !this.lastIndexOf(substring, 0);
}

String.prototype.endsWith = function(substring)
{
return this.indexOf(substring, this.length - substring.length) !== -1;
}

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

Date.prototype.toISO8601Compact = function()
{
function leadZero(x)
{
return x > 9 ? '' + x : '0' + x
}
return this.getFullYear() +
leadZero(this.getMonth() + 1) +
leadZero(this.getDate()) + 'T' +
leadZero(this.getHours()) +
leadZero(this.getMinutes()) +
leadZero(this.getSeconds());
}

Object.defineProperty(Array.prototype, "remove",
{

value: 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);
}
}
});

Object.defineProperty(Array.prototype, "keySet",
{

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

Object.defineProperty(Array.prototype, "upperBound",
{

value: function(value)
{
var first = 0;
var count = this.length;
while (count > 0) {
var step = count >> 1;
var middle = first + step;
if (value >= this[middle]) {
first = middle + 1;
count -= step + 1;
} else
count = step;
}
return first;
}
});

Object.defineProperty(Array.prototype, "rotate",
{

value: function(index)
{
var result = [];
for (var i = index; i < index + this.length; ++i)
result.push(this[i % this.length]);
return result;
}
});

Object.defineProperty(Uint32Array.prototype, "sort", {
value: Array.prototype.sort
});

(function() {
var partition = {

value: function(comparator, left, right, pivotIndex)
{
function swap(array, i1, i2)
{
var temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
}

var pivotValue = this[pivotIndex];
swap(this, right, pivotIndex);
var storeIndex = left;
for (var i = left; i < right; ++i) {
if (comparator(this[i], pivotValue) < 0) {
swap(this, storeIndex, i);
++storeIndex;
}
}
swap(this, right, storeIndex);
return storeIndex;
}
};
Object.defineProperty(Array.prototype, "partition", partition);
Object.defineProperty(Uint32Array.prototype, "partition", partition);

var sortRange = {

value: function(comparator, leftBound, rightBound, k)
{
function quickSortFirstK(array, comparator, left, right, k)
{
if (right <= left)
return;
var pivotIndex = Math.floor(Math.random() * (right - left)) + left;
var pivotNewIndex = array.partition(comparator, left, right, pivotIndex);
quickSortFirstK(array, comparator, left, pivotNewIndex - 1, k);
if (pivotNewIndex < left + k - 1)
quickSortFirstK(array, comparator, pivotNewIndex + 1, right, left + k - 1 - pivotNewIndex);
}

if (leftBound === 0 && rightBound === (this.length - 1) && k >= this.length)
this.sort(comparator);
else
quickSortFirstK(this, comparator, leftBound, rightBound, k);
return this;
}
}
Object.defineProperty(Array.prototype, "sortRange", sortRange);
Object.defineProperty(Uint32Array.prototype, "sortRange", sortRange);
})();

Object.defineProperty(Array.prototype, "qselect",
{

value: function(k, comparator)
{
if (k < 0 || k >= this.length)
return;
if (!comparator)
comparator = function(a, b) { return a - b; }

var low = 0;
var high = this.length - 1;
for (;;) {
var pivotPosition = this.partition(comparator, low, high, Math.floor((high + low) / 2));
if (pivotPosition === k)
return this[k];
else if (pivotPosition > k)
high = pivotPosition - 1;
else
low = pivotPosition + 1;
}
}
});


function binarySearch(object, array, comparator)
{
var first = 0;
var last = array.length - 1;

while (first <= last) {
var mid = (first + last) >> 1;
var c = comparator(object, array[mid]);
if (c > 0)
first = mid + 1;
else if (c < 0)
last = mid - 1;
else
return mid;
}


return -(first + 1);
}

Object.defineProperty(Array.prototype, "binaryIndexOf",
{

value: function(value, comparator)
{
var result = binarySearch(value, this, comparator);
return result >= 0 ? result : -1;
}
});

Object.defineProperty(Array.prototype, "select",
{

value: function(field)
{
var result = new Array(this.length);
for (var i = 0; i < this.length; ++i)
result[i] = this[i][field];
return result;
}
});

Object.defineProperty(Array.prototype, "peekLast",
{

value: function()
{
return this[this.length - 1];
}
});


function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction)
{
var index = binarySearch(anObject, aList, aFunction);
if (index < 0)

return -index - 1;
else {

while (index > 0 && aFunction(anObject, aList[index - 1]) === 0)
index--;
return index;
}
}


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

String.tokenizeFormatString = function(format, formatters)
{
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 });
}

function isDigit(c)
{
return !!/[0-9]/.exec(c);
}

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

if (isDigit(format[index])) {

var number = parseInt(format.substring(index), 10);
while (isDigit(format[index]))
++index;



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

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


++index;
precision = parseInt(format.substring(index), 10);
if (isNaN(precision))
precision = 0;

while (isDigit(format[index]))
++index;
}

if (!(format[index] in formatters)) {
addStringToken(format.substring(precentIndex, index + 1));
++index;
continue;
}

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

++substitutionIndex;
++index;
}

addStringToken(format.substring(index));

return tokens;
}

String.standardFormatters = {
d: function(substitution)
{
return !isNaN(substitution) ? substitution : 0;
},

f: function(substitution, token)
{
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)
{
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, formatters);
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 createSearchRegex(query, caseSensitive, isRegex)
{
var regexFlags = caseSensitive ? "g" : "gi";
var regexObject;

if (isRegex) {
try {
regexObject = new RegExp(query, regexFlags);
} catch (e) {

}
}

if (!regexObject)
regexObject = createPlainTextSearchRegex(query, regexFlags);

return regexObject;
}


function createPlainTextSearchRegex(query, flags)
{

var regexSpecialCharacters = String.regexSpecialCharacters();
var regex = "";
for (var i = 0; i < query.length; ++i) {
var c = query.charAt(i);
if (regexSpecialCharacters.indexOf(c) != -1)
regex += "\\";
regex += c;
}
return new RegExp(regex, flags || "");
}


function countRegexMatches(regex, content)
{
var text = content;
var result = 0;
var match;
while (text && (match = regex.exec(text))) {
if (match[0].length > 0)
++result;
text = text.substring(match.index + 1);
}
return result;
}


function numberToStringWithSpacesPadding(value, symbolsCount)
{
var numberString = value.toString();
var paddingLength = Math.max(0, symbolsCount - numberString.length);
var paddingString = Array(paddingLength + 1).join("\u00a0");
return paddingString + numberString;
}


var createObjectIdentifier = function()
{

return '_' + ++createObjectIdentifier._last;
}

createObjectIdentifier._last = 0;


var Set = function()
{

this._set = {};
this._size = 0;
}

Set.prototype = {

add: function(item)
{
var objectIdentifier = item.__identifier;
if (!objectIdentifier) {
objectIdentifier = createObjectIdentifier();
item.__identifier = objectIdentifier;
}
if (!this._set[objectIdentifier])
++this._size;
this._set[objectIdentifier] = item;
},


remove: function(item)
{
if (this._set[item.__identifier]) {
--this._size;
delete this._set[item.__identifier];
return true;
}
return false;
},


items: function()
{
var result = new Array(this._size);
var i = 0;
for (var objectIdentifier in this._set)
result[i++] = this._set[objectIdentifier];
return result;
},


hasItem: function(item)
{
return !!this._set[item.__identifier];
},


size: function()
{
return this._size;
},

clear: function()
{
this._set = {};
this._size = 0;
}
}


var Map = function()
{
this._map = {};
this._size = 0;
}

Map.prototype = {

put: function(key, value)
{
var objectIdentifier = key.__identifier;
if (!objectIdentifier) {
objectIdentifier = createObjectIdentifier();
key.__identifier = objectIdentifier;
}
if (!this._map[objectIdentifier])
++this._size;
this._map[objectIdentifier] = [key, value];
},


remove: function(key)
{
var result = this._map[key.__identifier];
if (!result)
return undefined;
--this._size;
delete this._map[key.__identifier];
return result[1];
},


keys: function()
{
return this._list(0);
},


values: function()
{
return this._list(1);
},


_list: function(index)
{
var result = new Array(this._size);
var i = 0;
for (var objectIdentifier in this._map)
result[i++] = this._map[objectIdentifier][index];
return result;
},


get: function(key)
{
var entry = this._map[key.__identifier];
return entry ? entry[1] : undefined;
},


contains: function(key)
{
var entry = this._map[key.__identifier];
return !!entry;
},


size: function()
{
return this._size;
},

clear: function()
{
this._map = {};
this._size = 0;
}
}


var StringMap = function()
{
this._map = {};
this._size = 0;
}

StringMap.prototype = {

put: function(key, value)
{
if (key === "__proto__") {
if (!this._hasProtoKey) {
++this._size;
this._hasProtoKey = true;
}
this._protoValue = value;
return;
}
if (!Object.prototype.hasOwnProperty.call(this._map, key))
++this._size;
this._map[key] = value;
},


remove: function(key)
{
var result;
if (key === "__proto__") {
if (!this._hasProtoKey)
return undefined;
--this._size;
delete this._hasProtoKey;
result = this._protoValue;
delete this._protoValue;
return result;
}
if (!Object.prototype.hasOwnProperty.call(this._map, key))
return undefined;
--this._size;
result = this._map[key];
delete this._map[key];
return result;
},


keys: function()
{
var result = Object.keys(this._map);
if (this._hasProtoKey)
result.push("__proto__");
return result;
},


values: function()
{
var result = Object.values(this._map);
if (this._hasProtoKey)
result.push(this._protoValue);
return result;
},


get: function(key)
{
if (key === "__proto__")
return this._protoValue;
if (!Object.prototype.hasOwnProperty.call(this._map, key))
return undefined;
return this._map[key];
},


contains: function(key)
{
var result;
if (key === "__proto__")
return this._hasProtoKey;
return Object.prototype.hasOwnProperty.call(this._map, key);
},


size: function()
{
return this._size;
},

clear: function()
{
this._map = {};
this._size = 0;
delete this._hasProtoKey;
delete this._protoValue;
}
}


function loadXHR(url, async, callback) 
{
function onReadyStateChanged() 
{
if (xhr.readyState !== XMLHttpRequest.DONE)
return;

if (xhr.status === 200) {
callback(xhr.responseText);
return;
}

callback(null); 
}

var xhr = new XMLHttpRequest();
xhr.open("GET", url, async);
if (async)
xhr.onreadystatechange = onReadyStateChanged;        
xhr.send(null);

if (!async) {
if (xhr.status === 200) 
return xhr.responseText;
return null;
}
return null;
}


function StringPool()
{
this.reset();
}

StringPool.prototype = {

intern: function(string)
{

if (string === "__proto__")
return "__proto__";
var result = this._strings[string];
if (result === undefined) {
this._strings[string] = string;
result = string;
}
return result;
},

reset: function()
{
this._strings = Object.create(null);
},


internObjectStrings: function(obj, depthLimit)
{
if (typeof depthLimit !== "number")
depthLimit = 100;
else if (--depthLimit < 0)
throw "recursion depth limit reached in StringPool.deepIntern(), perhaps attempting to traverse cyclical references?";

for (var field in obj) {
switch (typeof obj[field]) {
case "string":
obj[field] = this.intern(obj[field]);
break;
case "object":
this.internObjectStrings(obj[field], depthLimit);
break;
}
}
}
}

var _importedScripts = {};


function importScript(scriptName)
{
if (_importedScripts[scriptName])
return;
var xhr = new XMLHttpRequest();
_importedScripts[scriptName] = true;
if (window.flattenImports)
scriptName = scriptName.split("/").reverse()[0];
xhr.open("GET", scriptName, false);
xhr.send(null);
if (!xhr.responseText)
throw "empty response arrived for script '" + scriptName + "'";
var sourceURL = WebInspector.ParsedURL.completeURL(window.location.href, scriptName); 
window.eval(xhr.responseText + "\n//@ sourceURL=" + sourceURL);
}

var loadScript = importScript;


function CallbackBarrier()
{
this._pendingIncomingCallbacksCount = 0;
}

CallbackBarrier.prototype = {

createCallback: function(userCallback)
{
console.assert(!this._outgoingCallback, "CallbackBarrier.createCallback() is called after CallbackBarrier.callWhenDone()");
++this._pendingIncomingCallbacksCount;
return this._incomingCallback.bind(this, userCallback);
},


callWhenDone: function(callback)
{
console.assert(!this._outgoingCallback, "CallbackBarrier.callWhenDone() is called multiple times");
this._outgoingCallback = callback;
if (!this._pendingIncomingCallbacksCount)
this._outgoingCallback();
},

_incomingCallback: function(userCallback)
{
console.assert(this._pendingIncomingCallbacksCount > 0);
if (userCallback) {
var args = Array.prototype.slice.call(arguments, 1);
userCallback.apply(null, args);
}
if (!--this._pendingIncomingCallbacksCount && this._outgoingCallback)
this._outgoingCallback();
}
}








__whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true};

difflib = {
defaultJunkFunction: function (c) {
return __whitespace.hasOwnProperty(c);
},

stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); },

stringAsLines: function (str) {
var lfpos = str.indexOf("\n");
var crpos = str.indexOf("\r");
var linebreak = ((lfpos > -1 && crpos > -1) || crpos < 0) ? "\n" : "\r";

var lines = str.split(linebreak);
for (var i = 0; i < lines.length; i++) {
lines[i] = difflib.stripLinebreaks(lines[i]);
}

return lines;
},


__reduce: function (func, list, initial) {
if (initial != null) {
var value = initial;
var idx = 0;
} else if (list) {
var value = list[0];
var idx = 1;
} else {
return null;
}

for (; idx < list.length; idx++) {
value = func(value, list[idx]);
}

return value;
},


__ntuplecomp: function (a, b) {
var mlen = Math.max(a.length, b.length);
for (var i = 0; i < mlen; i++) {
if (a[i] < b[i]) return -1;
if (a[i] > b[i]) return 1;
}

return a.length == b.length ? 0 : (a.length < b.length ? -1 : 1);
},

__calculate_ratio: function (matches, length) {
return length ? 2.0 * matches / length : 1.0;
},




__isindict: function (dict) {
return function (key) { return dict.hasOwnProperty(key); };
},


__dictget: function (dict, key, defaultValue) {
return dict.hasOwnProperty(key) ? dict[key] : defaultValue;
},  

SequenceMatcher: function (a, b, isjunk) {
this.set_seqs = function (a, b) {
this.set_seq1(a);
this.set_seq2(b);
}

this.set_seq1 = function (a) {
if (a == this.a) return;
this.a = a;
this.matching_blocks = this.opcodes = null;
}

this.set_seq2 = function (b) {
if (b == this.b) return;
this.b = b;
this.matching_blocks = this.opcodes = this.fullbcount = null;
this.__chain_b();
}

this.__chain_b = function () {
var b = this.b;
var n = b.length;
var b2j = this.b2j = {};
var populardict = {};
for (var i = 0; i < b.length; i++) {
var elt = b[i];
if (b2j.hasOwnProperty(elt)) {
var indices = b2j[elt];
if (n >= 200 && indices.length * 100 > n) {
populardict[elt] = 1;
delete b2j[elt];
} else {
indices.push(i);
}
} else {
b2j[elt] = [i];
}
}

for (var elt in populardict) {
if (populardict.hasOwnProperty(elt)) {
delete b2j[elt];
}
}

var isjunk = this.isjunk;
var junkdict = {};
if (isjunk) {
for (var elt in populardict) {
if (populardict.hasOwnProperty(elt) && isjunk(elt)) {
junkdict[elt] = 1;
delete populardict[elt];
}
}
for (var elt in b2j) {
if (b2j.hasOwnProperty(elt) && isjunk(elt)) {
junkdict[elt] = 1;
delete b2j[elt];
}
}
}

this.isbjunk = difflib.__isindict(junkdict);
this.isbpopular = difflib.__isindict(populardict);
}

this.find_longest_match = function (alo, ahi, blo, bhi) {
var a = this.a;
var b = this.b;
var b2j = this.b2j;
var isbjunk = this.isbjunk;
var besti = alo;
var bestj = blo;
var bestsize = 0;
var j = null;

var j2len = {};
var nothing = [];
for (var i = alo; i < ahi; i++) {
var newj2len = {};
var jdict = difflib.__dictget(b2j, a[i], nothing);
for (var jkey in jdict) {
if (jdict.hasOwnProperty(jkey)) {
j = jdict[jkey];
if (j < blo) continue;
if (j >= bhi) break;
newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1;
if (k > bestsize) {
besti = i - k + 1;
bestj = j - k + 1;
bestsize = k;
}
}
}
j2len = newj2len;
}

while (besti > alo && bestj > blo && !isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
besti--;
bestj--;
bestsize++;
}

while (besti + bestsize < ahi && bestj + bestsize < bhi &&
!isbjunk(b[bestj + bestsize]) &&
a[besti + bestsize] == b[bestj + bestsize]) {
bestsize++;
}

while (besti > alo && bestj > blo && isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
besti--;
bestj--;
bestsize++;
}

while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) &&
a[besti + bestsize] == b[bestj + bestsize]) {
bestsize++;
}

return [besti, bestj, bestsize];
}

this.get_matching_blocks = function () {
if (this.matching_blocks != null) return this.matching_blocks;
var la = this.a.length;
var lb = this.b.length;

var queue = [[0, la, 0, lb]];
var matching_blocks = [];
var alo, ahi, blo, bhi, qi, i, j, k, x;
while (queue.length) {
qi = queue.pop();
alo = qi[0];
ahi = qi[1];
blo = qi[2];
bhi = qi[3];
x = this.find_longest_match(alo, ahi, blo, bhi);
i = x[0];
j = x[1];
k = x[2];

if (k) {
matching_blocks.push(x);
if (alo < i && blo < j)
queue.push([alo, i, blo, j]);
if (i+k < ahi && j+k < bhi)
queue.push([i + k, ahi, j + k, bhi]);
}
}

matching_blocks.sort(difflib.__ntuplecomp);

var i1 = j1 = k1 = block = 0;
var non_adjacent = [];
for (var idx in matching_blocks) {
if (matching_blocks.hasOwnProperty(idx)) {
block = matching_blocks[idx];
i2 = block[0];
j2 = block[1];
k2 = block[2];
if (i1 + k1 == i2 && j1 + k1 == j2) {
k1 += k2;
} else {
if (k1) non_adjacent.push([i1, j1, k1]);
i1 = i2;
j1 = j2;
k1 = k2;
}
}
}

if (k1) non_adjacent.push([i1, j1, k1]);

non_adjacent.push([la, lb, 0]);
this.matching_blocks = non_adjacent;
return this.matching_blocks;
}

this.get_opcodes = function () {
if (this.opcodes != null) return this.opcodes;
var i = 0;
var j = 0;
var answer = [];
this.opcodes = answer;
var block, ai, bj, size, tag;
var blocks = this.get_matching_blocks();
for (var idx in blocks) {
if (blocks.hasOwnProperty(idx)) {
block = blocks[idx];
ai = block[0];
bj = block[1];
size = block[2];
tag = '';
if (i < ai && j < bj) {
tag = 'replace';
} else if (i < ai) {
tag = 'delete';
} else if (j < bj) {
tag = 'insert';
}
if (tag) answer.push([tag, i, ai, j, bj]);
i = ai + size;
j = bj + size;

if (size) answer.push(['equal', ai, i, bj, j]);
}
}

return answer;
}



this.get_grouped_opcodes = function (n) {
if (!n) n = 3;
var codes = this.get_opcodes();
if (!codes) codes = [["equal", 0, 1, 0, 1]];
var code, tag, i1, i2, j1, j2;
if (codes[0][0] == 'equal') {
code = codes[0];
tag = code[0];
i1 = code[1];
i2 = code[2];
j1 = code[3];
j2 = code[4];
codes[0] = [tag, Math.max(i1, i2 - n), i2, Math.max(j1, j2 - n), j2];
}
if (codes[codes.length - 1][0] == 'equal') {
code = codes[codes.length - 1];
tag = code[0];
i1 = code[1];
i2 = code[2];
j1 = code[3];
j2 = code[4];
codes[codes.length - 1] = [tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)];
}

var nn = n + n;
var groups = [];
for (var idx in codes) {
if (codes.hasOwnProperty(idx)) {
code = codes[idx];
tag = code[0];
i1 = code[1];
i2 = code[2];
j1 = code[3];
j2 = code[4];
if (tag == 'equal' && i2 - i1 > nn) {
groups.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]);
i1 = Math.max(i1, i2-n);
j1 = Math.max(j1, j2-n);
}

groups.push([tag, i1, i2, j1, j2]);
}
}

if (groups && groups[groups.length - 1][0] == 'equal') groups.pop();

return groups;
}

this.ratio = function () {
matches = difflib.__reduce(
function (sum, triple) { return sum + triple[triple.length - 1]; },
this.get_matching_blocks(), 0);
return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
}

this.quick_ratio = function () {
var fullbcount, elt;
if (this.fullbcount == null) {
this.fullbcount = fullbcount = {};
for (var i = 0; i < this.b.length; i++) {
elt = this.b[i];
fullbcount[elt] = difflib.__dictget(fullbcount, elt, 0) + 1;
}
}
fullbcount = this.fullbcount;

var avail = {};
var availhas = difflib.__isindict(avail);
var matches = numb = 0;
for (var i = 0; i < this.a.length; i++) {
elt = this.a[i];
if (availhas(elt)) {
numb = avail[elt];
} else {
numb = difflib.__dictget(fullbcount, elt, 0);
}
avail[elt] = numb - 1;
if (numb > 0) matches++;
}

return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
}

this.real_quick_ratio = function () {
var la = this.a.length;
var lb = this.b.length;
return _calculate_ratio(Math.min(la, lb), la + lb);
}

this.isjunk = isjunk ? isjunk : difflib.defaultJunkFunction;
this.a = this.b = null;
this.set_seqs(a, b);
}
}






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)
{
this.classList.remove(className);
}

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)
{
this.classList.add(className);
}


Element.prototype.hasStyleClass = function(className)
{
return this.classList.contains(className);
}


Element.prototype.enableStyleClass = function(className, enable)
{
if (enable)
this.addStyleClass(className);
else
this.removeStyleClass(className);
}


Element.prototype.positionAt = function(x, y)
{
if (typeof x === "number")
this.style.setProperty("left", x + "px");
else
this.style.removeProperty("left");

if (typeof y === "number")
this.style.setProperty("top", y + "px");
else
this.style.removeProperty("top");
}

Element.prototype.isScrolledToBottom = function()
{

return this.scrollTop + this.clientHeight === this.scrollHeight;
}

Element.prototype.removeSelf = function()
{
if (this.parentElement)
this.parentElement.removeChild(this);
}

CharacterData.prototype.removeSelf = Element.prototype.removeSelf;
DocumentType.prototype.removeSelf = Element.prototype.removeSelf;


function removeSubsequentNodes(fromNode, toNode)
{
for (var node = fromNode; node && node !== toNode; ) {
var nodeToRemove = node;
node = node.nextSibling;
nodeToRemove.removeSelf();
}
}


function Size(width, height)
{
this.width = width;
this.height = height;
}


Element.prototype.measurePreferredSize = function(containerElement)
{
containerElement = containerElement || document.body;
containerElement.appendChild(this);
this.positionAt(0, 0);
var result = new Size(this.offsetWidth, this.offsetHeight);
this.positionAt(undefined, undefined);
this.removeSelf();
return result;
}

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, stayWithin)
{
for (var node = this; node && node !== stayWithin && node !== this.ownerDocument; node = node.parentNode)
if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className))
return node;
return null;
}

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.isSelfOrDescendant(this);
}


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

DocumentFragment.prototype.createChild = Element.prototype.createChild;


Element.prototype.createTextChild = function(text)
{
var element = this.ownerDocument.createTextNode(text);
this.appendChild(element);
return element;
}

DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild;


Element.prototype.totalOffsetLeft = function()
{
return this.totalOffset().left;
}


Element.prototype.totalOffsetTop = function()
{
return this.totalOffset().top;

}

Element.prototype.totalOffset = function()
{
var totalLeft = 0;
var totalTop = 0;

for (var element = this; element; element = element.offsetParent) {
totalLeft += element.offsetLeft;
totalTop += element.offsetTop;
if (this !== element) {
totalLeft += element.clientLeft - element.scrollLeft;
totalTop += element.clientTop - element.scrollTop;
}
}

return { left: totalLeft, top: totalTop };
}

Element.prototype.scrollOffset = function()
{
var curLeft = 0;
var curTop = 0;
for (var element = this; element; element = element.scrollParent) {
curLeft += element.scrollLeft;
curTop += element.scrollTop;
}
return { left: curLeft, top: curTop };
}


function AnchorBox(x, y, width, height)
{
this.x = x || 0;
this.y = y || 0;
this.width = width || 0;
this.height = height || 0;
}


Element.prototype.offsetRelativeToWindow = function(targetWindow)
{
var elementOffset = new AnchorBox();
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;
}


Element.prototype.boxInWindow = function(targetWindow)
{
targetWindow = targetWindow || this.ownerDocument.defaultView;

var anchorBox = this.offsetRelativeToWindow(window);
anchorBox.width = Math.min(this.offsetWidth, window.innerWidth - anchorBox.x);
anchorBox.height = Math.min(this.offsetHeight, window.innerHeight - anchorBox.y);

return anchorBox;
}


Element.prototype.setTextAndTitle = function(text)
{
this.textContent = text;
this.title = text;
}

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 "";
}
});


Event.prototype.consume = function(preventDefault)
{
this.stopImmediatePropagation();
if (preventDefault)
this.preventDefault();
this.handled = true;
}

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

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

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

Element.prototype.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.isAncestor = function(node)
{
if (!node)
return false;

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

Node.prototype.isDescendant = function(descendant)
{
return !!descendant && descendant.isAncestor(this);
}

Node.prototype.isSelfOrAncestor = function(node)
{
return !!node && (node === this || this.isAncestor(node));
}

Node.prototype.isSelfOrDescendant = function(node)
{
return !!node && (node === this || this.isDescendant(node));
}

Node.prototype.traverseNextNode = function(stayWithin)
{
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;
}

Node.prototype.traversePreviousNode = function(stayWithin)
{
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 isEnterKey(event) {

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

function consumeEvent(e)
{
e.consume();
}


function NonLeakingMutationObserver(handler)
{
this._observer = new WebKitMutationObserver(handler);
NonLeakingMutationObserver._instances.push(this);
if (!NonLeakingMutationObserver._unloadListener) {
NonLeakingMutationObserver._unloadListener = function() {
while (NonLeakingMutationObserver._instances.length)
NonLeakingMutationObserver._instances[NonLeakingMutationObserver._instances.length - 1].disconnect();
};
window.addEventListener("unload", NonLeakingMutationObserver._unloadListener, false);
}
}

NonLeakingMutationObserver._instances = [];

NonLeakingMutationObserver.prototype = {

observe: function(element, config)
{
if (this._observer)
this._observer.observe(element, config);
},

disconnect: function()
{
if (this._observer)
this._observer.disconnect();
NonLeakingMutationObserver._instances.remove(this);
delete this._observer;
}
}







function TreeOutline(listNode, nonFocusable)
{

this.children = [];
this.selectedTreeElement = null;
this._childrenListNode = listNode;
this.childrenListElement = this._childrenListNode;
this._childrenListNode.removeChildren();
this.expandTreeElementsWhenArrowing = false;
this.root = true;
this.hasChildren = false;
this.expanded = true;
this.selected = false;
this.treeOutline = this;
this.comparator = null;

this.setFocusable(!nonFocusable);
this._childrenListNode.addEventListener("keydown", this._treeKeyDown.bind(this), true);

this._treeElementsMap = new Map();
this._expandedStateMap = new Map();
}

TreeOutline.prototype.setFocusable = function(focusable)
{
if (focusable)
this._childrenListNode.setAttribute("tabIndex", 0);
else
this._childrenListNode.removeAttribute("tabIndex");
}

TreeOutline.prototype.appendChild = function(child)
{
var insertionIndex;
if (this.treeOutline.comparator)
insertionIndex = insertionIndexForObjectInListSortedByFunction(child, this.children, this.treeOutline.comparator);
else
insertionIndex = this.children.length;
this.insertChild(child, insertionIndex);
}

TreeOutline.prototype.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 && typeof(child.treeOutline._expandedStateMap.get(child.representedObject)) !== "undefined")
child.expanded = child.treeOutline._expandedStateMap.get(child.representedObject);

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

child._attach();
}

TreeOutline.prototype.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.prototype.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");

this.removeChildAtIndex.call(this, childIndex);
}

TreeOutline.prototype.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.prototype._rememberTreeElement = function(element)
{
if (!this._treeElementsMap.get(element.representedObject))
this._treeElementsMap.put(element.representedObject, []);


var elements = this._treeElementsMap.get(element.representedObject);
if (elements.indexOf(element) !== -1)
return;


elements.push(element);
}

TreeOutline.prototype._forgetTreeElement = function(element)
{
if (this._treeElementsMap.get(element.representedObject)) {
var elements = this._treeElementsMap.get(element.representedObject);
elements.remove(element, true);
if (!elements.length)
this._treeElementsMap.remove(element.representedObject);
}
}

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

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

var elements = this._treeElementsMap.get(representedObject);
if (elements && elements.length)
return elements[0];
return null;
}

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

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


var ancestors = [];
for (var currentObject = getParent(representedObject); currentObject;  currentObject = getParent(currentObject)) {
ancestors.push(currentObject);
if (this.getCachedTreeElement(currentObject))  
break;
}

if (!currentObject)
return null;


for (var i = ancestors.length - 1; i >= 0; --i) {
var treeElement = this.getCachedTreeElement(ancestors[i]);
if (treeElement)
treeElement.onpopulate();  
}

return this.getCachedTreeElement(representedObject);
}

TreeOutline.prototype.treeElementFromPoint = function(x, y)
{
var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y);
if (!node)
return null;

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;
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.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];
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.nextSibling;
handled = nextSelectedElement ? true : false;
} else {
if (event.altKey)
this.selectedTreeElement.expandRecursively();
else
this.selectedTreeElement.expand();
}
}
} else if (event.keyCode === 8   || event.keyCode === 46  )
handled = this.selectedTreeElement.ondelete();
else if (isEnterKey(event))
handled = this.selectedTreeElement.onenter();
else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
handled = this.selectedTreeElement.onspace();

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

if (handled)
event.consume(true);
}

TreeOutline.prototype.expand = function()
{

}

TreeOutline.prototype.collapse = function()
{

}

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

TreeOutline.prototype.reveal = function()
{

}

TreeOutline.prototype.select = function()
{

}


TreeOutline.prototype.revealAndSelect = function(omitFocus)
{

}


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

this._hidden = false;
this._selectable = true;
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 = {
arrowToggleWidth: 10,

get selectable() {
if (this._hidden)
return false;
return this._selectable;
},

set selectable(x) {
this._selectable = x;
},

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

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

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

set title(x) {
this._title = 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.classList.add("parent");
else {
this._listItemNode.classList.remove("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.classList.add("hidden");
if (this._childrenListNode)
this._childrenListNode.classList.add("hidden");
} else {
if (this._listItemNode)
this._listItemNode.classList.remove("hidden");
if (this._childrenListNode)
this._childrenListNode.classList.remove("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 (typeof this._title === "string")
this._listItemNode.textContent = this._title;
else {
this._listItemNode.removeChildren();
if (this._title)
this._listItemNode.appendChild(this._title);
}
}
}

TreeElement.prototype.appendChild = TreeOutline.prototype.appendChild;
TreeElement.prototype.insertChild = TreeOutline.prototype.insertChild;
TreeElement.prototype.removeChild = TreeOutline.prototype.removeChild;
TreeElement.prototype.removeChildAtIndex = TreeOutline.prototype.removeChildAtIndex;
TreeElement.prototype.removeChildren = TreeOutline.prototype.removeChildren;

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.classList.add("hidden");
if (this.hasChildren)
this._listItemNode.classList.add("parent");
if (this.expanded)
this._listItemNode.classList.add("expanded");
if (this.selected)
this._listItemNode.classList.add("selected");

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

this.onattach();
}

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;

var toggleOnClick = element.treeElement.toggleOnClick && !element.treeElement.selectable;
var isInTriangle = element.treeElement.isEventWithinDisclosureTriangle(event);
if (!toggleOnClick && !isInTriangle)
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.consume();
}

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

var handled = element.treeElement.ondblclick.call(element.treeElement, event);
if (handled)
return;
if (element.treeElement.hasChildren && !element.treeElement.expanded)
element.treeElement.expand();
}

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

this.expanded = false;

if (this.treeOutline)
this.treeOutline._expandedStateMap.put(this.representedObject, false);

this.oncollapse();
}

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;





this.expanded = true;
if (this.treeOutline)
this.treeOutline._expandedStateMap.put(this.representedObject, true);

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.classList.add("children");

if (this.hidden)
this._childrenListNode.classList.add("hidden");

this.onpopulate();

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

delete this._shouldRefreshChildren;
}

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

if (this._childrenListNode)
this._childrenListNode.classList.add("expanded");

this.onexpand();
}

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




if (isNaN(maxDepth))
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;
}

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)
{
if (this.select(false, true))
event.consume(true);
}


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

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

this.selected = true;

if(!omitFocus)
this.treeOutline._childrenListNode.focus();


if (!this.treeOutline)
return false;
this.treeOutline.selectedTreeElement = this;
if (this._listItemNode)
this._listItemNode.classList.add("selected");

return this.onselect(selectedByUser);
}


TreeElement.prototype.revealAndSelect = function(omitFocus)
{
this.reveal();
this.select(omitFocus);
}


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.classList.remove("selected");
return true;
}


TreeElement.prototype.onpopulate = function() { }
TreeElement.prototype.onenter = function() { }
TreeElement.prototype.ondelete = function() { }
TreeElement.prototype.onspace = function() { }
TreeElement.prototype.onattach = function() { }
TreeElement.prototype.onexpand = function() { }
TreeElement.prototype.oncollapse = function() { }
TreeElement.prototype.ondblclick = function() { }
TreeElement.prototype.onreveal = function() { }

TreeElement.prototype.onselect = function(selectedByUser) { }


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

if (info)
info.depthChange = 0;

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

if (this === stayWithin)
return null;

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

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

if (!element)
return null;

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


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

while (element && (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1])) {
if (!dontPopulate && element.hasChildren)
element.onpopulate();
element = (skipUnrevealed ? (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 paddingLeftValue = window.getComputedStyle(this._listItemNode).getPropertyCSSValue("padding-left");
var computedLeftPadding = paddingLeftValue ? paddingLeftValue.getFloatValue(CSSPrimitiveValue.CSS_PX) : 0;
var left = this._listItemNode.totalOffsetLeft() + computedLeftPadding;
return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
}





var WebInspector = {
_panelDescriptors: function()
{
this.panels = {};
WebInspector.inspectorView = new WebInspector.InspectorView();
var parentElement = document.getElementById("main");
WebInspector.inspectorView.show(parentElement);
WebInspector.inspectorView.addEventListener(WebInspector.InspectorView.Events.PanelSelected, this._panelSelected, this);

var elements = new WebInspector.ElementsPanelDescriptor();
var resources = new WebInspector.PanelDescriptor("resources", WebInspector.UIString("Resources"), "ResourcesPanel", "ResourcesPanel.js");
var network = new WebInspector.NetworkPanelDescriptor();
var scripts = new WebInspector.ScriptsPanelDescriptor();
var timeline = new WebInspector.TimelinePanelDescriptor();
var profiles = new WebInspector.ProfilesPanelDescriptor();
var audits = new WebInspector.PanelDescriptor("audits", WebInspector.UIString("Audits"), "AuditsPanel", "AuditsPanel.js");
var console = new WebInspector.PanelDescriptor("console", WebInspector.UIString("Console"), "ConsolePanel");
var allDescriptors = [elements, resources, network, scripts, timeline, profiles, audits, console];
var allProfilers = [profiles];
if (WebInspector.experimentsSettings.customizableToolbar.isEnabled()) {
allProfilers = [];
allProfilers.push(new WebInspector.PanelDescriptor("cpu-profiler", WebInspector.UIString("CPU Profiler"), "CPUProfilerPanel", "ProfilesPanel.js"));
if (!WebInspector.WorkerManager.isWorkerFrontend())
allProfilers.push(new WebInspector.PanelDescriptor("css-profiler", WebInspector.UIString("CSS Profiler"), "CSSSelectorProfilerPanel", "ProfilesPanel.js"));
allProfilers.push(new WebInspector.PanelDescriptor("heap-profiler", WebInspector.UIString("Heap Profiler"), "HeapProfilerPanel", "ProfilesPanel.js"));
if (!WebInspector.WorkerManager.isWorkerFrontend() && WebInspector.experimentsSettings.canvasInspection.isEnabled())
allProfilers.push(new WebInspector.PanelDescriptor("canvas-profiler", WebInspector.UIString("Canvas Profiler"), "CanvasProfilerPanel", "ProfilesPanel.js"));
if (!WebInspector.WorkerManager.isWorkerFrontend() && WebInspector.experimentsSettings.nativeMemorySnapshots.isEnabled()) {
allProfilers.push(new WebInspector.PanelDescriptor("memory-chart-profiler", WebInspector.UIString("Memory Distribution"), "MemoryChartProfilerPanel", "ProfilesPanel.js"));
allProfilers.push(new WebInspector.PanelDescriptor("memory-snapshot-profiler", WebInspector.UIString("Memory Snapshots"), "NativeMemoryProfilerPanel", "ProfilesPanel.js"));
}
Array.prototype.splice.bind(allDescriptors, allDescriptors.indexOf(profiles), 1).apply(null, allProfilers);
}

var panelDescriptors = [];
if (WebInspector.WorkerManager.isWorkerFrontend()) {
panelDescriptors.push(scripts);
panelDescriptors.push(timeline);
panelDescriptors = panelDescriptors.concat(allProfilers);
panelDescriptors.push(console);
return panelDescriptors;
}
for (var i = 0; i < allDescriptors.length; ++i)
panelDescriptors.push(allDescriptors[i]);
return panelDescriptors;
},

_panelSelected: function()
{
this._toggleConsoleButton.setEnabled(WebInspector.inspectorView.currentPanel().name !== "console");
},

_createGlobalStatusBarItems: function()
{
var bottomStatusBarContainer = document.getElementById("bottom-status-bar-container");


var mainStatusBar = document.getElementById("main-status-bar");
mainStatusBar.insertBefore(this.dockController.element, bottomStatusBarContainer);

this._toggleConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Show console."), "console-status-bar-item");
this._toggleConsoleButton.addEventListener("click", this._toggleConsoleButtonClicked.bind(this), false);
mainStatusBar.insertBefore(this._toggleConsoleButton.element, bottomStatusBarContainer);

if (this.inspectElementModeController)
mainStatusBar.insertBefore(this.inspectElementModeController.toggleSearchButton.element, bottomStatusBarContainer);

mainStatusBar.appendChild(this.settingsController.statusBarItem);
},

_toggleConsoleButtonClicked: function()
{
if (!this._toggleConsoleButton.enabled())
return;

var animationType = window.event && window.event.shiftKey ? WebInspector.Drawer.AnimationType.Slow : WebInspector.Drawer.AnimationType.Normal;

if (this._toggleConsoleButton.toggled)
this.closeConsole(animationType);
else
this.showConsole(animationType);
},


showViewInDrawer: function(statusBarElement, view, onclose)
{
this._toggleConsoleButton.title = WebInspector.UIString("Show console.");
this._toggleConsoleButton.toggled = false;
this._removeDrawerView();

var drawerStatusBarHeader = document.createElement("div");
drawerStatusBarHeader.className = "drawer-header status-bar-item";
drawerStatusBarHeader.appendChild(statusBarElement);
drawerStatusBarHeader.onclose = onclose;

var closeButton = drawerStatusBarHeader.createChild("div", "close-button");
closeButton.addEventListener("click", this.closeViewInDrawer.bind(this), false);

var panelStatusBar = document.getElementById("panel-status-bar");
var drawerViewAnchor = document.getElementById("drawer-view-anchor");
panelStatusBar.insertBefore(drawerStatusBarHeader, drawerViewAnchor);
this._drawerStatusBarHeader = drawerStatusBarHeader;
this.drawer.show(view, WebInspector.Drawer.AnimationType.Immediately);
},

closeViewInDrawer: function()
{
if (this._drawerStatusBarHeader) {
this._removeDrawerView();


if (this._consoleWasShown)
this.showConsole();
else
this.drawer.hide(WebInspector.Drawer.AnimationType.Immediately);
}
},

_removeDrawerView: function()
{
if (this._drawerStatusBarHeader) {
this._drawerStatusBarHeader.removeSelf();
if (this._drawerStatusBarHeader.onclose)
this._drawerStatusBarHeader.onclose();
delete this._drawerStatusBarHeader;
}
},


showConsole: function(animationType)
{
animationType = animationType || WebInspector.Drawer.AnimationType.Normal;

if (this.consoleView.isShowing())
return;

if (WebInspector.drawer.visible)
this._removeDrawerView();

this._toggleConsoleButton.toggled = true;
this._toggleConsoleButton.title = WebInspector.UIString("Hide console.");
this.drawer.show(this.consoleView, animationType);
this._consoleWasShown = true;
},


closeConsole: function(animationType)
{
animationType = animationType || WebInspector.Drawer.AnimationType.Normal;

if (!this.consoleView.isShowing() || !WebInspector.drawer.visible)
return;

this._toggleConsoleButton.toggled = false;
this._toggleConsoleButton.title = WebInspector.UIString("Show console.");
this.drawer.hide(animationType);
this._consoleWasShown = false;
},


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

var errors = WebInspector.console.errors;
var warnings = WebInspector.console.warnings;
if (!errors && !warnings) {
errorWarningElement.addStyleClass("hidden");
return;
}

errorWarningElement.removeStyleClass("hidden");

errorWarningElement.removeChildren();

if (errors) {
var errorImageElement = errorWarningElement.createChild("div", "error-icon-small");
var errorElement = errorWarningElement.createChild("span");
errorElement.id = "error-count";
errorElement.textContent = errors;
}

if (warnings) {
var warningsImageElement = errorWarningElement.createChild("div", "warning-icon-small");
var warningsElement = errorWarningElement.createChild("span");
warningsElement.id = "warning-count";
warningsElement.textContent = warnings;
}

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

get inspectedPageDomain()
{
var parsedURL = WebInspector.inspectedPageURL && WebInspector.inspectedPageURL.asParsedURL();
return parsedURL ? parsedURL.host : "";
},

_initializeCapability: function(name, callback, error, result)
{
Capabilities[name] = result;
if (callback)
callback();
},

_zoomIn: function()
{
this._zoomLevel = Math.min(this._zoomLevel + 1, WebInspector.Zoom.Table.length - WebInspector.Zoom.DefaultOffset - 1);
this._requestZoom();
},

_zoomOut: function()
{
this._zoomLevel = Math.max(this._zoomLevel - 1, -WebInspector.Zoom.DefaultOffset);
this._requestZoom();
},

_resetZoom: function()
{
this._zoomLevel = 0;
this._requestZoom();
},

_requestZoom: function()
{
WebInspector.settings.zoomLevel.set(this._zoomLevel);

var index = this._zoomLevel + WebInspector.Zoom.DefaultOffset;
index = Math.min(WebInspector.Zoom.Table.length - 1, index);
index = Math.max(0, index);
InspectorFrontendHost.setZoomFactor(WebInspector.Zoom.Table[index]);
},

_debuggerPaused: function()
{

WebInspector.panel("scripts");
},

_setupTethering: function()
{
if (!this._portForwardings) {
this._portForwardings = {};
WebInspector.settings.portForwardings.addChangeListener(this._setupTethering.bind(this));
}
var entries = WebInspector.settings.portForwardings.get();
var newForwardings = {};
for (var i = 0; i < entries.length; ++i)
newForwardings[entries[i].port] = entries[i].location;

for (var port in this._portForwardings) {
if (!newForwardings[port])
unbind(port);
}

for (var port in newForwardings) {
if (this._portForwardings[port] && newForwardings[port] === this._portForwardings[port])
continue;
if (this._portForwardings[port])
unbind(port);
bind(port, newForwardings[port]);
}
this._portForwardings = newForwardings;


function bind(port, location)
{
var command = { method: "Tethering.bind", params: { port: parseInt(port, 10), location: location }, id: InspectorBackend.nextCallbackId() };
InspectorBackend.sendMessageObjectToBackend(command);
}


function unbind(port)
{
var command = { method: "Tethering.unbind", params: { port: parseInt(port, 10) }, id: InspectorBackend.nextCallbackId() };
InspectorBackend.sendMessageObjectToBackend(command);
}
}
}

WebInspector.Events = {
InspectorLoaded: "InspectorLoaded",
InspectorClosing: "InspectorClosing"
}

{(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.suggestReload = function()
{
if (window.confirm(WebInspector.UIString("It is recommended to restart inspector after making these changes. Would you like to restart it?")))
this.reload();
}

WebInspector.reload = function()
{
var queryParams = window.location.search;
var url = window.location.href;
url = url.substring(0, url.length - queryParams.length);
var queryParamsObject = {};
for (var name in WebInspector.queryParamsObject)
queryParamsObject[name] = WebInspector.queryParamsObject[name];
if (this.dockController)
queryParamsObject["dockSide"] = this.dockController.dockSide();
var names = Object.keys(queryParamsObject);
for (var i = 0; i < names.length; ++i)
url += (i ? "&" : "?") + names[i] + "=" + queryParamsObject[names[i]];

InspectorBackend.disconnect();
document.location = url;
}

WebInspector.loaded = function()
{
InspectorBackend.loadFromJSONIfNeeded("../protocol.json");
WebInspector.dockController = new WebInspector.DockController();

if (WebInspector.WorkerManager.isDedicatedWorkerFrontend()) {

WebInspector.doLoadedDone();
return;
}

var ws;
if ("ws" in WebInspector.queryParamsObject)
ws = "ws://" + WebInspector.queryParamsObject.ws;
else if ("page" in WebInspector.queryParamsObject) {
var page = WebInspector.queryParamsObject.page;
var host = "host" in WebInspector.queryParamsObject ? WebInspector.queryParamsObject.host : window.location.host;
ws = "ws://" + host + "/devtools/page/" + page;
}

if (ws) {
WebInspector.socket = new WebSocket(ws);
WebInspector.socket.onmessage = function(message) { InspectorBackend.dispatch(message.data); }
WebInspector.socket.onerror = function(error) { console.error(error); }
WebInspector.socket.onopen = function() {
InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket);
WebInspector.doLoadedDone();
}
WebInspector.socket.onclose = function() {
if (!WebInspector.socket._detachReason)
(new WebInspector.RemoteDebuggingTerminatedScreen("websocket_closed")).showModal();
}
return;
}

WebInspector.doLoadedDone();


if (InspectorFrontendHost.isStub) {
InspectorFrontendAPI.dispatchQueryParameters();
WebInspector._doLoadedDoneWithCapabilities();
}
}

WebInspector.doLoadedDone = function()
{

WebInspector.installPortStyles();
if (WebInspector.socket)
document.body.addStyleClass("remote");

if (WebInspector.queryParamsObject.toolbarColor && WebInspector.queryParamsObject.textColor)
WebInspector.setToolbarColors(WebInspector.queryParamsObject.toolbarColor, WebInspector.queryParamsObject.textColor);

WebInspector.WorkerManager.loaded();

PageAgent.canShowFPSCounter(WebInspector._initializeCapability.bind(WebInspector, "canShowFPSCounter", null));
PageAgent.canContinuouslyPaint(WebInspector._initializeCapability.bind(WebInspector, "canContinuouslyPaint", null));
WorkerAgent.canInspectWorkers(WebInspector._initializeCapability.bind(WebInspector, "canInspectWorkers", WebInspector._doLoadedDoneWithCapabilities.bind(WebInspector)));
}

WebInspector._doLoadedDoneWithCapabilities = function()
{
new WebInspector.VersionController().updateVersion();

WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
this._registerShortcuts();


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

var panelDescriptors = this._panelDescriptors();
for (var i = 0; i < panelDescriptors.length; ++i)
panelDescriptors[i].registerShortcuts();

this.console = new WebInspector.ConsoleModel();
this.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._updateErrorAndWarningCounts, this);
this.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this);
this.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._updateErrorAndWarningCounts, this);

WebInspector.CSSMetadata.requestCSSShorthandData();

this.drawer = new WebInspector.Drawer();

this.networkManager = new WebInspector.NetworkManager();
this.resourceTreeModel = new WebInspector.ResourceTreeModel(this.networkManager);
this.debuggerModel = new WebInspector.DebuggerModel();
this.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
this.networkLog = new WebInspector.NetworkLog();
this.domAgent = new WebInspector.DOMAgent();
this.domAgent.addEventListener(WebInspector.DOMAgent.Events.InspectNodeRequested, this._inspectNodeRequested, this);
this.runtimeModel = new WebInspector.RuntimeModel(this.resourceTreeModel);

this.consoleView = new WebInspector.ConsoleView(WebInspector.WorkerManager.isWorkerFrontend());

InspectorBackend.registerInspectorDispatcher(this);

this.isolatedFileSystemManager = new WebInspector.IsolatedFileSystemManager();
this.isolatedFileSystemDispatcher = new WebInspector.IsolatedFileSystemDispatcher(this.isolatedFileSystemManager);
this.fileMapping = new WebInspector.FileMapping();
this.workspace = new WebInspector.Workspace(this.fileMapping, this.isolatedFileSystemManager.mapping());

this.cssModel = new WebInspector.CSSStyleModel(this.workspace);
this.timelineManager = new WebInspector.TimelineManager();
this.userAgentSupport = new WebInspector.UserAgentSupport();

this.searchController = new WebInspector.SearchController();
this.advancedSearchController = new WebInspector.AdvancedSearchController();
if (!WebInspector.WorkerManager.isWorkerFrontend())
this.inspectElementModeController = new WebInspector.InspectElementModeController();

this.settingsController = new WebInspector.SettingsController();

this.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();

this._zoomLevel = WebInspector.settings.zoomLevel.get();
if (this._zoomLevel)
this._requestZoom();

var autoselectPanel = WebInspector.UIString("a panel chosen automatically");
var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
this.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
this.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });

this.workspaceController = new WebInspector.WorkspaceController(this.workspace);

this.fileSystemWorkspaceProvider = new WebInspector.FileSystemWorkspaceProvider(this.isolatedFileSystemManager, this.workspace);

this.networkWorkspaceProvider = new WebInspector.SimpleWorkspaceProvider(this.workspace, WebInspector.projectTypes.Network);
new WebInspector.NetworkUISourceCodeProvider(this.networkWorkspaceProvider, this.workspace);

this.breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, this.debuggerModel, this.workspace);

this.scriptSnippetModel = new WebInspector.ScriptSnippetModel(this.workspace);

new WebInspector.DebuggerScriptMapping(this.workspace, this.networkWorkspaceProvider);
this.liveEditSupport = new WebInspector.LiveEditSupport(this.workspace);
this.styleContentBinding = new WebInspector.StyleContentBinding(this.cssModel, this.workspace);
new WebInspector.StylesSourceMapping(this.cssModel, this.workspace);
if (WebInspector.experimentsSettings.sass.isEnabled())
new WebInspector.SASSSourceMapping(this.cssModel, this.workspace, this.networkWorkspaceProvider);

new WebInspector.PresentationConsoleMessageHelper(this.workspace);

this._createGlobalStatusBarItems();

this.toolbar = new WebInspector.Toolbar();
WebInspector.startBatchUpdate();
for (var i = 0; i < panelDescriptors.length; ++i)
WebInspector.inspectorView.addPanel(panelDescriptors[i]);
WebInspector.endBatchUpdate();

this.addMainEventListeners(document);

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

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

this.extensionServer.initExtensions();

this.console.enableAgent();

function showInitialPanel()
{
if (!WebInspector.inspectorView.currentPanel())
WebInspector.showPanel(WebInspector.settings.lastActivePanel.get());
}

InspectorAgent.enable(showInitialPanel);
this.databaseModel = new WebInspector.DatabaseModel();
this.domStorageModel = new WebInspector.DOMStorageModel();

ProfilerAgent.enable();

if (WebInspector.settings.showPaintRects.get())
PageAgent.setShowPaintRects(true);

if (WebInspector.settings.showDebugBorders.get())
PageAgent.setShowDebugBorders(true);

if (WebInspector.settings.continuousPainting.get())
PageAgent.setContinuousPaintingEnabled(true);

if (WebInspector.settings.showFPSCounter.get())
PageAgent.setShowFPSCounter(true);

this.domAgent._emulateTouchEventsChanged();

WebInspector.WorkerManager.loadCompleted();
InspectorFrontendAPI.loadCompleted();

if (WebInspector.experimentsSettings.tethering.isEnabled())
this._setupTethering();

WebInspector.notifications.dispatchEventToListeners(WebInspector.Events.InspectorLoaded);
}

var windowLoaded = function()
{
WebInspector.loaded();
window.removeEventListener("DOMContentLoaded", windowLoaded, false);
delete windowLoaded;
};

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







var messagesToDispatch = [];

WebInspector.dispatchQueueIsEmpty = function() {
return messagesToDispatch.length == 0;
}

WebInspector.dispatch = function(message) {
messagesToDispatch.push(message);
setTimeout(function() {
InspectorBackend.dispatch(messagesToDispatch.shift());
}, 0);
}

WebInspector.windowResize = function(event)
{
if (WebInspector.inspectorView)
WebInspector.inspectorView.doResize();
if (WebInspector.drawer)
WebInspector.drawer.resize();
if (WebInspector.toolbar)
WebInspector.toolbar.resize();
if (WebInspector.settingsController)
WebInspector.settingsController.resize();
}

WebInspector.setDockingUnavailable = function(unavailable)
{
if (this.dockController)
this.dockController.setDockingUnavailable(unavailable);
}

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

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


event.consume(true);

function followLink()
{
if (WebInspector.isBeingEdited(event.target) || WebInspector._showAnchorLocation(anchor))
return;

const profileMatch = WebInspector.ProfilesPanelDescriptor.ProfileURLRegExp.exec(anchor.href);
if (profileMatch) {
WebInspector.showPanel("profiles").showProfile(profileMatch[1], profileMatch[2]);
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.panel(panel))
WebInspector.showPanel(panel);
}
return;
}

InspectorFrontendHost.openInNewTab(anchor.href);
}

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.showPanel("resources").showResource(resource);
else
InspectorFrontendHost.openInNewTab(resourceURL);
}

WebInspector._registerShortcuts = function()
{
var shortcut = WebInspector.KeyboardShortcut;
var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
var keys = [
shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta),
shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta)
];
section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));

keys = [
shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
];
section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));

section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), WebInspector.UIString("Toggle console"));
section.addKey(shortcut.makeDescriptor("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));

var advancedSearchShortcut = WebInspector.AdvancedSearchController.createShortcut();
section.addKey(advancedSearchShortcut, WebInspector.UIString("Search across all sources"));

var inspectElementModeShortcut = WebInspector.InspectElementModeController.createShortcut();
section.addKey(inspectElementModeShortcut, WebInspector.UIString("Select node to inspect"));

var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
section.addKey(openResourceShortcut, WebInspector.UIString("Go to source"));

if (WebInspector.isMac()) {
keys = [
shortcut.makeDescriptor("g", shortcut.Modifiers.Meta),
shortcut.makeDescriptor("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
}

var goToShortcut = WebInspector.GoToLineDialog.createShortcut();
section.addKey(goToShortcut, WebInspector.UIString("Go to line"));

keys = [
shortcut.Keys.F1,
shortcut.makeDescriptor("?")
];
section.addAlternateKeys(keys, WebInspector.UIString("Show keyboard shortcuts"));
}


WebInspector.documentKeyDown = function(event)
{
const helpKey = WebInspector.isMac() ? "U+003F" : "U+00BF"; 

if (event.keyIdentifier === "F1" ||
(event.keyIdentifier === helpKey && event.shiftKey && (!WebInspector.isBeingEdited(event.target) || event.metaKey))) {
this.settingsController.showSettingsScreen(WebInspector.SettingsScreen.Tabs.General);
event.consume(true);
return;
}

if (WebInspector.currentFocusElement() && WebInspector.currentFocusElement().handleKeyEvent) {
WebInspector.currentFocusElement().handleKeyEvent(event);
if (event.handled) {
event.consume(true);
return;
}
}

if (WebInspector.inspectorView.currentPanel()) {
WebInspector.inspectorView.currentPanel().handleShortcut(event);
if (event.handled) {
event.consume(true);
return;
}
}

if (WebInspector.searchController.handleShortcut(event))
return;
if (WebInspector.advancedSearchController.handleShortcut(event))
return;
if (WebInspector.inspectElementModeController && WebInspector.inspectElementModeController.handleShortcut(event))
return;

switch (event.keyIdentifier) {
case "U+004F": 
if (!event.shiftKey && !event.altKey && WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
WebInspector.showPanel("scripts").showGoToSourceDialog();
event.consume(true);
}
break;
case "U+0052": 
if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
PageAgent.reload(event.shiftKey);
event.consume(true);
}
if (window.DEBUG && event.altKey) {
WebInspector.reload();
return;
}
break;
case "F5":
if (!WebInspector.isMac()) {
PageAgent.reload(event.ctrlKey || event.shiftKey);
event.consume(true);
}
break;
}

var isValidZoomShortcut = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) &&
!event.altKey &&
!InspectorFrontendHost.isStub;
switch (event.keyCode) {
case 107: 
case 187: 
if (isValidZoomShortcut) {
WebInspector._zoomIn();
event.consume(true);
}
break;
case 109: 
case 189: 
if (isValidZoomShortcut) {
WebInspector._zoomOut();
event.consume(true);
}
break;
case 48: 

if (isValidZoomShortcut && !event.shiftKey) {
WebInspector._resetZoom();
event.consume(true);
}
break;
}
}

WebInspector.postDocumentKeyDown = function(event)
{
if (event.handled)
return;

if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {

if (!this._toggleConsoleButton.toggled && WebInspector.drawer.visible)
this.closeViewInDrawer();
else
this._toggleConsoleButtonClicked();
}
}

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

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

WebInspector.documentCopyEventFired = function(event)
{
}

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

WebInspector.showPanel = function(panel)
{
return WebInspector.inspectorView.showPanel(panel);
}

WebInspector.panel = function(panel)
{
return WebInspector.inspectorView.panel(panel);
}

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


WebInspector.log = function(message, messageLevel, showConsole)
{

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 msg = WebInspector.ConsoleMessage.create(
WebInspector.ConsoleMessage.MessageSource.Other,
messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug,
message);

self.console.addMessage(msg);
if (showConsole)
WebInspector.showConsole();
}


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.showErrorMessage = function(error)
{
WebInspector.log(error, WebInspector.ConsoleMessage.MessageLevel.Error, true);
}


WebInspector.inspect = function(payload, hints)
{
var object = WebInspector.RemoteObject.fromPayload(payload);
if (object.subtype === "node") {
function callback(nodeId)
{
WebInspector._updateFocusedNode(nodeId);
object.release();
}
object.pushNodeToFrontend(callback);
return;
}

if (hints.databaseId)
WebInspector.showPanel("resources").selectDatabase(WebInspector.databaseModel.databaseForId(hints.databaseId));
else if (hints.domStorageId)
WebInspector.showPanel("resources").selectDOMStorage(WebInspector.domStorageModel.storageForId(hints.domStorageId));

object.release();
}


WebInspector.detached = function(reason)
{
WebInspector.socket._detachReason = reason;
(new WebInspector.RemoteDebuggingTerminatedScreen(reason)).showModal();
}

WebInspector.targetCrashed = function()
{
(new WebInspector.HelpScreenUntilReload(
WebInspector.UIString("Inspected target crashed"),
WebInspector.UIString("Inspected target has crashed. Once it reloads we will attach to it automatically."))).showModal();
}

WebInspector._inspectNodeRequested = function(event)
{
WebInspector._updateFocusedNode(event.data);
}

WebInspector._updateFocusedNode = function(nodeId)
{
if (WebInspector.inspectElementModeController && WebInspector.inspectElementModeController.enabled()) {
InspectorFrontendHost.bringToFront();
WebInspector.inspectElementModeController.disable();
}
WebInspector.showPanel("elements").revealAndSelectNode(nodeId);
}

WebInspector._showAnchorLocation = function(anchor)
{
if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
return true;
var preferredPanel = this.panels[anchor.preferredPanel];
if (preferredPanel && WebInspector._showAnchorLocationInPanel(anchor, preferredPanel))
return true;
if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("scripts")))
return true;
if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("resources")))
return true;
if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("network")))
return true;
return false;
}

WebInspector._showAnchorLocationInPanel = function(anchor, panel)
{
if (!panel || !panel.canShowAnchorLocation(anchor))
return false;


if (anchor.hasStyleClass("webkit-html-external-link")) {
anchor.removeStyleClass("webkit-html-external-link");
anchor.addStyleClass("webkit-html-resource-link");
}

WebInspector.inspectorView.showPanelForAnchorNavigation(panel);
panel.showAnchorLocation(anchor);
return true;
}

WebInspector.evaluateInConsole = function(expression, showResultOnly)
{
this.showConsole();
this.consoleView.evaluateUsingTextPrompt(expression, showResultOnly);
}

WebInspector.addMainEventListeners = function(doc)
{
doc.addEventListener("keydown", this.documentKeyDown.bind(this), true);
doc.addEventListener("keydown", this.postDocumentKeyDown.bind(this), false);
doc.addEventListener("beforecopy", this.documentCanCopy.bind(this), true);
doc.addEventListener("copy", this.documentCopy.bind(this), false);
doc.addEventListener("contextmenu", this.contextMenuEventFired.bind(this), true);
doc.addEventListener("click", this.documentClick.bind(this), true);
}

WebInspector.Zoom = {
Table: [0.25, 0.33, 0.5, 0.66, 0.75, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5],
DefaultOffset: 6
}





function buildPlatformExtensionAPI(extensionInfo)
{
return "var extensionInfo = " + JSON.stringify(extensionInfo) + ";" +
"var tabId = " + WebInspector._inspectedTabId + ";" +
platformExtensionAPI.toString();
}

WebInspector.setInspectedTabId = function(tabId)
{
WebInspector._inspectedTabId = tabId;
}


WebInspector.getSelectionBackgroundColor = function()
{
return InspectorFrontendHost.getSelectionBackgroundColor();
}


WebInspector.getSelectionForegroundColor = function()
{
return InspectorFrontendHost.getSelectionForegroundColor();
}

window.DEBUG = true;






WebInspector.UIString = function(string, vararg)
{
return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
}






function InspectorBackendClass()
{
this._lastCallbackId = 1;
this._pendingResponsesCount = 0;
this._callbacks = {};
this._domainDispatchers = {};
this._eventArgs = {};
this._replyArgs = {};

this.dumpInspectorTimeStats = false;
this.dumpInspectorProtocolMessages = false;
this._initialized = false;
}

InspectorBackendClass.prototype = {

nextCallbackId: function()
{
return this._lastCallbackId++;
},

_wrap: function(callback, method)
{
var callbackId = this.nextCallbackId();
if (!callback)
callback = function() {};

this._callbacks[callbackId] = callback;
callback.methodName = method;
if (this.dumpInspectorTimeStats)
callback.sendRequestTime = Date.now();

return callbackId;
},

_getAgent: function(domain)
{
var agentName = domain + "Agent";
if (!window[agentName])
window[agentName] = {};
return window[agentName];
},

registerCommand: function(method, signature, replyArgs)
{
var domainAndMethod = method.split(".");
var agent = this._getAgent(domainAndMethod[0]);

agent[domainAndMethod[1]] = this._sendMessageToBackend.bind(this, method, signature);
agent[domainAndMethod[1]]["invoke"] = this._invoke.bind(this, method, signature);
this._replyArgs[method] = replyArgs;

this._initialized = true;
},

registerEnum: function(type, values)
{
var domainAndMethod = type.split(".");
var agent = this._getAgent(domainAndMethod[0]);

agent[domainAndMethod[1]] = values;

this._initialized = true;
},

registerEvent: function(eventName, params)
{
this._eventArgs[eventName] = params;

this._initialized = true;
},

_invoke: function(method, signature, args, callback)
{
this._wrapCallbackAndSendMessageObject(method, args, callback);
},

_sendMessageToBackend: function(method, signature, vararg)
{
var args = Array.prototype.slice.call(arguments, 2);
var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : null;

var params = {};
var hasParams = false;
for (var i = 0; i < signature.length; ++i) {
var param = signature[i];
var paramName = param["name"];
var typeName = param["type"];
var optionalFlag = param["optional"];

if (!args.length && !optionalFlag) {
console.error("Protocol Error: Invalid number of arguments for method '" + method + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'.");
return;
}

var value = args.shift();
if (optionalFlag && typeof value === "undefined") {
continue;
}

if (typeof value !== typeName) {
console.error("Protocol Error: Invalid type of argument '" + paramName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
return;
}

params[paramName] = value;
hasParams = true;
}

if (args.length === 1 && !callback) {
if (typeof args[0] !== "undefined") {
console.error("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'.");
return;
}
}

this._wrapCallbackAndSendMessageObject(method, hasParams ? params : null, callback);
},

_wrapCallbackAndSendMessageObject: function(method, params, callback)
{
var messageObject = {};
messageObject.method = method;
if (params)
messageObject.params = params;
messageObject.id = this._wrap(callback, method);

if (this.dumpInspectorProtocolMessages)
console.log("frontend: " + JSON.stringify(messageObject));

++this._pendingResponsesCount;
this.sendMessageObjectToBackend(messageObject);
},

sendMessageObjectToBackend: function(messageObject)
{
if (this._disconnected)
return;
var message = JSON.stringify(messageObject);
InspectorFrontendHost.sendMessageToBackend(message);
},

disconnect: function()
{
this._disconnected = true;
},

registerDomainDispatcher: function(domain, dispatcher)
{
this._domainDispatchers[domain] = dispatcher;
},

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

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

if ("id" in messageObject) { 
if (messageObject.error) {
if (messageObject.error.code !== -32000)
this.reportProtocolError(messageObject);
}

var callback = this._callbacks[messageObject.id];
if (callback) {
var argumentsArray = [];
if (messageObject.result) {
var paramNames = this._replyArgs[callback.methodName];
if (paramNames) {
for (var i = 0; i < paramNames.length; ++i)
argumentsArray.push(messageObject.result[paramNames[i]]);
}
}

var processingStartTime;
if (this.dumpInspectorTimeStats && callback.methodName)
processingStartTime = Date.now();

argumentsArray.unshift(messageObject.error ? messageObject.error.message : null);
callback.apply(null, argumentsArray);
--this._pendingResponsesCount;
delete this._callbacks[messageObject.id];

if (this.dumpInspectorTimeStats && callback.methodName)
console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime));
}

if (this._scripts && !this._pendingResponsesCount)
this.runAfterPendingDispatches();

return;
} else {
var method = messageObject.method.split(".");
var domainName = method[0];
var functionName = method[1];
if (!(domainName in this._domainDispatchers)) {
console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
return;
}
var dispatcher = this._domainDispatchers[domainName];
if (!(functionName in dispatcher)) {
console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
return;
}

if (!this._eventArgs[messageObject.method]) {
console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
return;
}

var params = [];
if (messageObject.params) {
var paramNames = this._eventArgs[messageObject.method];
for (var i = 0; i < paramNames.length; ++i)
params.push(messageObject.params[paramNames[i]]);
}

var processingStartTime;
if (this.dumpInspectorTimeStats)
processingStartTime = Date.now();

dispatcher[functionName].apply(dispatcher, params);

if (this.dumpInspectorTimeStats)
console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime));
}
},

reportProtocolError: function(messageObject)
{
console.error("Request with id = " + messageObject.id + " failed. " + messageObject.error);
},


runAfterPendingDispatches: function(script)
{
if (!this._scripts)
this._scripts = [];

if (script)
this._scripts.push(script);

if (!this._pendingResponsesCount) {
var scripts = this._scripts;
this._scripts = []
for (var id = 0; id < scripts.length; ++id)
scripts[id].call(this);
}
},

loadFromJSONIfNeeded: function(jsonUrl)
{
if (this._initialized)
return;

var xhr = new XMLHttpRequest();
xhr.open("GET", jsonUrl, false);
xhr.send(null);

var schema = JSON.parse(xhr.responseText);
var code = InspectorBackendClass._generateCommands(schema);
eval(code);
}
}


InspectorBackendClass._generateCommands = function(schema) {
var jsTypes = { integer: "number", array: "object" };
var rawTypes = {};
var result = [];

var domains = schema["domains"] || [];
for (var i = 0; i < domains.length; ++i) {
var domain = domains[i];
for (var j = 0; domain.types && j < domain.types.length; ++j) {
var type = domain.types[j];
rawTypes[domain.domain + "." + type.id] = jsTypes[type.type] || type.type;
}
}

function toUpperCase(groupIndex, group0, group1)
{
return [group0, group1][groupIndex].toUpperCase();
}
function generateEnum(enumName, items)
{
var members = []
for (var m = 0; m < items.length; ++m) {
var value = items[m];
var name = value.replace(/-(\w)/g, toUpperCase.bind(null, 1)).toTitleCase();
name = name.replace(/HTML|XML|WML|API/ig, toUpperCase.bind(null, 0));
members.push(name + ": \"" + value +"\"");
}
return "InspectorBackend.registerEnum(\"" + enumName + "\", {" + members.join(", ") + "});";
}

for (var i = 0; i < domains.length; ++i) {
var domain = domains[i];

var types = domain["types"] || [];
for (var j = 0; j < types.length; ++j) {
var type = types[j];
if ((type["type"] === "string") && type["enum"])
result.push(generateEnum(domain.domain + "." + type.id, type["enum"]));
else if (type["type"] === "object") {
var properties = type["properties"] || [];
for (var k = 0; k < properties.length; ++k) {
var property = properties[k];
if ((property["type"] === "string") && property["enum"])
result.push(generateEnum(domain.domain + "." + type.id + property["name"].toTitleCase(), property["enum"]));
}
}
}

var commands = domain["commands"] || [];
for (var j = 0; j < commands.length; ++j) {
var command = commands[j];
var parameters = command["parameters"];
var paramsText = [];
for (var k = 0; parameters && k < parameters.length; ++k) {
var parameter = parameters[k];

var type;
if (parameter.type)
type = jsTypes[parameter.type] || parameter.type;
else {
var ref = parameter["$ref"];
if (ref.indexOf(".") !== -1)
type = rawTypes[ref];
else
type = rawTypes[domain.domain + "." + ref];
}

var text = "{\"name\": \"" + parameter.name + "\", \"type\": \"" + type + "\", \"optional\": " + (parameter.optional ? "true" : "false") + "}";
paramsText.push(text);
}

var returnsText = [];
var returns = command["returns"] || [];
for (var k = 0; k < returns.length; ++k) {
var parameter = returns[k];
returnsText.push("\"" + parameter.name + "\"");
}
result.push("InspectorBackend.registerCommand(\"" + domain.domain + "." + command.name + "\", [" + paramsText.join(", ") + "], [" + returnsText.join(", ") + "]);");
}

for (var j = 0; domain.events && j < domain.events.length; ++j) {
var event = domain.events[j];
var paramsText = [];
for (var k = 0; event.parameters && k < event.parameters.length; ++k) {
var parameter = event.parameters[k];
paramsText.push("\"" + parameter.name + "\"");
}
result.push("InspectorBackend.registerEvent(\"" + domain.domain + "." + event.name + "\", [" + paramsText.join(", ") + "]);");
}

result.push("InspectorBackend.register" + domain.domain + "Dispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, \"" + domain.domain + "\");");
}
return result.join("\n");
}

InspectorBackend = new InspectorBackendClass();











InspectorBackend.registerInspectorDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Inspector");
InspectorBackend.registerEvent("Inspector.evaluateForTestInFrontend", ["testCallId", "script"]);
InspectorBackend.registerEvent("Inspector.inspect", ["object", "hints"]);
InspectorBackend.registerEvent("Inspector.detached", ["reason"]);
InspectorBackend.registerEvent("Inspector.targetCrashed", []);
InspectorBackend.registerCommand("Inspector.enable", [], []);
InspectorBackend.registerCommand("Inspector.disable", [], []);


InspectorBackend.registerMemoryDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Memory");
InspectorBackend.registerEvent("Memory.addNativeSnapshotChunk", ["chunk"]);
InspectorBackend.registerCommand("Memory.getDOMCounters", [], ["documents", "nodes", "jsEventListeners"]);
InspectorBackend.registerCommand("Memory.getProcessMemoryDistribution", [{"name": "reportGraph", "type": "boolean", "optional": true}], ["distribution", "graphMetaInformation"]);


InspectorBackend.registerPageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Page");
InspectorBackend.registerEnum("Page.ResourceType", {Document: "Document", Stylesheet: "Stylesheet", Image: "Image", Font: "Font", Script: "Script", XHR: "XHR", WebSocket: "WebSocket", Other: "Other"});
InspectorBackend.registerEvent("Page.domContentEventFired", ["timestamp"]);
InspectorBackend.registerEvent("Page.loadEventFired", ["timestamp"]);
InspectorBackend.registerEvent("Page.frameNavigated", ["frame"]);
InspectorBackend.registerEvent("Page.frameDetached", ["frameId"]);
InspectorBackend.registerEvent("Page.frameStartedLoading", ["frameId"]);
InspectorBackend.registerEvent("Page.frameStoppedLoading", ["frameId"]);
InspectorBackend.registerEvent("Page.frameScheduledNavigation", ["frameId", "delay"]);
InspectorBackend.registerEvent("Page.frameClearedScheduledNavigation", ["frameId"]);
InspectorBackend.registerEvent("Page.javascriptDialogOpening", ["message"]);
InspectorBackend.registerEvent("Page.javascriptDialogClosed", []);
InspectorBackend.registerEvent("Page.scriptsEnabled", ["isEnabled"]);
InspectorBackend.registerCommand("Page.enable", [], []);
InspectorBackend.registerCommand("Page.disable", [], []);
InspectorBackend.registerCommand("Page.addScriptToEvaluateOnLoad", [{"name": "scriptSource", "type": "string", "optional": false}], ["identifier"]);
InspectorBackend.registerCommand("Page.removeScriptToEvaluateOnLoad", [{"name": "identifier", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.reload", [{"name": "ignoreCache", "type": "boolean", "optional": true}, {"name": "scriptToEvaluateOnLoad", "type": "string", "optional": true}, {"name": "scriptPreprocessor", "type": "string", "optional": true}], []);
InspectorBackend.registerCommand("Page.navigate", [{"name": "url", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.getCookies", [], ["cookies", "cookiesString"]);
InspectorBackend.registerCommand("Page.deleteCookie", [{"name": "cookieName", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.getResourceTree", [], ["frameTree"]);
InspectorBackend.registerCommand("Page.getResourceContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}], ["content", "base64Encoded"]);
InspectorBackend.registerCommand("Page.searchInResource", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Page.searchInResources", [{"name": "text", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Page.setDocumentContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "html", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "fontScaleFactor", "type": "number", "optional": false}, {"name": "fitWindow", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.setShowPaintRects", [{"name": "result", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.setShowDebugBorders", [{"name": "show", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.canShowFPSCounter", [], ["show"]);
InspectorBackend.registerCommand("Page.setShowFPSCounter", [{"name": "show", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.canContinuouslyPaint", [], ["value"]);
InspectorBackend.registerCommand("Page.setContinuousPaintingEnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.getScriptExecutionStatus", [], ["result"]);
InspectorBackend.registerCommand("Page.setScriptExecutionDisabled", [{"name": "value", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.setGeolocationOverride", [{"name": "latitude", "type": "number", "optional": true}, {"name": "longitude", "type": "number", "optional": true}, {"name": "accuracy", "type": "number", "optional": true}], []);
InspectorBackend.registerCommand("Page.clearGeolocationOverride", [], []);
InspectorBackend.registerCommand("Page.setDeviceOrientationOverride", [{"name": "alpha", "type": "number", "optional": false}, {"name": "beta", "type": "number", "optional": false}, {"name": "gamma", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Page.clearDeviceOrientationOverride", [], []);
InspectorBackend.registerCommand("Page.setTouchEmulationEnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.setEmulatedMedia", [{"name": "media", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.getCompositingBordersVisible", [], ["result"]);
InspectorBackend.registerCommand("Page.setCompositingBordersVisible", [{"name": "visible", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.captureScreenshot", [], ["data"]);
InspectorBackend.registerCommand("Page.handleJavaScriptDialog", [{"name": "accept", "type": "boolean", "optional": false}, {"name": "promptText", "type": "string", "optional": true}], []);


InspectorBackend.registerRuntimeDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Runtime");
InspectorBackend.registerEnum("Runtime.RemoteObjectType", {Object: "object", Function: "function", Undefined: "undefined", String: "string", Number: "number", Boolean: "boolean"});
InspectorBackend.registerEnum("Runtime.RemoteObjectSubtype", {Array: "array", Null: "null", Node: "node", Regexp: "regexp", Date: "date"});
InspectorBackend.registerEnum("Runtime.PropertyPreviewType", {Object: "object", Function: "function", Undefined: "undefined", String: "string", Number: "number", Boolean: "boolean"});
InspectorBackend.registerEnum("Runtime.PropertyPreviewSubtype", {Array: "array", Null: "null", Node: "node", Regexp: "regexp", Date: "date"});
InspectorBackend.registerEvent("Runtime.executionContextCreated", ["context"]);
InspectorBackend.registerCommand("Runtime.evaluate", [{"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "contextId", "type": "number", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Runtime.callFunctionOn", [{"name": "objectId", "type": "string", "optional": false}, {"name": "functionDeclaration", "type": "string", "optional": false}, {"name": "arguments", "type": "object", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Runtime.getProperties", [{"name": "objectId", "type": "string", "optional": false}, {"name": "ownProperties", "type": "boolean", "optional": true}], ["result", "internalProperties"]);
InspectorBackend.registerCommand("Runtime.releaseObject", [{"name": "objectId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Runtime.releaseObjectGroup", [{"name": "objectGroup", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Runtime.run", [], []);
InspectorBackend.registerCommand("Runtime.enable", [], []);
InspectorBackend.registerCommand("Runtime.disable", [], []);


InspectorBackend.registerConsoleDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Console");
InspectorBackend.registerEnum("Console.ConsoleMessageSource", {XML: "xml", Javascript: "javascript", Network: "network", ConsoleAPI: "console-api", Storage: "storage", Appcache: "appcache", Rendering: "rendering", Css: "css", Security: "security", Other: "other", Deprecation: "deprecation"});
InspectorBackend.registerEnum("Console.ConsoleMessageLevel", {Log: "log", Warning: "warning", Error: "error", Debug: "debug"});
InspectorBackend.registerEnum("Console.ConsoleMessageType", {Log: "log", Dir: "dir", DirXML: "dirxml", Table: "table", Trace: "trace", Clear: "clear", StartGroup: "startGroup", StartGroupCollapsed: "startGroupCollapsed", EndGroup: "endGroup", Assert: "assert", Timing: "timing", Profile: "profile", ProfileEnd: "profileEnd"});
InspectorBackend.registerEvent("Console.messageAdded", ["message"]);
InspectorBackend.registerEvent("Console.messageRepeatCountUpdated", ["count"]);
InspectorBackend.registerEvent("Console.messagesCleared", []);
InspectorBackend.registerCommand("Console.enable", [], []);
InspectorBackend.registerCommand("Console.disable", [], []);
InspectorBackend.registerCommand("Console.clearMessages", [], []);
InspectorBackend.registerCommand("Console.setMonitoringXHREnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Console.addInspectedNode", [{"name": "nodeId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Console.addInspectedHeapObject", [{"name": "heapObjectId", "type": "number", "optional": false}], []);


InspectorBackend.registerNetworkDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Network");
InspectorBackend.registerEnum("Network.InitiatorType", {Parser: "parser", Script: "script", Other: "other"});
InspectorBackend.registerEvent("Network.requestWillBeSent", ["requestId", "frameId", "loaderId", "documentURL", "request", "timestamp", "initiator", "redirectResponse"]);
InspectorBackend.registerEvent("Network.requestServedFromCache", ["requestId"]);
InspectorBackend.registerEvent("Network.responseReceived", ["requestId", "frameId", "loaderId", "timestamp", "type", "response"]);
InspectorBackend.registerEvent("Network.dataReceived", ["requestId", "timestamp", "dataLength", "encodedDataLength"]);
InspectorBackend.registerEvent("Network.loadingFinished", ["requestId", "timestamp"]);
InspectorBackend.registerEvent("Network.loadingFailed", ["requestId", "timestamp", "errorText", "canceled"]);
InspectorBackend.registerEvent("Network.requestServedFromMemoryCache", ["requestId", "frameId", "loaderId", "documentURL", "timestamp", "initiator", "resource"]);
InspectorBackend.registerEvent("Network.webSocketWillSendHandshakeRequest", ["requestId", "timestamp", "request"]);
InspectorBackend.registerEvent("Network.webSocketHandshakeResponseReceived", ["requestId", "timestamp", "response"]);
InspectorBackend.registerEvent("Network.webSocketCreated", ["requestId", "url"]);
InspectorBackend.registerEvent("Network.webSocketClosed", ["requestId", "timestamp"]);
InspectorBackend.registerEvent("Network.webSocketFrameReceived", ["requestId", "timestamp", "response"]);
InspectorBackend.registerEvent("Network.webSocketFrameError", ["requestId", "timestamp", "errorMessage"]);
InspectorBackend.registerEvent("Network.webSocketFrameSent", ["requestId", "timestamp", "response"]);
InspectorBackend.registerCommand("Network.enable", [], []);
InspectorBackend.registerCommand("Network.disable", [], []);
InspectorBackend.registerCommand("Network.setUserAgentOverride", [{"name": "userAgent", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Network.setExtraHTTPHeaders", [{"name": "headers", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("Network.getResponseBody", [{"name": "requestId", "type": "string", "optional": false}], ["body", "base64Encoded"]);
InspectorBackend.registerCommand("Network.replayXHR", [{"name": "requestId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Network.canClearBrowserCache", [], ["result"]);
InspectorBackend.registerCommand("Network.clearBrowserCache", [], []);
InspectorBackend.registerCommand("Network.canClearBrowserCookies", [], ["result"]);
InspectorBackend.registerCommand("Network.clearBrowserCookies", [], []);
InspectorBackend.registerCommand("Network.setCacheDisabled", [{"name": "cacheDisabled", "type": "boolean", "optional": false}], []);


InspectorBackend.registerDatabaseDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Database");
InspectorBackend.registerEvent("Database.addDatabase", ["database"]);
InspectorBackend.registerCommand("Database.enable", [], []);
InspectorBackend.registerCommand("Database.disable", [], []);
InspectorBackend.registerCommand("Database.getDatabaseTableNames", [{"name": "databaseId", "type": "string", "optional": false}], ["tableNames"]);
InspectorBackend.registerCommand("Database.executeSQL", [{"name": "databaseId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["columnNames", "values", "sqlError"]);


InspectorBackend.registerIndexedDBDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "IndexedDB");
InspectorBackend.registerEnum("IndexedDB.KeyType", {Number: "number", String: "string", Date: "date", Array: "array"});
InspectorBackend.registerEnum("IndexedDB.KeyPathType", {Null: "null", String: "string", Array: "array"});
InspectorBackend.registerCommand("IndexedDB.enable", [], []);
InspectorBackend.registerCommand("IndexedDB.disable", [], []);
InspectorBackend.registerCommand("IndexedDB.requestDatabaseNames", [{"name": "securityOrigin", "type": "string", "optional": false}], ["databaseNames"]);
InspectorBackend.registerCommand("IndexedDB.requestDatabase", [{"name": "securityOrigin", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}], ["databaseWithObjectStores"]);
InspectorBackend.registerCommand("IndexedDB.requestData", [{"name": "securityOrigin", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}, {"name": "objectStoreName", "type": "string", "optional": false}, {"name": "indexName", "type": "string", "optional": false}, {"name": "skipCount", "type": "number", "optional": false}, {"name": "pageSize", "type": "number", "optional": false}, {"name": "keyRange", "type": "object", "optional": true}], ["objectStoreDataEntries", "hasMore"]);
InspectorBackend.registerCommand("IndexedDB.clearObjectStore", [{"name": "securityOrigin", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}, {"name": "objectStoreName", "type": "string", "optional": false}], []);


InspectorBackend.registerDOMStorageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOMStorage");
InspectorBackend.registerEvent("DOMStorage.domStorageItemsCleared", ["storageId"]);
InspectorBackend.registerEvent("DOMStorage.domStorageItemRemoved", ["storageId", "key"]);
InspectorBackend.registerEvent("DOMStorage.domStorageItemAdded", ["storageId", "key", "newValue"]);
InspectorBackend.registerEvent("DOMStorage.domStorageItemUpdated", ["storageId", "key", "oldValue", "newValue"]);
InspectorBackend.registerCommand("DOMStorage.enable", [], []);
InspectorBackend.registerCommand("DOMStorage.disable", [], []);
InspectorBackend.registerCommand("DOMStorage.getDOMStorageItems", [{"name": "storageId", "type": "object", "optional": false}], ["entries"]);
InspectorBackend.registerCommand("DOMStorage.setDOMStorageItem", [{"name": "storageId", "type": "object", "optional": false}, {"name": "key", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMStorage.removeDOMStorageItem", [{"name": "storageId", "type": "object", "optional": false}, {"name": "key", "type": "string", "optional": false}], []);


InspectorBackend.registerApplicationCacheDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "ApplicationCache");
InspectorBackend.registerEvent("ApplicationCache.applicationCacheStatusUpdated", ["frameId", "manifestURL", "status"]);
InspectorBackend.registerEvent("ApplicationCache.networkStateUpdated", ["isNowOnline"]);
InspectorBackend.registerCommand("ApplicationCache.getFramesWithManifests", [], ["frameIds"]);
InspectorBackend.registerCommand("ApplicationCache.enable", [], []);
InspectorBackend.registerCommand("ApplicationCache.getManifestForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["manifestURL"]);
InspectorBackend.registerCommand("ApplicationCache.getApplicationCacheForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["applicationCache"]);


InspectorBackend.registerFileSystemDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "FileSystem");
InspectorBackend.registerCommand("FileSystem.enable", [], []);
InspectorBackend.registerCommand("FileSystem.disable", [], []);
InspectorBackend.registerCommand("FileSystem.requestFileSystemRoot", [{"name": "origin", "type": "string", "optional": false}, {"name": "type", "type": "string", "optional": false}], ["errorCode", "root"]);
InspectorBackend.registerCommand("FileSystem.requestDirectoryContent", [{"name": "url", "type": "string", "optional": false}], ["errorCode", "entries"]);
InspectorBackend.registerCommand("FileSystem.requestMetadata", [{"name": "url", "type": "string", "optional": false}], ["errorCode", "metadata"]);
InspectorBackend.registerCommand("FileSystem.requestFileContent", [{"name": "url", "type": "string", "optional": false}, {"name": "readAsText", "type": "boolean", "optional": false}, {"name": "start", "type": "number", "optional": true}, {"name": "end", "type": "number", "optional": true}, {"name": "charset", "type": "string", "optional": true}], ["errorCode", "content", "charset"]);
InspectorBackend.registerCommand("FileSystem.deleteEntry", [{"name": "url", "type": "string", "optional": false}], ["errorCode"]);


InspectorBackend.registerDOMDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOM");
InspectorBackend.registerEvent("DOM.documentUpdated", []);
InspectorBackend.registerEvent("DOM.inspectNodeRequested", ["nodeId"]);
InspectorBackend.registerEvent("DOM.setChildNodes", ["parentId", "nodes"]);
InspectorBackend.registerEvent("DOM.attributeModified", ["nodeId", "name", "value"]);
InspectorBackend.registerEvent("DOM.attributeRemoved", ["nodeId", "name"]);
InspectorBackend.registerEvent("DOM.inlineStyleInvalidated", ["nodeIds"]);
InspectorBackend.registerEvent("DOM.characterDataModified", ["nodeId", "characterData"]);
InspectorBackend.registerEvent("DOM.childNodeCountUpdated", ["nodeId", "childNodeCount"]);
InspectorBackend.registerEvent("DOM.childNodeInserted", ["parentNodeId", "previousNodeId", "node"]);
InspectorBackend.registerEvent("DOM.childNodeRemoved", ["parentNodeId", "nodeId"]);
InspectorBackend.registerEvent("DOM.shadowRootPushed", ["hostId", "root"]);
InspectorBackend.registerEvent("DOM.shadowRootPopped", ["hostId", "rootId"]);
InspectorBackend.registerCommand("DOM.getDocument", [], ["root"]);
InspectorBackend.registerCommand("DOM.requestChildNodes", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "depth", "type": "number", "optional": true}], []);
InspectorBackend.registerCommand("DOM.querySelector", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.querySelectorAll", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeIds"]);
InspectorBackend.registerCommand("DOM.setNodeName", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.setNodeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.removeNode", [{"name": "nodeId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("DOM.setAttributeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.setAttributesAsText", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "name", "type": "string", "optional": true}], []);
InspectorBackend.registerCommand("DOM.removeAttribute", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.getEventListenersForNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["listeners"]);
InspectorBackend.registerCommand("DOM.getOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}], ["outerHTML"]);
InspectorBackend.registerCommand("DOM.setOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "outerHTML", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.performSearch", [{"name": "query", "type": "string", "optional": false}], ["searchId", "resultCount"]);
InspectorBackend.registerCommand("DOM.getSearchResults", [{"name": "searchId", "type": "string", "optional": false}, {"name": "fromIndex", "type": "number", "optional": false}, {"name": "toIndex", "type": "number", "optional": false}], ["nodeIds"]);
InspectorBackend.registerCommand("DOM.discardSearchResults", [{"name": "searchId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.requestNode", [{"name": "objectId", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.setInspectModeEnabled", [{"name": "enabled", "type": "boolean", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": true}], []);
InspectorBackend.registerCommand("DOM.highlightRect", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "color", "type": "object", "optional": true}, {"name": "outlineColor", "type": "object", "optional": true}], []);
InspectorBackend.registerCommand("DOM.highlightQuad", [{"name": "quad", "type": "object", "optional": false}, {"name": "color", "type": "object", "optional": true}, {"name": "outlineColor", "type": "object", "optional": true}], []);
InspectorBackend.registerCommand("DOM.highlightNode", [{"name": "highlightConfig", "type": "object", "optional": false}, {"name": "nodeId", "type": "number", "optional": true}, {"name": "objectId", "type": "string", "optional": true}], []);
InspectorBackend.registerCommand("DOM.hideHighlight", [], []);
InspectorBackend.registerCommand("DOM.highlightFrame", [{"name": "frameId", "type": "string", "optional": false}, {"name": "contentColor", "type": "object", "optional": true}, {"name": "contentOutlineColor", "type": "object", "optional": true}], []);
InspectorBackend.registerCommand("DOM.pushNodeByPathToFrontend", [{"name": "path", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.pushNodeByBackendIdToFrontend", [{"name": "backendNodeId", "type": "number", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.releaseBackendNodeIds", [{"name": "nodeGroup", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.resolveNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["object"]);
InspectorBackend.registerCommand("DOM.getAttributes", [{"name": "nodeId", "type": "number", "optional": false}], ["attributes"]);
InspectorBackend.registerCommand("DOM.moveTo", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "targetNodeId", "type": "number", "optional": false}, {"name": "insertBeforeNodeId", "type": "number", "optional": true}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.undo", [], []);
InspectorBackend.registerCommand("DOM.redo", [], []);
InspectorBackend.registerCommand("DOM.markUndoableState", [], []);
InspectorBackend.registerCommand("DOM.focus", [{"name": "nodeId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("DOM.setFileInputFiles", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "files", "type": "object", "optional": false}], []);


InspectorBackend.registerCSSDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "CSS");
InspectorBackend.registerEnum("CSS.StyleSheetOrigin", {User: "user", UserAgent: "user-agent", Inspector: "inspector", Regular: "regular"});
InspectorBackend.registerEnum("CSS.CSSPropertyStatus", {Active: "active", Inactive: "inactive", Disabled: "disabled", Style: "style"});
InspectorBackend.registerEnum("CSS.CSSMediaSource", {MediaRule: "mediaRule", ImportRule: "importRule", LinkedSheet: "linkedSheet", InlineSheet: "inlineSheet"});
InspectorBackend.registerEnum("CSS.RegionRegionOverset", {Overset: "overset", Fit: "fit", Empty: "empty"});
InspectorBackend.registerEvent("CSS.mediaQueryResultChanged", []);
InspectorBackend.registerEvent("CSS.styleSheetChanged", ["styleSheetId"]);
InspectorBackend.registerEvent("CSS.styleSheetAdded", ["header"]);
InspectorBackend.registerEvent("CSS.styleSheetRemoved", ["styleSheetId"]);
InspectorBackend.registerEvent("CSS.namedFlowCreated", ["namedFlow"]);
InspectorBackend.registerEvent("CSS.namedFlowRemoved", ["documentNodeId", "flowName"]);
InspectorBackend.registerEvent("CSS.regionLayoutUpdated", ["namedFlow"]);
InspectorBackend.registerCommand("CSS.enable", [], []);
InspectorBackend.registerCommand("CSS.disable", [], []);
InspectorBackend.registerCommand("CSS.getMatchedStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "includePseudo", "type": "boolean", "optional": true}, {"name": "includeInherited", "type": "boolean", "optional": true}], ["matchedCSSRules", "pseudoElements", "inherited"]);
InspectorBackend.registerCommand("CSS.getInlineStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["inlineStyle", "attributesStyle"]);
InspectorBackend.registerCommand("CSS.getComputedStyleForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["computedStyle"]);
InspectorBackend.registerCommand("CSS.getAllStyleSheets", [], ["headers"]);
InspectorBackend.registerCommand("CSS.getStyleSheet", [{"name": "styleSheetId", "type": "string", "optional": false}], ["styleSheet"]);
InspectorBackend.registerCommand("CSS.getStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}], ["text"]);
InspectorBackend.registerCommand("CSS.setStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "text", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("CSS.setStyleText", [{"name": "styleId", "type": "object", "optional": false}, {"name": "text", "type": "string", "optional": false}], ["style"]);
InspectorBackend.registerCommand("CSS.setPropertyText", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "overwrite", "type": "boolean", "optional": false}], ["style"]);
InspectorBackend.registerCommand("CSS.toggleProperty", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "disable", "type": "boolean", "optional": false}], ["style"]);
InspectorBackend.registerCommand("CSS.setRuleSelector", [{"name": "ruleId", "type": "object", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]);
InspectorBackend.registerCommand("CSS.addRule", [{"name": "contextNodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]);
InspectorBackend.registerCommand("CSS.getSupportedCSSProperties", [], ["cssProperties"]);
InspectorBackend.registerCommand("CSS.forcePseudoState", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "forcedPseudoClasses", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("CSS.startSelectorProfiler", [], []);
InspectorBackend.registerCommand("CSS.stopSelectorProfiler", [], ["profile"]);
InspectorBackend.registerCommand("CSS.getNamedFlowCollection", [{"name": "documentNodeId", "type": "number", "optional": false}], ["namedFlows"]);


InspectorBackend.registerTimelineDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Timeline");
InspectorBackend.registerEvent("Timeline.eventRecorded", ["record"]);
InspectorBackend.registerCommand("Timeline.start", [{"name": "maxCallStackDepth", "type": "number", "optional": true}, {"name": "includeDomCounters", "type": "boolean", "optional": true}, {"name": "includeNativeMemoryStatistics", "type": "boolean", "optional": true}], []);
InspectorBackend.registerCommand("Timeline.stop", [], []);


InspectorBackend.registerDebuggerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Debugger");
InspectorBackend.registerEnum("Debugger.ScopeType", {Global: "global", Local: "local", With: "with", Closure: "closure", Catch: "catch"});
InspectorBackend.registerEvent("Debugger.globalObjectCleared", []);
InspectorBackend.registerEvent("Debugger.scriptParsed", ["scriptId", "url", "startLine", "startColumn", "endLine", "endColumn", "isContentScript", "sourceMapURL", "hasSourceURL"]);
InspectorBackend.registerEvent("Debugger.scriptFailedToParse", ["url", "scriptSource", "startLine", "errorLine", "errorMessage"]);
InspectorBackend.registerEvent("Debugger.breakpointResolved", ["breakpointId", "location"]);
InspectorBackend.registerEvent("Debugger.paused", ["callFrames", "reason", "data"]);
InspectorBackend.registerEvent("Debugger.resumed", []);
InspectorBackend.registerCommand("Debugger.enable", [], []);
InspectorBackend.registerCommand("Debugger.disable", [], []);
InspectorBackend.registerCommand("Debugger.setBreakpointsActive", [{"name": "active", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.setBreakpointByUrl", [{"name": "lineNumber", "type": "number", "optional": false}, {"name": "url", "type": "string", "optional": true}, {"name": "urlRegex", "type": "string", "optional": true}, {"name": "columnNumber", "type": "number", "optional": true}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "locations"]);
InspectorBackend.registerCommand("Debugger.setBreakpoint", [{"name": "location", "type": "object", "optional": false}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "actualLocation"]);
InspectorBackend.registerCommand("Debugger.removeBreakpoint", [{"name": "breakpointId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.continueToLocation", [{"name": "location", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.stepOver", [], []);
InspectorBackend.registerCommand("Debugger.stepInto", [], []);
InspectorBackend.registerCommand("Debugger.stepOut", [], []);
InspectorBackend.registerCommand("Debugger.pause", [], []);
InspectorBackend.registerCommand("Debugger.resume", [], []);
InspectorBackend.registerCommand("Debugger.searchInContent", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Debugger.canSetScriptSource", [], ["result"]);
InspectorBackend.registerCommand("Debugger.setScriptSource", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "scriptSource", "type": "string", "optional": false}, {"name": "preview", "type": "boolean", "optional": true}], ["callFrames", "result"]);
InspectorBackend.registerCommand("Debugger.restartFrame", [{"name": "callFrameId", "type": "string", "optional": false}], ["callFrames", "result"]);
InspectorBackend.registerCommand("Debugger.getScriptSource", [{"name": "scriptId", "type": "string", "optional": false}], ["scriptSource"]);
InspectorBackend.registerCommand("Debugger.getFunctionDetails", [{"name": "functionId", "type": "string", "optional": false}], ["details"]);
InspectorBackend.registerCommand("Debugger.setPauseOnExceptions", [{"name": "state", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.evaluateOnCallFrame", [{"name": "callFrameId", "type": "string", "optional": false}, {"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}, {"name": "generatePreview", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Debugger.compileScript", [{"name": "expression", "type": "string", "optional": false}, {"name": "sourceURL", "type": "string", "optional": false}], ["scriptId", "syntaxErrorMessage"]);
InspectorBackend.registerCommand("Debugger.runScript", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "contextId", "type": "number", "optional": true}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Debugger.setOverlayMessage", [{"name": "message", "type": "string", "optional": true}], []);
InspectorBackend.registerCommand("Debugger.setVariableValue", [{"name": "scopeNumber", "type": "number", "optional": false}, {"name": "variableName", "type": "string", "optional": false}, {"name": "newValue", "type": "object", "optional": false}, {"name": "callFrameId", "type": "string", "optional": true}, {"name": "functionObjectId", "type": "string", "optional": true}], []);


InspectorBackend.registerDOMDebuggerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOMDebugger");
InspectorBackend.registerEnum("DOMDebugger.DOMBreakpointType", {SubtreeModified: "subtree-modified", AttributeModified: "attribute-modified", NodeRemoved: "node-removed"});
InspectorBackend.registerCommand("DOMDebugger.setDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.setEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.setInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.setXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []);


InspectorBackend.registerProfilerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Profiler");
InspectorBackend.registerEnum("Profiler.ProfileHeaderTypeId", {CPU: "CPU", CSS: "CSS", HEAP: "HEAP"});
InspectorBackend.registerEvent("Profiler.addProfileHeader", ["header"]);
InspectorBackend.registerEvent("Profiler.setRecordingProfile", ["isProfiling"]);
InspectorBackend.registerEvent("Profiler.resetProfiles", []);
InspectorBackend.registerCommand("Profiler.enable", [], []);
InspectorBackend.registerCommand("Profiler.disable", [], []);
InspectorBackend.registerCommand("Profiler.start", [], []);
InspectorBackend.registerCommand("Profiler.stop", [], ["header"]);
InspectorBackend.registerCommand("Profiler.getProfileHeaders", [], ["headers"]);
InspectorBackend.registerCommand("Profiler.getCPUProfile", [{"name": "uid", "type": "number", "optional": false}], ["profile"]);
InspectorBackend.registerCommand("Profiler.removeProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Profiler.clearProfiles", [], []);


InspectorBackend.registerHeapProfilerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "HeapProfiler");
InspectorBackend.registerEvent("HeapProfiler.addProfileHeader", ["header"]);
InspectorBackend.registerEvent("HeapProfiler.addHeapSnapshotChunk", ["uid", "chunk"]);
InspectorBackend.registerEvent("HeapProfiler.finishHeapSnapshot", ["uid"]);
InspectorBackend.registerEvent("HeapProfiler.resetProfiles", []);
InspectorBackend.registerEvent("HeapProfiler.reportHeapSnapshotProgress", ["done", "total"]);
InspectorBackend.registerEvent("HeapProfiler.lastSeenObjectId", ["lastSeenObjectId", "timestamp"]);
InspectorBackend.registerEvent("HeapProfiler.heapStatsUpdate", ["statsUpdate"]);
InspectorBackend.registerCommand("HeapProfiler.getProfileHeaders", [], ["headers"]);
InspectorBackend.registerCommand("HeapProfiler.startTrackingHeapObjects", [], []);
InspectorBackend.registerCommand("HeapProfiler.stopTrackingHeapObjects", [], []);
InspectorBackend.registerCommand("HeapProfiler.getHeapSnapshot", [{"name": "uid", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("HeapProfiler.removeProfile", [{"name": "uid", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("HeapProfiler.clearProfiles", [], []);
InspectorBackend.registerCommand("HeapProfiler.takeHeapSnapshot", [{"name": "reportProgress", "type": "boolean", "optional": true}], []);
InspectorBackend.registerCommand("HeapProfiler.collectGarbage", [], []);
InspectorBackend.registerCommand("HeapProfiler.getObjectByHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["result"]);
InspectorBackend.registerCommand("HeapProfiler.getHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}], ["heapSnapshotObjectId"]);


InspectorBackend.registerWorkerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Worker");
InspectorBackend.registerEvent("Worker.workerCreated", ["workerId", "url", "inspectorConnected"]);
InspectorBackend.registerEvent("Worker.workerTerminated", ["workerId"]);
InspectorBackend.registerEvent("Worker.dispatchMessageFromWorker", ["workerId", "message"]);
InspectorBackend.registerEvent("Worker.disconnectedFromWorker", []);
InspectorBackend.registerCommand("Worker.enable", [], []);
InspectorBackend.registerCommand("Worker.disable", [], []);
InspectorBackend.registerCommand("Worker.sendMessageToWorker", [{"name": "workerId", "type": "number", "optional": false}, {"name": "message", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("Worker.canInspectWorkers", [], ["result"]);
InspectorBackend.registerCommand("Worker.connectToWorker", [{"name": "workerId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Worker.disconnectFromWorker", [{"name": "workerId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Worker.setAutoconnectToWorkers", [{"name": "value", "type": "boolean", "optional": false}], []);


InspectorBackend.registerCanvasDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Canvas");
InspectorBackend.registerEvent("Canvas.contextCreated", ["frameId"]);
InspectorBackend.registerEvent("Canvas.traceLogsRemoved", ["frameId", "traceLogId"]);
InspectorBackend.registerCommand("Canvas.enable", [], []);
InspectorBackend.registerCommand("Canvas.disable", [], []);
InspectorBackend.registerCommand("Canvas.dropTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Canvas.hasUninstrumentedCanvases", [], ["result"]);
InspectorBackend.registerCommand("Canvas.captureFrame", [{"name": "frameId", "type": "string", "optional": true}], ["traceLogId"]);
InspectorBackend.registerCommand("Canvas.startCapturing", [{"name": "frameId", "type": "string", "optional": true}], ["traceLogId"]);
InspectorBackend.registerCommand("Canvas.stopCapturing", [{"name": "traceLogId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Canvas.getTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}, {"name": "startOffset", "type": "number", "optional": true}, {"name": "maxLength", "type": "number", "optional": true}], ["traceLog"]);
InspectorBackend.registerCommand("Canvas.replayTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}, {"name": "stepNo", "type": "number", "optional": false}], ["resourceState"]);
InspectorBackend.registerCommand("Canvas.getResourceInfo", [{"name": "resourceId", "type": "string", "optional": false}], ["resourceInfo"]);
InspectorBackend.registerCommand("Canvas.getResourceState", [{"name": "traceLogId", "type": "string", "optional": false}, {"name": "resourceId", "type": "string", "optional": false}], ["resourceState"]);


InspectorBackend.registerInputDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Input");
InspectorBackend.registerCommand("Input.dispatchKeyEvent", [{"name": "type", "type": "string", "optional": false}, {"name": "modifiers", "type": "number", "optional": true}, {"name": "timestamp", "type": "number", "optional": true}, {"name": "text", "type": "string", "optional": true}, {"name": "unmodifiedText", "type": "string", "optional": true}, {"name": "keyIdentifier", "type": "string", "optional": true}, {"name": "windowsVirtualKeyCode", "type": "number", "optional": true}, {"name": "nativeVirtualKeyCode", "type": "number", "optional": true}, {"name": "macCharCode", "type": "number", "optional": true}, {"name": "autoRepeat", "type": "boolean", "optional": true}, {"name": "isKeypad", "type": "boolean", "optional": true}, {"name": "isSystemKey", "type": "boolean", "optional": true}], []);
InspectorBackend.registerCommand("Input.dispatchMouseEvent", [{"name": "type", "type": "string", "optional": false}, {"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "modifiers", "type": "number", "optional": true}, {"name": "timestamp", "type": "number", "optional": true}, {"name": "button", "type": "string", "optional": true}, {"name": "clickCount", "type": "number", "optional": true}], []);


InspectorBackend.registerLayerTreeDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "LayerTree");
InspectorBackend.registerEvent("LayerTree.layerTreeDidChange", []);
InspectorBackend.registerCommand("LayerTree.enable", [], []);
InspectorBackend.registerCommand("LayerTree.disable", [], []);
InspectorBackend.registerCommand("LayerTree.layersForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["layers"]);
InspectorBackend.registerCommand("LayerTree.reasonsForCompositingLayer", [{"name": "layerId", "type": "string", "optional": false}], ["compositingReasons"]);







if (!window.InspectorExtensionRegistry) {


WebInspector.InspectorExtensionRegistryStub = function()
{
}

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

var InspectorExtensionRegistry = new WebInspector.InspectorExtensionRegistryStub();

}





var InspectorFrontendAPI = {
_pendingCommands: [],

setAttachedWindow: function(side)
{
},

setDockSide: function(side)
{
if (WebInspector.dockController)
WebInspector.dockController.setDockSide(side);
},

showConsole: function()
{
WebInspector.showPanel("console");
},

showMainResourceForFrame: function(frameId)
{

},

showResources: function()
{
WebInspector.showPanel("resources");
},

setDockingUnavailable: function(unavailable)
{
WebInspector.setDockingUnavailable(unavailable);
},

enterInspectElementMode: function()
{
WebInspector.showPanel("elements");

if (WebInspector.inspectElementModeController)
WebInspector.inspectElementModeController.toggleSearch();
},

fileSystemsLoaded: function(fileSystems)
{
WebInspector.isolatedFileSystemDispatcher.fileSystemsLoaded(fileSystems);
},

fileSystemRemoved: function(fileSystemPath)
{
WebInspector.isolatedFileSystemDispatcher.fileSystemRemoved(fileSystemPath);
},

fileSystemAdded: function(errorMessage, fileSystem)
{
WebInspector.isolatedFileSystemDispatcher.fileSystemAdded(errorMessage, fileSystem);
},

savedURL: function(url)
{
WebInspector.fileManager.savedURL(url);
},

appendedToURL: function(url)
{
WebInspector.fileManager.appendedToURL(url);
},

setToolbarColors: function(backgroundColor, color)
{
WebInspector.setToolbarColors(backgroundColor, color);
},

evaluateForTest: function(callId, script)
{
WebInspector.evaluateForTestInFrontend(callId, script);
},

dispatch: function(signature)
{
if (InspectorFrontendAPI._isLoaded) {
var methodName = signature.shift();
return InspectorFrontendAPI[methodName].apply(InspectorFrontendAPI, signature);
}
InspectorFrontendAPI._pendingCommands.push(signature);
},

dispatchQueryParameters: function()
{
if ("dispatch" in WebInspector.queryParamsObject)
InspectorFrontendAPI.dispatch(JSON.parse(window.decodeURI(WebInspector.queryParamsObject["dispatch"])));
},


loadTimelineFromURL: function(url) 
{
(WebInspector.showPanel("timeline")).loadFromURL(url);
},

loadCompleted: function()
{
InspectorFrontendAPI._isLoaded = true;
for (var i = 0; i < InspectorFrontendAPI._pendingCommands.length; ++i)
InspectorFrontendAPI.dispatch(InspectorFrontendAPI._pendingCommands[i]);
InspectorFrontendAPI._pendingCommands = [];
if (window.opener)
window.opener.postMessage(["loadCompleted"], "*");
},

contextMenuItemSelected: function(id)
{
WebInspector.contextMenuItemSelected(id);
},

contextMenuCleared: function()
{
WebInspector.contextMenuCleared();
},

dispatchMessageAsync: function(messageObject)
{
WebInspector.dispatch(messageObject);
},

dispatchMessage: function(messageObject)
{
InspectorBackend.dispatch(messageObject);
}
}

if (window.opener && window.dispatchStandaloneTestRunnerMessages) {
function onMessageFromOpener(event)
{
if (event.source === window.opener)
InspectorFrontendAPI.dispatch(event.data);
}
window.addEventListener("message", onMessageFromOpener, true);
}






WebInspector.Object = function() {
}

WebInspector.Object.prototype = {

addEventListener: function(eventType, listener, thisObject)
{
console.assert(listener);

if (!this._listeners)
this._listeners = {};
if (!this._listeners[eventType])
this._listeners[eventType] = [];
this._listeners[eventType].push({ thisObject: thisObject, listener: listener });
},


removeEventListener: function(eventType, listener, thisObject)
{
console.assert(listener);

if (!this._listeners || !this._listeners[eventType])
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;
},


hasEventListeners: function(eventType)
{
if (!this._listeners || !this._listeners[eventType])
return false;
return true;
},


dispatchEventToListeners: function(eventType, eventData)
{
if (!this._listeners || !this._listeners[eventType])
return false;

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

return event.defaultPrevented;
}
}


WebInspector.Event = function(target, type, data)
{
this.target = target;
this.type = type;
this.data = data;
this.defaultPrevented = false;
this._stoppedPropagation = false;
}

WebInspector.Event.prototype = {
stopPropagation: function()
{
this._stoppedPropagation = true;
},

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


consume: function(preventDefault)
{
this.stopPropagation();
if (preventDefault)
this.preventDefault();
}
}


WebInspector.EventTarget = function()
{
}

WebInspector.EventTarget.prototype = {

addEventListener: function(eventType, listener, thisObject) { },


removeEventListener: function(eventType, listener, thisObject) { },

removeAllListeners: function() { },


hasEventListeners: function(eventType) { },


dispatchEventToListeners: function(eventType, eventData) { },
}

WebInspector.notifications = new WebInspector.Object();






var Preferences = {
maxInlineTextChildLength: 80,
minConsoleHeight: 75,
minSidebarWidth: 100,
minSidebarHeight: 75,
minElementsSidebarWidth: 200,
minElementsSidebarHeight: 200,
minScriptsSidebarWidth: 200,
applicationTitle: "Developer Tools - %s",
experimentsEnabled: false
}

var Capabilities = {
canShowFPSCounter: false,
canContinuouslyPaint: false,
canInspectWorkers: false
}


WebInspector.Settings = function()
{
this._eventSupport = new WebInspector.Object();
this._registry =   ({});

this.colorFormat = this.createSetting("colorFormat", "original");
this.consoleHistory = this.createSetting("consoleHistory", []);
this.domWordWrap = this.createSetting("domWordWrap", true);
this.eventListenersFilter = this.createSetting("eventListenersFilter", "all");
this.lastActivePanel = this.createSetting("lastActivePanel", "elements");
this.lastViewedScriptFile = this.createSetting("lastViewedScriptFile", "application");
this.monitoringXHREnabled = this.createSetting("monitoringXHREnabled", false);
this.preserveConsoleLog = this.createSetting("preserveConsoleLog", false);
this.resourcesLargeRows = this.createSetting("resourcesLargeRows", true);
this.resourcesSortOptions = this.createSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"});
this.resourceViewTab = this.createSetting("resourceViewTab", "preview");
this.showInheritedComputedStyleProperties = this.createSetting("showInheritedComputedStyleProperties", false);
this.showUserAgentStyles = this.createSetting("showUserAgentStyles", true);
this.watchExpressions = this.createSetting("watchExpressions", []);
this.breakpoints = this.createSetting("breakpoints", []);
this.eventListenerBreakpoints = this.createSetting("eventListenerBreakpoints", []);
this.domBreakpoints = this.createSetting("domBreakpoints", []);
this.xhrBreakpoints = this.createSetting("xhrBreakpoints", []);
this.sourceMapsEnabled = this.createSetting("sourceMapsEnabled", true);
this.cacheDisabled = this.createSetting("cacheDisabled", false);
this.overrideUserAgent = this.createSetting("overrideUserAgent", "");
this.userAgent = this.createSetting("userAgent", "");
this.deviceMetrics = this.createSetting("deviceMetrics", "");
this.deviceFitWindow = this.createSetting("deviceFitWindow", false);
this.emulateTouchEvents = this.createSetting("emulateTouchEvents", false);
this.showPaintRects = this.createSetting("showPaintRects", false);
this.continuousPainting = this.createSetting("continuousPainting", false);
this.showDebugBorders = this.createSetting("showDebugBorders", false);
this.showFPSCounter = this.createSetting("showFPSCounter", false);
this.showShadowDOM = this.createSetting("showShadowDOM", false);
this.zoomLevel = this.createSetting("zoomLevel", 0);
this.savedURLs = this.createSetting("savedURLs", {});
this.javaScriptDisabled = this.createSetting("javaScriptDisabled", false);
this.geolocationOverride = this.createSetting("geolocationOverride", "");
this.deviceOrientationOverride = this.createSetting("deviceOrientationOverride", "");
this.showHeapSnapshotObjectsHiddenProperties = this.createSetting("showHeaSnapshotObjectsHiddenProperties", false);
this.showNativeSnapshotUninstrumentedSize = this.createSetting("showNativeSnapshotUninstrumentedSize", false);
this.searchInContentScripts = this.createSetting("searchInContentScripts", false);
this.textEditorIndent = this.createSetting("textEditorIndent", "    ");
this.lastDockState = this.createSetting("lastDockState", "");
this.cssReloadEnabled = this.createSetting("cssReloadEnabled", false);
this.cssReloadTimeout = this.createSetting("cssReloadTimeout", 1000);
this.showCpuOnTimelineRuler = this.createSetting("showCpuOnTimelineRuler", false);
this.timelineStackFramesToCapture = this.createSetting("timelineStackFramesToCapture", 30);
this.timelineLimitStackFramesFlag = this.createSetting("timelineLimitStackFramesFlag", false);
this.showMetricsRulers = this.createSetting("showMetricsRulers", false);
this.emulatedCSSMedia = this.createSetting("emulatedCSSMedia", "print");
this.showToolbarIcons = this.createSetting("showToolbarIcons", false);
this.workerInspectorWidth = this.createSetting("workerInspectorWidth", 600);
this.workerInspectorHeight = this.createSetting("workerInspectorHeight", 600);
this.messageURLFilters = this.createSetting("messageURLFilters", {});
this.splitVerticallyWhenDockedToRight = this.createSetting("splitVerticallyWhenDockedToRight", true);
this.visiblePanels = this.createSetting("visiblePanels", {});
this.shortcutPanelSwitch = this.createSetting("shortcutPanelSwitch", false);
this.portForwardings = this.createSetting("portForwardings", []);
this.codemirror = this.createSetting("codemirror", false);
}

WebInspector.Settings.prototype = {

createSetting: function(key, defaultValue)
{
if (!this._registry[key])
this._registry[key] = new WebInspector.Setting(key, defaultValue, this._eventSupport, window.localStorage);
return this._registry[key];
}
}


WebInspector.Setting = function(name, defaultValue, eventSupport, storage)
{
this._name = name;
this._defaultValue = defaultValue;
this._eventSupport = eventSupport;
this._storage = storage;
}

WebInspector.Setting.prototype = {
addChangeListener: function(listener, thisObject)
{
this._eventSupport.addEventListener(this._name, listener, thisObject);
},

removeChangeListener: function(listener, thisObject)
{
this._eventSupport.removeEventListener(this._name, listener, thisObject);
},

get name()
{
return this._name;
},

get: function()
{
if (typeof this._value !== "undefined")
return this._value;

this._value = this._defaultValue;
if (this._storage && this._name in this._storage) {
try {
this._value = JSON.parse(this._storage[this._name]);
} catch(e) {
delete this._storage[this._name];
}
}
return this._value;
},

set: function(value)
{
this._value = value;
if (this._storage) {
try {
this._storage[this._name] = JSON.stringify(value);
} catch(e) {
console.error("Error saving setting with name:" + this._name);
}
}
this._eventSupport.dispatchEventToListeners(this._name, value);
}
}


WebInspector.ExperimentsSettings = function()
{
this._setting = WebInspector.settings.createSetting("experiments", {});
this._experiments = [];
this._enabledForTest = {};


this.nativeMemorySnapshots = this._createExperiment("nativeMemorySnapshots", "Native memory profiling");
this.nativeMemoryTimeline = this._createExperiment("nativeMemoryTimeline", "Native memory timeline");
this.fileSystemInspection = this._createExperiment("fileSystemInspection", "FileSystem inspection");
this.canvasInspection = this._createExperiment("canvasInspection ", "Canvas inspection");
this.sass = this._createExperiment("sass", "Sass stylesheet debugging");
this.cssRegions = this._createExperiment("cssRegions", "CSS Regions Support");
this.showOverridesInDrawer = this._createExperiment("showOverridesInDrawer", "Show Overrides in drawer");
this.showWhitespaceInEditor = this._createExperiment("showWhitespaceInEditor", "Show whitespace characters in editor");
this.customizableToolbar = this._createExperiment("customizableToolbar", "Enable toolbar customization");
this.tethering = this._createExperiment("tethering", "Enable port forwarding");
this.drawerOverlay = this._createExperiment("drawerOverlay", "Open console as overlay");
this.heapObjectsTracking = this._createExperiment("heapObjectsTracking", "Enable heap objects tracking profile type");

this._cleanUpSetting();
}

WebInspector.ExperimentsSettings.prototype = {

get experiments()
{
return this._experiments.slice();
},


get experimentsEnabled()
{
return Preferences.experimentsEnabled || ("experiments" in WebInspector.queryParamsObject);
},


_createExperiment: function(experimentName, experimentTitle)
{
var experiment = new WebInspector.Experiment(this, experimentName, experimentTitle);
this._experiments.push(experiment);
return experiment;
},


isEnabled: function(experimentName)
{
if (this._enabledForTest[experimentName])
return true;

if (!this.experimentsEnabled)
return false;

var experimentsSetting = this._setting.get();
return experimentsSetting[experimentName];
},


setEnabled: function(experimentName, enabled)
{
var experimentsSetting = this._setting.get();
experimentsSetting[experimentName] = enabled;
this._setting.set(experimentsSetting);
},


_enableForTest: function(experimentName)
{
this._enabledForTest[experimentName] = true;
},

_cleanUpSetting: function()
{
var experimentsSetting = this._setting.get();
var cleanedUpExperimentSetting = {};
for (var i = 0; i < this._experiments.length; ++i) {
var experimentName = this._experiments[i].name;
if (experimentsSetting[experimentName])
cleanedUpExperimentSetting[experimentName] = true;
}
this._setting.set(cleanedUpExperimentSetting);
}
}


WebInspector.Experiment = function(experimentsSettings, name, title)
{
this._name = name;
this._title = title;
this._experimentsSettings = experimentsSettings;
}

WebInspector.Experiment.prototype = {

get name()
{
return this._name;
},


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


isEnabled: function()
{
return this._experimentsSettings.isEnabled(this._name);
},


setEnabled: function(enabled)
{
return this._experimentsSettings.setEnabled(this._name, enabled);
},

enableForTest: function()
{
this._experimentsSettings._enableForTest(this._name);
}
}


WebInspector.VersionController = function()
{
}

WebInspector.VersionController.currentVersion = 2;

WebInspector.VersionController.prototype = {
updateVersion: function()
{
var versionSetting = WebInspector.settings.createSetting("inspectorVersion", 0);
var currentVersion = WebInspector.VersionController.currentVersion;
var oldVersion = versionSetting.get();
var methodsToRun = this._methodsToRunToUpdateVersion(oldVersion, currentVersion);
for (var i = 0; i < methodsToRun.length; ++i)
this[methodsToRun[i]].call(this);
versionSetting.set(currentVersion);
},


_methodsToRunToUpdateVersion: function(oldVersion, currentVersion)
{
var result = [];
for (var i = oldVersion; i < currentVersion; ++i)
result.push("_updateVersionFrom" + i + "To" + (i + 1));
return result;
},

_updateVersionFrom0To1: function()
{
this._clearBreakpointsWhenTooMany(WebInspector.settings.breakpoints, 500000);
},

_updateVersionFrom1To2: function()
{
var versionSetting = WebInspector.settings.createSetting("previouslyViewedFiles", []);
versionSetting.set([]);
},


_clearBreakpointsWhenTooMany: function(breakpointsSetting, maxBreakpointsCount)
{


if (breakpointsSetting.get().length > maxBreakpointsCount)
breakpointsSetting.set([]);
}
}

WebInspector.settings = new WebInspector.Settings();
WebInspector.experimentsSettings = new WebInspector.ExperimentsSettings();






WebInspector.View = function()
{
this.element = document.createElement("div");
this.element.__view = this;
this._visible = true;
this._isRoot = false;
this._isShowing = false;
this._children = [];
this._hideOnDetach = false;
this._cssFiles = [];
this._notificationDepth = 0;
}

WebInspector.View._cssFileToVisibleViewCount = {};
WebInspector.View._cssFileToStyleElement = {};
WebInspector.View._cssUnloadTimeout = 2000;

WebInspector.View.prototype = {

statusBarText: function()
{
return null;
},

markAsRoot: function()
{
WebInspector.View._assert(!this.element.parentElement, "Attempt to mark as root attached node");
this._isRoot = true;
},


parentView: function()
{
return this._parentView;
},

isShowing: function()
{
return this._isShowing;
},

setHideOnDetach: function()
{
this._hideOnDetach = true;
},


_inNotification: function()
{
return !!this._notificationDepth || (this._parentView && this._parentView._inNotification());
},

_parentIsShowing: function()
{
if (this._isRoot)
return true;
return this._parentView && this._parentView.isShowing();
},


_callOnVisibleChildren: function(method)
{
var copy = this._children.slice();
for (var i = 0; i < copy.length; ++i) {
if (copy[i]._parentView === this && copy[i]._visible)
method.call(copy[i]);
}
},

_processWillShow: function()
{
this._loadCSSIfNeeded();
this._callOnVisibleChildren(this._processWillShow);
},

_processWasShown: function()
{
if (this._inNotification())
return;
this._isShowing = true;
this.restoreScrollPositions();
this._notify(this.wasShown);
this._notify(this.onResize);
this._callOnVisibleChildren(this._processWasShown);
},

_processWillHide: function()
{
if (this._inNotification())
return;
this.storeScrollPositions();

this._callOnVisibleChildren(this._processWillHide);
this._notify(this.willHide);
this._isShowing = false;
},

_processWasHidden: function()
{
this._disableCSSIfNeeded();
this._callOnVisibleChildren(this._processWasHidden);
},

_processOnResize: function()
{
if (this._inNotification())
return;
if (!this.isShowing())
return;
this._notify(this.onResize);
this._callOnVisibleChildren(this._processOnResize);
},


_notify: function(notification)
{
++this._notificationDepth;
try {
notification.call(this);
} finally {
--this._notificationDepth;
}
},

wasShown: function()
{
},

willHide: function()
{
},

onResize: function()
{
},


show: function(parentElement, insertBefore)
{
WebInspector.View._assert(parentElement, "Attempt to attach view with no parent element");


if (this.element.parentElement !== parentElement) {
if (this.element.parentElement)
this.detach();

var currentParent = parentElement;
while (currentParent && !currentParent.__view)
currentParent = currentParent.parentElement;

if (currentParent) {
this._parentView = currentParent.__view;
this._parentView._children.push(this);
this._isRoot = false;
} else
WebInspector.View._assert(this._isRoot, "Attempt to attach view to orphan node");
} else if (this._visible)
return;

this._visible = true;

if (this._parentIsShowing())
this._processWillShow();

this.element.addStyleClass("visible");


if (this.element.parentElement !== parentElement) {
WebInspector.View._incrementViewCounter(parentElement, this.element);
if (insertBefore)
WebInspector.View._originalInsertBefore.call(parentElement, this.element, insertBefore);
else
WebInspector.View._originalAppendChild.call(parentElement, this.element);
}

if (this._parentIsShowing())
this._processWasShown();
},


detach: function(overrideHideOnDetach)
{
var parentElement = this.element.parentElement;
if (!parentElement)
return;

if (this._parentIsShowing())
this._processWillHide();

if (this._hideOnDetach && !overrideHideOnDetach) {
this.element.removeStyleClass("visible");
this._visible = false;
if (this._parentIsShowing())
this._processWasHidden();
return;
}


WebInspector.View._decrementViewCounter(parentElement, this.element);
WebInspector.View._originalRemoveChild.call(parentElement, this.element);

this._visible = false;
if (this._parentIsShowing())
this._processWasHidden();


if (this._parentView) {
var childIndex = this._parentView._children.indexOf(this);
WebInspector.View._assert(childIndex >= 0, "Attempt to remove non-child view");
this._parentView._children.splice(childIndex, 1);
this._parentView = null;
} else
WebInspector.View._assert(this._isRoot, "Removing non-root view from DOM");
},

detachChildViews: function()
{
var children = this._children.slice();
for (var i = 0; i < children.length; ++i)
children[i].detach();
},

elementsToRestoreScrollPositionsFor: function()
{
return [this.element];
},

storeScrollPositions: function()
{
var elements = this.elementsToRestoreScrollPositionsFor();
for (var i = 0; i < elements.length; ++i) {
var container = elements[i];
container._scrollTop = container.scrollTop;
container._scrollLeft = container.scrollLeft;
}
},

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;
if (container._scrollLeft)
container.scrollLeft = container._scrollLeft;
}
},

canHighlightLine: function()
{
return false;
},

highlightLine: function(line)
{
},

doResize: function()
{
this._processOnResize();
},

registerRequiredCSS: function(cssFile)
{
if (window.flattenImports)
cssFile = cssFile.split("/").reverse()[0];
this._cssFiles.push(cssFile);
},

_loadCSSIfNeeded: function()
{
for (var i = 0; i < this._cssFiles.length; ++i) {
var cssFile = this._cssFiles[i];

var viewsWithCSSFile = WebInspector.View._cssFileToVisibleViewCount[cssFile];
WebInspector.View._cssFileToVisibleViewCount[cssFile] = (viewsWithCSSFile || 0) + 1;
if (!viewsWithCSSFile)
this._doLoadCSS(cssFile);
}
},

_doLoadCSS: function(cssFile)
{
var styleElement = WebInspector.View._cssFileToStyleElement[cssFile];
if (styleElement) {
styleElement.disabled = false;
return;
}

if (window.debugCSS) {  
styleElement = document.createElement("link");
styleElement.rel = "stylesheet";
styleElement.type = "text/css";
styleElement.href = cssFile;
} else {
var xhr = new XMLHttpRequest();
xhr.open("GET", cssFile, false);
xhr.send(null);

styleElement = document.createElement("style");
styleElement.type = "text/css";
styleElement.textContent = xhr.responseText;
}
document.head.insertBefore(styleElement, document.head.firstChild);

WebInspector.View._cssFileToStyleElement[cssFile] = styleElement;
},

_disableCSSIfNeeded: function()
{
var scheduleUnload = !!WebInspector.View._cssUnloadTimer;

for (var i = 0; i < this._cssFiles.length; ++i) {
var cssFile = this._cssFiles[i];

if (!--WebInspector.View._cssFileToVisibleViewCount[cssFile])
scheduleUnload = true;
}

function doUnloadCSS()
{
delete WebInspector.View._cssUnloadTimer;

for (cssFile in WebInspector.View._cssFileToVisibleViewCount) {
if (WebInspector.View._cssFileToVisibleViewCount.hasOwnProperty(cssFile)
&& !WebInspector.View._cssFileToVisibleViewCount[cssFile])
WebInspector.View._cssFileToStyleElement[cssFile].disabled = true;
}
}

if (scheduleUnload) {
if (WebInspector.View._cssUnloadTimer)
clearTimeout(WebInspector.View._cssUnloadTimer);

WebInspector.View._cssUnloadTimer = setTimeout(doUnloadCSS, WebInspector.View._cssUnloadTimeout)
}
},

printViewHierarchy: function()
{
var lines = [];
this._collectViewHierarchy("", lines);
console.log(lines.join("\n"));
},

_collectViewHierarchy: function(prefix, lines)
{
lines.push(prefix + "[" + this.element.className + "]" + (this._children.length ? " {" : ""));

for (var i = 0; i < this._children.length; ++i)
this._children[i]._collectViewHierarchy(prefix + "    ", lines);

if (this._children.length)
lines.push(prefix + "}");
},


defaultFocusedElement: function()
{
return this._defaultFocusedElement || this.element;
},


setDefaultFocusedElement: function(element)
{
this._defaultFocusedElement = element;
},

focus: function()
{
var element = this.defaultFocusedElement();
if (!element || element.isAncestor(document.activeElement))
return;

WebInspector.setCurrentFocusElement(element);
},


measurePreferredSize: function()
{
this._loadCSSIfNeeded();
WebInspector.View._originalAppendChild.call(document.body, this.element);
this.element.positionAt(0, 0);
var result = new Size(this.element.offsetWidth, this.element.offsetHeight);
this.element.positionAt(undefined, undefined);
WebInspector.View._originalRemoveChild.call(document.body, this.element);
this._disableCSSIfNeeded();
return result;
},

__proto__: WebInspector.Object.prototype
}

WebInspector.View._originalAppendChild = Element.prototype.appendChild;
WebInspector.View._originalInsertBefore = Element.prototype.insertBefore;
WebInspector.View._originalRemoveChild = Element.prototype.removeChild;
WebInspector.View._originalRemoveChildren = Element.prototype.removeChildren;

WebInspector.View._incrementViewCounter = function(parentElement, childElement)
{
var count = (childElement.__viewCounter || 0) + (childElement.__view ? 1 : 0);
if (!count)
return;

while (parentElement) {
parentElement.__viewCounter = (parentElement.__viewCounter || 0) + count;
parentElement = parentElement.parentElement;
}
}

WebInspector.View._decrementViewCounter = function(parentElement, childElement)
{
var count = (childElement.__viewCounter || 0) + (childElement.__view ? 1 : 0);
if (!count)
return;

while (parentElement) {
parentElement.__viewCounter -= count;
parentElement = parentElement.parentElement;
}
}

WebInspector.View._assert = function(condition, message)
{
if (!condition) {
console.trace();
throw new Error(message);
}
}

Element.prototype.appendChild = function(child)
{
WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation.");
return WebInspector.View._originalAppendChild.call(this, child);
}

Element.prototype.insertBefore = function(child, anchor)
{
WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation.");
return WebInspector.View._originalInsertBefore.call(this, child, anchor);
}


Element.prototype.removeChild = function(child)
{
WebInspector.View._assert(!child.__viewCounter && !child.__view, "Attempt to remove element containing view via regular DOM operation");
return WebInspector.View._originalRemoveChild.call(this, child);
}

Element.prototype.removeChildren = function()
{
WebInspector.View._assert(!this.__viewCounter, "Attempt to remove element containing view via regular DOM operation");
WebInspector.View._originalRemoveChildren.call(this);
}






WebInspector.installDragHandle = function(element, elementDragStart, elementDrag, elementDragEnd, cursor)
{
element.addEventListener("mousedown", WebInspector._elementDragStart.bind(WebInspector, elementDragStart, elementDrag, elementDragEnd, cursor), false);
}


WebInspector._elementDragStart = function(elementDragStart, elementDrag, elementDragEnd, cursor, event)
{

if (event.button || (WebInspector.isMac() && event.ctrlKey))
return;

if (WebInspector._elementDraggingEventListener)
return;

if (elementDragStart && !elementDragStart(event))
return;

if (WebInspector._elementDraggingGlassPane) {
WebInspector._elementDraggingGlassPane.dispose();
delete WebInspector._elementDraggingGlassPane;
}

var targetDocument = event.target.ownerDocument;

WebInspector._elementDraggingEventListener = elementDrag;
WebInspector._elementEndDraggingEventListener = elementDragEnd;
WebInspector._mouseOutWhileDraggingTargetDocument = targetDocument;

targetDocument.addEventListener("mousemove", WebInspector._elementDragMove, true);
targetDocument.addEventListener("mouseup", WebInspector._elementDragEnd, true);
targetDocument.addEventListener("mouseout", WebInspector._mouseOutWhileDragging, true);

targetDocument.body.style.cursor = cursor;

event.preventDefault();
}

WebInspector._mouseOutWhileDragging = function()
{
WebInspector._unregisterMouseOutWhileDragging();
WebInspector._elementDraggingGlassPane = new WebInspector.GlassPane();
}

WebInspector._unregisterMouseOutWhileDragging = function()
{
if (!WebInspector._mouseOutWhileDraggingTargetDocument)
return;
WebInspector._mouseOutWhileDraggingTargetDocument.removeEventListener("mouseout", WebInspector._mouseOutWhileDragging, true);
delete WebInspector._mouseOutWhileDraggingTargetDocument;
}

WebInspector._elementDragMove = function(event)
{
if (WebInspector._elementDraggingEventListener(event))
WebInspector._cancelDragEvents(event);
}

WebInspector._cancelDragEvents = function(event)
{
var targetDocument = event.target.ownerDocument;
targetDocument.removeEventListener("mousemove", WebInspector._elementDragMove, true);
targetDocument.removeEventListener("mouseup", WebInspector._elementDragEnd, true);
WebInspector._unregisterMouseOutWhileDragging();

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

if (WebInspector._elementDraggingGlassPane)
WebInspector._elementDraggingGlassPane.dispose();

delete WebInspector._elementDraggingGlassPane;
delete WebInspector._elementDraggingEventListener;
delete WebInspector._elementEndDraggingEventListener;
}

WebInspector._elementDragEnd = function(event)
{
var elementDragEnd = WebInspector._elementEndDraggingEventListener;

WebInspector._cancelDragEvents(event);

event.preventDefault();
if (elementDragEnd)
elementDragEnd(event);
}


WebInspector.GlassPane = function()
{
this.element = document.createElement("div");
this.element.style.cssText = "position:absolute;top:0;bottom:0;left:0;right:0;background-color:transparent;z-index:1000;";
this.element.id = "glass-pane-for-drag";
document.body.appendChild(this.element);
WebInspector._glassPane = this;
}

WebInspector.GlassPane.prototype = {
dispose: function()
{
delete WebInspector._glassPane;
WebInspector.inspectorView.focus();
if (this.element.parentElement)
this.element.parentElement.removeChild(this.element);
}
}

WebInspector.isBeingEdited = function(element)
{
if (element.hasStyleClass("text-prompt") || element.nodeName === "INPUT" || element.nodeName === "TEXTAREA")
return true;

if (!WebInspector.__editingCount)
return false;

while (element) {
if (element.__editing)
return true;
element = element.parentElement;
}
return false;
}

WebInspector.markBeingEdited = function(element, value)
{
if (value) {
if (element.__editing)
return false;
element.addStyleClass("being-edited");
element.__editing = true;
WebInspector.__editingCount = (WebInspector.__editingCount || 0) + 1;
} else {
if (!element.__editing)
return false;
element.removeStyleClass("being-edited");
delete element.__editing;
--WebInspector.__editingCount;
}
return true;
}


WebInspector.EditingConfig = function(commitHandler, cancelHandler, context)
{
this.commitHandler = commitHandler;
this.cancelHandler = cancelHandler
this.context = context;


this.pasteHandler;


this.multiline;


this.customFinishHandler;
}

WebInspector.EditingConfig.prototype = {
setPasteHandler: function(pasteHandler)
{
this.pasteHandler = pasteHandler;
},


setMultilineOptions: function(initialValue, mode, theme, lineWrapping, smartIndent)
{
this.multiline = true;
this.initialValue = initialValue;
this.mode = mode;
this.theme = theme;
this.lineWrapping = lineWrapping;
this.smartIndent = smartIndent;
},

setCustomFinishHandler: function(customFinishHandler)
{
this.customFinishHandler = customFinishHandler;
}
}

WebInspector.CSSNumberRegex = /^(-?(?:\d+(?:\.\d+)?|\.\d+))$/;

WebInspector.StyleValueDelimiters = " \xA0\t\n\"':;,/()";



WebInspector._valueModificationDirection = function(event)
{
var direction = null;
if (event.type === "mousewheel") {
if (event.wheelDeltaY > 0)
direction = "Up";
else if (event.wheelDeltaY < 0)
direction = "Down";
} else {
if (event.keyIdentifier === "Up" || event.keyIdentifier === "PageUp")
direction = "Up";
else if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown")
direction = "Down";        
}
return direction;
}


WebInspector._modifiedHexValue = function(hexString, event)
{
var direction = WebInspector._valueModificationDirection(event);
if (!direction)
return hexString;

var number = parseInt(hexString, 16);
if (isNaN(number) || !isFinite(number))
return hexString;

var maxValue = Math.pow(16, hexString.length) - 1;
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
var delta;

if (arrowKeyOrMouseWheelEvent)
delta = (direction === "Up") ? 1 : -1;
else
delta = (event.keyIdentifier === "PageUp") ? 16 : -16;

if (event.shiftKey)
delta *= 16;

var result = number + delta;
if (result < 0)
result = 0; 
else if (result > maxValue)
return hexString;


var resultString = result.toString(16).toUpperCase();
for (var i = 0, lengthDelta = hexString.length - resultString.length; i < lengthDelta; ++i)
resultString = "0" + resultString;
return resultString;
}


WebInspector._modifiedFloatNumber = function(number, event)
{
var direction = WebInspector._valueModificationDirection(event);
if (!direction)
return number;

var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");



var changeAmount = 1;
if (event.shiftKey && !arrowKeyOrMouseWheelEvent)
changeAmount = 100;
else if (event.shiftKey || !arrowKeyOrMouseWheelEvent)
changeAmount = 10;
else if (event.altKey)
changeAmount = 0.1;

if (direction === "Down")
changeAmount *= -1;



var result = Number((number + changeAmount).toFixed(6));
if (!String(result).match(WebInspector.CSSNumberRegex))
return null;

return result;
}


WebInspector.handleElementValueModifications = function(event, element, finishHandler, suggestionHandler, customNumberHandler)
{
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
if (!arrowKeyOrMouseWheelEvent && !pageKeyPressed)
return false;

var selection = window.getSelection();
if (!selection.rangeCount)
return false;

var selectionRange = selection.getRangeAt(0);
if (!selectionRange.commonAncestorContainer.isSelfOrDescendant(element))
return false;

var originalValue = element.textContent;
var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StyleValueDelimiters, element);
var wordString = wordRange.toString();

if (suggestionHandler && suggestionHandler(wordString))
return false;

var replacementString;
var prefix, suffix, number;

var matches;
matches = /(.*#)([\da-fA-F]+)(.*)/.exec(wordString);
if (matches && matches.length) {
prefix = matches[1];
suffix = matches[3];
number = WebInspector._modifiedHexValue(matches[2], event);

if (customNumberHandler)
number = customNumberHandler(number);

replacementString = prefix + number + suffix;
} else {
matches = /(.*?)(-?(?:\d+(?:\.\d+)?|\.\d+))(.*)/.exec(wordString);
if (matches && matches.length) {
prefix = matches[1];
suffix = matches[3];
number = WebInspector._modifiedFloatNumber(parseFloat(matches[2]), event);


if (number === null)                
return false;

if (customNumberHandler)
number = customNumberHandler(number);

replacementString = prefix + number + suffix;
}
}

if (replacementString) {
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.handled = true;
event.preventDefault();

if (finishHandler)
finishHandler(originalValue, replacementString);

return true;
}
return false;
}


WebInspector.startEditing = function(element, config)
{
if (!WebInspector.markBeingEdited(element, true))
return null;

config = config || new WebInspector.EditingConfig(function() {}, function() {});
var committedCallback = config.commitHandler;
var cancelledCallback = config.cancelHandler;
var pasteCallback = config.pasteHandler;
var context = config.context;
var isMultiline = config.multiline || false;
var oldText = isMultiline ? config.initialValue : getContent(element);
var moveDirection = "";
var oldTabIndex;
var codeMirror;
var cssLoadView;


function consumeCopy(e)
{
e.consume();
}

if (isMultiline) {
loadScript("CodeMirrorTextEditor.js");
cssLoadView = new WebInspector.CodeMirrorCSSLoadView();
cssLoadView.show(element);
WebInspector.setCurrentFocusElement(element);
element.addEventListener("copy", consumeCopy, true);
codeMirror = window.CodeMirror(element, {
mode: config.mode,
lineWrapping: config.lineWrapping,
smartIndent: config.smartIndent,
autofocus: true,
theme: config.theme,
value: oldText
});
codeMirror.getWrapperElement().addStyleClass("source-code");
} else {
element.addStyleClass("editing");

oldTabIndex = element.getAttribute("tabIndex");
if (typeof oldTabIndex !== "number" || oldTabIndex < 0)
element.tabIndex = 0;
WebInspector.setCurrentFocusElement(element);
}


function blurEventListener(e) {
if (!isMultiline || !e || !e.relatedTarget || !e.relatedTarget.isSelfOrDescendant(element))
editingCommitted.call(element);
}

function getContent(element) {
if (isMultiline)
return codeMirror.getValue();

if (element.tagName === "INPUT" && element.type === "text")
return element.value;

return element.textContent;
}


function cleanUpAfterEditing()
{
WebInspector.markBeingEdited(element, false);

element.removeEventListener("blur", blurEventListener, isMultiline);
element.removeEventListener("keydown", keyDownEventListener, true);
if (pasteCallback)
element.removeEventListener("paste", pasteEventListener, true);

WebInspector.restoreFocusFromElement(element);

if (isMultiline) {
element.removeEventListener("copy", consumeCopy, true);
cssLoadView.detach();
return;
}

this.removeStyleClass("editing");

if (typeof oldTabIndex !== "number")
element.removeAttribute("tabIndex");
else
this.tabIndex = oldTabIndex;
this.scrollTop = 0;
this.scrollLeft = 0;
}


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

cleanUpAfterEditing.call(this);

cancelledCallback(this, context);
}


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

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

function defaultFinishHandler(event)
{
var isMetaOrCtrl = WebInspector.isMac() ?
event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !isMultiline || isMetaOrCtrl))
return "commit";
else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
return "cancel";
else if (!isMultiline && event.keyIdentifier === "U+0009") 
return "move-" + (event.shiftKey ? "backward" : "forward");
}

function handleEditingResult(result, event)
{
if (result === "commit") {
editingCommitted.call(element);
event.consume(true);
} else if (result === "cancel") {
editingCancelled.call(element);
event.consume(true);
} else if (result && result.startsWith("move-")) {
moveDirection = result.substring(5);
if (event.keyIdentifier !== "U+0009")
blurEventListener();
}
}

function pasteEventListener(event)
{
var result = pasteCallback(event);
handleEditingResult(result, event);
}

function keyDownEventListener(event)
{
var handler = config.customFinishHandler || defaultFinishHandler;
var result = handler(event);
handleEditingResult(result, event);
}

element.addEventListener("blur", blurEventListener, isMultiline);
element.addEventListener("keydown", keyDownEventListener, true);
if (pasteCallback)
element.addEventListener("paste", pasteEventListener, true);

return {
cancel: editingCancelled.bind(element),
commit: editingCommitted.bind(element),
codeMirror: codeMirror 
};
}


Number.secondsToString = function(seconds, higherResolution)
{
if (!isFinite(seconds))
return "-";

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

var ms = seconds * 1000;
if (higherResolution && ms < 1000)
return WebInspector.UIString("%.3f\u2009ms", ms);
else if (ms < 1000)
return WebInspector.UIString("%.0f\u2009ms", ms);

if (seconds < 60)
return WebInspector.UIString("%.2f\u2009s", seconds);

var minutes = seconds / 60;
if (minutes < 60)
return WebInspector.UIString("%.1f\u2009min", minutes);

var hours = minutes / 60;
if (hours < 24)
return WebInspector.UIString("%.1f\u2009hrs", hours);

var days = hours / 24;
return WebInspector.UIString("%.1f\u2009days", days);
}


Number.bytesToString = function(bytes)
{
if (bytes < 1024)
return WebInspector.UIString("%.0f\u2009B", bytes);

var kilobytes = bytes / 1024;
if (kilobytes < 100)
return WebInspector.UIString("%.1f\u2009KB", kilobytes);
if (kilobytes < 1024)
return WebInspector.UIString("%.0f\u2009KB", kilobytes);

var megabytes = kilobytes / 1024;
if (megabytes < 100)
return WebInspector.UIString("%.1f\u2009MB", megabytes);
else
return WebInspector.UIString("%.0f\u2009MB", megabytes);
}

Number.withThousandsSeparator = function(num)
{
var str = num + "";
var re = /(\d+)(\d{3})/;
while (str.match(re))
str = str.replace(re, "$1\u2009$2"); 
return str;
}

WebInspector.useLowerCaseMenuTitles = function()
{
return WebInspector.platform() === "windows";
}

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

WebInspector.openLinkExternallyLabel = function()
{
return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in new tab" : "Open Link in New Tab");
}

WebInspector.copyLinkAddressLabel = function()
{
return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy link address" : "Copy Link Address");
}

WebInspector.platform = function()
{
if (!WebInspector._platform)
WebInspector._platform = InspectorFrontendHost.platform();
return WebInspector._platform;
}

WebInspector.isMac = function()
{
if (typeof WebInspector._isMac === "undefined")
WebInspector._isMac = WebInspector.platform() === "mac";

return WebInspector._isMac;
}

WebInspector.isWin = function()
{
if (typeof WebInspector._isWin === "undefined")
WebInspector._isWin = WebInspector.platform() === "windows";

return WebInspector._isWin;
}

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

WebInspector.platformFlavor = function()
{
function detectFlavor()
{
const userAgent = navigator.userAgent;

if (WebInspector.platform() === "windows") {
var match = userAgent.match(/Windows NT (\d+)\.(?:\d+)/);
if (match && match[1] >= 6)
return WebInspector.PlatformFlavor.WindowsVista;
return null;
} else if (WebInspector.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:
return WebInspector.PlatformFlavor.MacSnowLeopard;
case 7:
return WebInspector.PlatformFlavor.MacLion;
case 8:
return WebInspector.PlatformFlavor.MacMountainLion;
default:
return "";
}
}
}

if (!WebInspector._platformFlavor)
WebInspector._platformFlavor = detectFlavor();

return WebInspector._platformFlavor;
}

WebInspector.port = function()
{
if (!WebInspector._port)
WebInspector._port = InspectorFrontendHost.port();

return WebInspector._port;
}

WebInspector.installPortStyles = function()
{
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);
}

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.previousFocusElement = function()
{
return WebInspector._previousFocusElement;
}

WebInspector.currentFocusElement = function()
{
return WebInspector._currentFocusElement;
}

WebInspector._focusChanged = function(event)
{
WebInspector.setCurrentFocusElement(event.target);
}

WebInspector._textInputTypes = ["text", "search", "tel", "url", "email", "password"].keySet(); 
WebInspector._isTextEditingElement = function(element)
{
if (element instanceof HTMLInputElement)
return element.type in WebInspector._textInputTypes;

if (element instanceof HTMLTextAreaElement)
return true;

return false;
}

WebInspector.setCurrentFocusElement = function(x)
{
if (WebInspector._glassPane && x && !WebInspector._glassPane.element.isAncestor(x))
return;
if (WebInspector._currentFocusElement !== x)
WebInspector._previousFocusElement = WebInspector._currentFocusElement;
WebInspector._currentFocusElement = x;

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




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

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

WebInspector.restoreFocusFromElement = function(element)
{
if (element && element.isSelfOrAncestor(WebInspector.currentFocusElement()))
WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement());
}

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.highlightSearchResult = function(element, offset, length, domChanges)
{
var result = WebInspector.highlightSearchResults(element, [{offset: offset, length: length }], domChanges);
return result.length ? result[0] : null;
}


WebInspector.highlightSearchResults = function(element, resultRanges, changes)
{
return WebInspector.highlightRangesWithStyleClass(element, resultRanges, "webkit-search-result", changes);
}


WebInspector.highlightRangesWithStyleClass = function(element, resultRanges, styleClass, changes)
{
changes = changes || [];
var highlightNodes = [];
var lineText = element.textContent;
var ownerDocument = element.ownerDocument;
var textNodeSnapshot = ownerDocument.evaluate(".//text()", element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

var snapshotLength = textNodeSnapshot.snapshotLength;
if (snapshotLength === 0)
return highlightNodes;

var nodeRanges = [];
var rangeEndOffset = 0;
for (var i = 0; i < snapshotLength; ++i) {
var range = {};
range.offset = rangeEndOffset;
range.length = textNodeSnapshot.snapshotItem(i).textContent.length;
rangeEndOffset = range.offset + range.length;
nodeRanges.push(range);
}

var startIndex = 0;
for (var i = 0; i < resultRanges.length; ++i) {
var startOffset = resultRanges[i].offset;
var endOffset = startOffset + resultRanges[i].length;

while (startIndex < snapshotLength && nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset)
startIndex++;
var endIndex = startIndex;
while (endIndex < snapshotLength && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset)
endIndex++;
if (endIndex === snapshotLength)
break;

var highlightNode = ownerDocument.createElement("span");
highlightNode.className = styleClass;
highlightNode.textContent = lineText.substring(startOffset, endOffset);

var lastTextNode = textNodeSnapshot.snapshotItem(endIndex);
var lastText = lastTextNode.textContent;
lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset);
changes.push({ node: lastTextNode, type: "changed", oldText: lastText, newText: lastTextNode.textContent });

if (startIndex === endIndex) {
lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode);
changes.push({ node: highlightNode, type: "added", nextSibling: lastTextNode, parent: lastTextNode.parentElement });
highlightNodes.push(highlightNode);

var prefixNode = ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset));
lastTextNode.parentElement.insertBefore(prefixNode, highlightNode);
changes.push({ node: prefixNode, type: "added", nextSibling: highlightNode, parent: lastTextNode.parentElement });
} else {
var firstTextNode = textNodeSnapshot.snapshotItem(startIndex);
var firstText = firstTextNode.textContent;
var anchorElement = firstTextNode.nextSibling;

firstTextNode.parentElement.insertBefore(highlightNode, anchorElement);
changes.push({ node: highlightNode, type: "added", nextSibling: anchorElement, parent: firstTextNode.parentElement });
highlightNodes.push(highlightNode);

firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset);
changes.push({ node: firstTextNode, type: "changed", oldText: firstText, newText: firstTextNode.textContent });

for (var j = startIndex + 1; j < endIndex; j++) {
var textNode = textNodeSnapshot.snapshotItem(j);
var text = textNode.textContent;
textNode.textContent = "";
changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent });
}
}
startIndex = endIndex;
nodeRanges[startIndex].offset = endOffset;
nodeRanges[startIndex].length = lastTextNode.textContent.length;

}
return highlightNodes;
}

WebInspector.applyDomChanges = function(domChanges)
{
for (var i = 0, size = domChanges.length; i < size; ++i) {
var entry = domChanges[i];
switch (entry.type) {
case "added":
entry.parent.insertBefore(entry.node, entry.nextSibling);
break;
case "changed":
entry.node.textContent = entry.newText;
break;
}
}
}

WebInspector.revertDomChanges = function(domChanges)
{
for (var i = domChanges.length - 1; i >= 0; --i) {
var entry = domChanges[i];
switch (entry.type) {
case "added":
if (entry.node.parentElement)
entry.node.parentElement.removeChild(entry.node);
break;
case "changed":
entry.node.textContent = entry.oldText;
break;
}
}
}

WebInspector._coalescingLevel = 0;

WebInspector.startBatchUpdate = function()
{
if (!WebInspector._coalescingLevel)
WebInspector._postUpdateHandlers = new Map();
WebInspector._coalescingLevel++;
}

WebInspector.endBatchUpdate = function()
{
if (--WebInspector._coalescingLevel)
return;

var handlers = WebInspector._postUpdateHandlers;
delete WebInspector._postUpdateHandlers;

var keys = handlers.keys();
for (var i = 0; i < keys.length; ++i) {
var object = keys[i];
var methods = handlers.get(object).keys();
for (var j = 0; j < methods.length; ++j)
methods[j].call(object);
}
}


WebInspector.invokeOnceAfterBatchUpdate = function(object, method)
{
if (!WebInspector._coalescingLevel) {
method.call(object);
return;
}

var methods = WebInspector._postUpdateHandlers.get(object);
if (!methods) {
methods = new Map();
WebInspector._postUpdateHandlers.put(object, methods);
}
methods.put(method);
}


WebInspector.CodeMirrorCSSLoadView = function()
{
WebInspector.View.call(this);
this.element.addStyleClass("hidden");
this.registerRequiredCSS("cm/codemirror.css");
this.registerRequiredCSS("cm/cmdevtools.css");
}

WebInspector.CodeMirrorCSSLoadView.prototype = {
__proto__: WebInspector.View.prototype
}

;(function() {

function windowLoaded()
{
window.addEventListener("focus", WebInspector._windowFocused, false);
window.addEventListener("blur", WebInspector._windowBlurred, false);
document.addEventListener("focus", WebInspector._focusChanged.bind(this), true);
window.removeEventListener("DOMContentLoaded", windowLoaded, false);
}

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

})();






WebInspector.HelpScreen = function(title)
{
WebInspector.View.call(this);
this.markAsRoot();
this.registerRequiredCSS("helpScreen.css");

this.element.className = "help-window-outer";
this.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
this.element.tabIndex = 0;
this.element.addEventListener("focus", this._onBlur.bind(this), false);

if (title) {
var mainWindow = this.element.createChild("div", "help-window-main");
var captionWindow = mainWindow.createChild("div", "help-window-caption");
captionWindow.appendChild(this._createCloseButton());
this.contentElement = mainWindow.createChild("div", "help-content");
captionWindow.createChild("h1", "help-window-title").textContent = title;
}
}


WebInspector.HelpScreen._visibleScreen = null;

WebInspector.HelpScreen.prototype = {
_createCloseButton: function()
{
var closeButton = document.createElement("div");
closeButton.className = "help-close-button close-button-gray";
closeButton.addEventListener("click", this.hide.bind(this), false);
return closeButton;
},

showModal: function()
{
var visibleHelpScreen = WebInspector.HelpScreen._visibleScreen;
if (visibleHelpScreen === this)
return;

if (visibleHelpScreen)
visibleHelpScreen.hide();
WebInspector.HelpScreen._visibleScreen = this;
this.show(document.body);
this.focus();
},

hide: function()
{
if (!this.isShowing())
return;

WebInspector.HelpScreen._visibleScreen = null;

WebInspector.restoreFocusFromElement(this.element);
this.detach();
},


isClosingKey: function(keyCode)
{
return [
WebInspector.KeyboardShortcut.Keys.Enter.code,
WebInspector.KeyboardShortcut.Keys.Esc.code,
WebInspector.KeyboardShortcut.Keys.Space.code,
].indexOf(keyCode) >= 0;
},

_onKeyDown: function(event)
{
if (this.isShowing() && this.isClosingKey(event.keyCode)) {
this.hide();
event.consume();
}
},

_onBlur: function(event)
{

if (this.isShowing() && !this.element.isSelfOrAncestor(event.target))
WebInspector.setCurrentFocusElement(this.element);
},

__proto__: WebInspector.View.prototype
}


WebInspector.HelpScreenUntilReload = function(title, message)
{
WebInspector.HelpScreen.call(this, title);
var p = this.contentElement.createChild("p");
p.addStyleClass("help-section");
p.textContent = message;
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this.hide, this);
}

WebInspector.HelpScreenUntilReload.prototype = {

willHide: function()
{
WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this.hide, this);
WebInspector.HelpScreen.prototype.willHide.call(this);
},

__proto__: WebInspector.HelpScreen.prototype
}






if (!window.InspectorFrontendHost) {


WebInspector.InspectorFrontendHostStub = function()
{
this._attachedWindowHeight = 0;
this.isStub = true;
this._fileBuffers = {};
WebInspector.documentCopyEventFired = this.documentCopy.bind(this);
}

WebInspector.InspectorFrontendHostStub.prototype = {
getSelectionBackgroundColor: function()
{
return "#6e86ff";
},

getSelectionForegroundColor: function()
{
return "#ffffff";
},

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;
},

requestSetDockSide: function(side)
{
InspectorFrontendAPI.setDockSide(side);
},

setAttachedWindowHeight: function(height)
{
},

moveWindowBy: function(x, y)
{
},

setInjectedScriptForOrigin: function(origin, script)
{
},

loaded: function()
{
},

localizedStringsURL: function()
{
return undefined;
},

inspectedURLChanged: function(url)
{
document.title = WebInspector.UIString(Preferences.applicationTitle, url);
},

documentCopy: function(event)
{
if (!this._textToCopy)
return;
event.clipboardData.setData("text", this._textToCopy);
event.preventDefault();
delete this._textToCopy;
},

copyText: function(text)
{
this._textToCopy = text;
if (!document.execCommand("copy")) {
var screen = new WebInspector.ClipboardAccessDeniedScreen();
screen.showModal();
}
},

openInNewTab: function(url)
{
window.open(url, "_blank");
},

canSave: function()
{
return true;
},

save: function(url, content, forceSaveAs)
{
if (this._fileBuffers[url])
throw new Error("Concurrent file modification denied.");

this._fileBuffers[url] = [content];
setTimeout(WebInspector.fileManager.savedURL.bind(WebInspector.fileManager, url), 0);
},

append: function(url, content)
{
var buffer = this._fileBuffers[url];
if (!buffer)
throw new Error("File is not open for write yet.");

buffer.push(content);
setTimeout(WebInspector.fileManager.appendedToURL.bind(WebInspector.fileManager, url), 0);
},

close: function(url)
{
var content = this._fileBuffers[url];
delete this._fileBuffers[url];

if (!content)
return;

var lastSlashIndex = url.lastIndexOf("/");
var fileNameSuffix = (lastSlashIndex === -1) ? url : url.substring(lastSlashIndex + 1);

var blob = new Blob(content, { type: "application/octet-stream" });
var objectUrl = window.URL.createObjectURL(blob);
window.location = objectUrl + "#" + fileNameSuffix;

function cleanup()
{
window.URL.revokeObjectURL(objectUrl);
}
setTimeout(cleanup, 0);
},

sendMessageToBackend: function(message)
{
},

recordActionTaken: function(actionCode)
{
},

recordPanelShown: function(panelCode)
{
},

recordSettingChanged: function(settingCode)
{
},

loadResourceSynchronously: function(url)
{
return loadXHR(url);
},

supportsFileSystems: function()
{
return false;
},

requestFileSystems: function()
{
},

addFileSystem: function()
{
},

removeFileSystem: function(fileSystemPath)
{
},

isolatedFileSystem: function(fileSystemId, registeredName)
{
return null;
},

setZoomFactor: function(zoom)
{
},

isUnderTest: function()
{
return false;
}
}

InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub();


WebInspector.ClipboardAccessDeniedScreen = function()
{
WebInspector.HelpScreen.call(this, WebInspector.UIString("Clipboard access is denied"));
var platformMessage = WebInspector.UIString("You need to install a Chrome extension that grants clipboard access to Developer Tools.");
if (platformMessage) {
var p = this.contentElement.createChild("p");
p.addStyleClass("help-section");
p.textContent = platformMessage;
}
}

WebInspector.ClipboardAccessDeniedScreen.prototype = {
__proto__: WebInspector.HelpScreen.prototype
}

}


WebInspector.RemoteDebuggingTerminatedScreen = function(reason)
{
WebInspector.HelpScreen.call(this, WebInspector.UIString("Detached from the target"));
var p = this.contentElement.createChild("p");
p.addStyleClass("help-section");
p.createChild("span").textContent = "Remote debugging has been terminated with reason: ";
p.createChild("span", "error-message").textContent = reason;
p.createChild("br");
p.createChild("span").textContent = "Please re-attach to the new target.";
}

WebInspector.RemoteDebuggingTerminatedScreen.prototype = {
__proto__: WebInspector.HelpScreen.prototype
}






WebInspector.FileManager = function()
{
}

WebInspector.FileManager.EventTypes = {
SavedURL: "SavedURL",
AppendedToURL: "AppendedToURL"
}

WebInspector.FileManager.prototype = {

canSave: function()
{
return true;
},


save: function(url, content, forceSaveAs)
{

var savedURLs = WebInspector.settings.savedURLs.get();
delete savedURLs[url];
WebInspector.settings.savedURLs.set(savedURLs);
InspectorFrontendHost.save(url, content, forceSaveAs);
},


savedURL: function(url)
{
var savedURLs = WebInspector.settings.savedURLs.get();
savedURLs[url] = true;
WebInspector.settings.savedURLs.set(savedURLs);
this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.SavedURL, url);
},


isURLSaved: function(url)
{
var savedURLs = WebInspector.settings.savedURLs.get();
return savedURLs[url];
},


append: function(url, content)
{
InspectorFrontendHost.append(url, content);
},


close: function(url)
{
InspectorFrontendHost.close(url);
},


appendedToURL: function(url)
{
this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.AppendedToURL, url);
},

__proto__: WebInspector.Object.prototype
}

WebInspector.fileManager = new WebInspector.FileManager();






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.consume();
return true;
}

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






WebInspector.ContextMenuItem = function(topLevelMenu, type, label, disabled, checked)
{
this._type = type;
this._label = label;
this._disabled = disabled;
this._checked = checked;
this._contextMenu = topLevelMenu;
if (type === "item" || type === "checkbox")
this._id = topLevelMenu.nextId();
}

WebInspector.ContextMenuItem.prototype = {
id: function()
{
return this._id;
},

type: function()
{
return this._type;
},


isEnabled: function()
{
return !this._disabled;
},


setEnabled: function(enabled)
{
this._disabled = !enabled;
},

_buildDescriptor: function()
{
switch (this._type) {
case "item":
return { type: "item", id: this._id, label: this._label, enabled: !this._disabled };
case "separator":
return { type: "separator" };
case "checkbox":
return { type: "checkbox", id: this._id, label: this._label, checked: !!this._checked, enabled: !this._disabled };
}
}
}


WebInspector.ContextSubMenuItem = function(topLevelMenu, label, disabled)
{
WebInspector.ContextMenuItem.call(this, topLevelMenu, "subMenu", label, disabled);

this._items = [];
}

WebInspector.ContextSubMenuItem.prototype = {

appendItem: function(label, handler, disabled)
{
var item = new WebInspector.ContextMenuItem(this._contextMenu, "item", label, disabled);
this._pushItem(item);
this._contextMenu._setHandler(item.id(), handler);
return item;
},


appendSubMenuItem: function(label, disabled)
{
var item = new WebInspector.ContextSubMenuItem(this._contextMenu, label, disabled);
this._pushItem(item);
return item;
},


appendCheckboxItem: function(label, handler, checked, disabled)
{
var item = new WebInspector.ContextMenuItem(this._contextMenu, "checkbox", label, disabled, checked);
this._pushItem(item);
this._contextMenu._setHandler(item.id(), handler);
return item;
},

appendSeparator: function()
{
if (this._items.length)
this._pendingSeparator = true;
},


_pushItem: function(item)
{
if (this._pendingSeparator) {
this._items.push(new WebInspector.ContextMenuItem(this._contextMenu, "separator"));
delete this._pendingSeparator;
}
this._items.push(item);
},


isEmpty: function()
{
return !this._items.length;
},

_buildDescriptor: function()
{
var result = { type: "subMenu", label: this._label, enabled: !this._disabled, subItems: [] };
for (var i = 0; i < this._items.length; ++i)
result.subItems.push(this._items[i]._buildDescriptor());
return result;
},

__proto__: WebInspector.ContextMenuItem.prototype
}


WebInspector.ContextMenu = function(event) {
WebInspector.ContextSubMenuItem.call(this, this, "");
this._event = event;
this._handlers = {};
this._id = 0;
}

WebInspector.ContextMenu.prototype = {
nextId: function()
{
return this._id++;
},

show: function()
{
var menuObject = this._buildDescriptor();

if (menuObject.length) {
WebInspector._contextMenu = this;
InspectorFrontendHost.showContextMenu(this._event, menuObject);
this._event.consume();
}
},

showSoftMenu: function()
{
var menuObject = this._buildDescriptor();

if (menuObject.length) {
WebInspector._contextMenu = this;
var softMenu = new WebInspector.SoftContextMenu(menuObject);
softMenu.show(this._event, true);
}
this._event.consume();
},

_setHandler: function(id, handler)
{
if (handler)
this._handlers[id] = handler;
},

_buildDescriptor: function()
{
var result = [];
for (var i = 0; i < this._items.length; ++i)
result.push(this._items[i]._buildDescriptor());
return result;
},

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


appendApplicableItems: function(target)
{
for (var i = 0; i < WebInspector.ContextMenu._providers.length; ++i) {
var provider = WebInspector.ContextMenu._providers[i];
this.appendSeparator();
provider.appendApplicableItems(this._event, this, target);
this.appendSeparator();
}
},

__proto__: WebInspector.ContextSubMenuItem.prototype
}


WebInspector.ContextMenu.Provider = function() { 
}

WebInspector.ContextMenu.Provider.prototype = {

appendApplicableItems: function(event, contextMenu, target) { }
}


WebInspector.ContextMenu.registerProvider = function(provider)
{
WebInspector.ContextMenu._providers.push(provider);
}

WebInspector.ContextMenu._providers = [];

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

WebInspector.contextMenuCleared = function()
{


}






WebInspector.SoftContextMenu = function(items, parentMenu)
{
this._items = items;
this._parentMenu = parentMenu;
}

WebInspector.SoftContextMenu.prototype = {

show: function(event, alignToCurrentTarget)
{
this._x = event.x;
this._y = event.y;
this._time = new Date().getTime();


var absoluteX = event.pageX;
var absoluteY = event.pageY;
var targetElement = event.target;
while (targetElement && window !== targetElement.ownerDocument.defaultView) {
var frameElement = targetElement.ownerDocument.defaultView.frameElement;
absoluteY += frameElement.totalOffsetTop();
absoluteX += frameElement.totalOffsetLeft();
targetElement = frameElement;
}


var targetRect;
this._contextMenuElement = document.createElement("div");
this._contextMenuElement.className = "soft-context-menu";
this._contextMenuElement.tabIndex = 0;
if (alignToCurrentTarget) {
targetRect = event.currentTarget.getBoundingClientRect();

absoluteX = targetRect.left;
absoluteY = targetRect.bottom;
}
this._contextMenuElement.style.top = absoluteY + "px";
this._contextMenuElement.style.left = absoluteX + "px";

this._contextMenuElement.addEventListener("mouseup", consumeEvent, false);
this._contextMenuElement.addEventListener("keydown", this._menuKeyDown.bind(this), false);

for (var i = 0; i < this._items.length; ++i)
this._contextMenuElement.appendChild(this._createMenuItem(this._items[i]));


if (!this._parentMenu) {
this._glassPaneElement = document.createElement("div");
this._glassPaneElement.className = "soft-context-menu-glass-pane";
this._glassPaneElement.tabIndex = 0;
this._glassPaneElement.addEventListener("mouseup", this._glassPaneMouseUp.bind(this), false);
this._glassPaneElement.appendChild(this._contextMenuElement);
document.body.appendChild(this._glassPaneElement);
this._focus();
} else
this._parentMenu._parentGlassPaneElement().appendChild(this._contextMenuElement);


if (document.body.offsetWidth <  this._contextMenuElement.offsetLeft + this._contextMenuElement.offsetWidth) {
if (alignToCurrentTarget)
this._contextMenuElement.style.left = Math.max(0, targetRect.right - this._contextMenuElement.offsetWidth) + "px";
else
this._contextMenuElement.style.left = (absoluteX - this._contextMenuElement.offsetWidth) + "px";
}
if (document.body.offsetHeight < this._contextMenuElement.offsetTop + this._contextMenuElement.offsetHeight) {
if (alignToCurrentTarget)
this._contextMenuElement.style.top = Math.max(0, targetRect.top - this._contextMenuElement.offsetHeight) + "px";
else
this._contextMenuElement.style.top = (document.body.offsetHeight - this._contextMenuElement.offsetHeight) + "px";
}

event.consume(true);
},

_parentGlassPaneElement: function()
{
if (this._glassPaneElement)
return this._glassPaneElement;
if (this._parentMenu)
return this._parentMenu._parentGlassPaneElement();
return null;
},

_createMenuItem: function(item)
{
if (item.type === "separator")
return this._createSeparator();

if (item.type === "subMenu")
return this._createSubMenu(item);

var menuItemElement = document.createElement("div");
menuItemElement.className = "soft-context-menu-item";

var checkMarkElement = document.createElement("span");
checkMarkElement.textContent = "\u2713 "; 
checkMarkElement.className = "soft-context-menu-item-checkmark";
if (!item.checked)
checkMarkElement.style.opacity = "0";

menuItemElement.appendChild(checkMarkElement);
menuItemElement.appendChild(document.createTextNode(item.label));

menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);


menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false);

menuItemElement._actionId = item.id;
return menuItemElement;
},

_createSubMenu: function(item)
{
var menuItemElement = document.createElement("div");
menuItemElement.className = "soft-context-menu-item";
menuItemElement._subItems = item.subItems;


var checkMarkElement = document.createElement("span");
checkMarkElement.textContent = "\u2713 "; 
checkMarkElement.className = "soft-context-menu-item-checkmark";
checkMarkElement.style.opacity = "0";
menuItemElement.appendChild(checkMarkElement);

var subMenuArrowElement = document.createElement("span");
subMenuArrowElement.textContent = "\u25B6"; 
subMenuArrowElement.className = "soft-context-menu-item-submenu-arrow";

menuItemElement.appendChild(document.createTextNode(item.label));
menuItemElement.appendChild(subMenuArrowElement);

menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);


menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false);

return menuItemElement;
},

_createSeparator: function()
{
var separatorElement = document.createElement("div");
separatorElement.className = "soft-context-menu-separator";
separatorElement._isSeparator = true;
separatorElement.addEventListener("mouseover", this._hideSubMenu.bind(this), false);
separatorElement.createChild("div", "separator-line");
return separatorElement;
},

_menuItemMouseDown: function(event)
{

event.consume(true);
},

_menuItemMouseUp: function(event)
{
this._triggerAction(event.target, event);
event.consume();
},

_focus: function()
{
this._contextMenuElement.focus();
},

_triggerAction: function(menuItemElement, event)
{
if (!menuItemElement._subItems) {
this._discardMenu(true, event);
if (typeof menuItemElement._actionId !== "undefined") {
WebInspector.contextMenuItemSelected(menuItemElement._actionId);
delete menuItemElement._actionId;
}
return;
}

this._showSubMenu(menuItemElement, event);
event.consume();
},

_showSubMenu: function(menuItemElement, event)
{
if (menuItemElement._subMenuTimer) {
clearTimeout(menuItemElement._subMenuTimer);
delete menuItemElement._subMenuTimer;
}
if (this._subMenu)
return;

this._subMenu = new WebInspector.SoftContextMenu(menuItemElement._subItems, this);
this._subMenu.show(this._buildMouseEventForSubMenu(menuItemElement));
},

_buildMouseEventForSubMenu: function(subMenuItemElement)
{
var subMenuOffset = { x: subMenuItemElement.offsetWidth - 3, y: subMenuItemElement.offsetTop - 1 };
var targetX = this._x + subMenuOffset.x;
var targetY = this._y + subMenuOffset.y;
var targetPageX = parseInt(this._contextMenuElement.style.left, 10) + subMenuOffset.x;
var targetPageY = parseInt(this._contextMenuElement.style.top, 10) + subMenuOffset.y;
return { x: targetX, y: targetY, pageX: targetPageX, pageY: targetPageY, consume: function() {} };
},

_hideSubMenu: function()
{
if (!this._subMenu)
return;
this._subMenu._discardSubMenus();
this._focus();
},

_menuItemMouseOver: function(event)
{
this._highlightMenuItem(event.target);
},

_menuItemMouseOut: function(event)
{
if (!this._subMenu || !event.relatedTarget) {
this._highlightMenuItem(null);
return;
}

var relatedTarget = event.relatedTarget;
if (this._contextMenuElement.isSelfOrAncestor(relatedTarget) || relatedTarget.hasStyleClass("soft-context-menu-glass-pane"))
this._highlightMenuItem(null);
},

_highlightMenuItem: function(menuItemElement)
{
if (this._highlightedMenuItemElement ===  menuItemElement)
return;

this._hideSubMenu();
if (this._highlightedMenuItemElement) {
this._highlightedMenuItemElement.removeStyleClass("soft-context-menu-item-mouse-over");
if (this._highlightedMenuItemElement._subItems && this._highlightedMenuItemElement._subMenuTimer) {
clearTimeout(this._highlightedMenuItemElement._subMenuTimer);
delete this._highlightedMenuItemElement._subMenuTimer;
}
}
this._highlightedMenuItemElement = menuItemElement;
if (this._highlightedMenuItemElement) {
this._highlightedMenuItemElement.addStyleClass("soft-context-menu-item-mouse-over");
this._contextMenuElement.focus();
if (this._highlightedMenuItemElement._subItems && !this._highlightedMenuItemElement._subMenuTimer)
this._highlightedMenuItemElement._subMenuTimer = setTimeout(this._showSubMenu.bind(this, this._highlightedMenuItemElement, this._buildMouseEventForSubMenu(this._highlightedMenuItemElement)), 150);
}
},

_highlightPrevious: function()
{
var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling : this._contextMenuElement.lastChild;
while (menuItemElement && menuItemElement._isSeparator)
menuItemElement = menuItemElement.previousSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement);
},

_highlightNext: function()
{
var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling : this._contextMenuElement.firstChild;
while (menuItemElement && menuItemElement._isSeparator)
menuItemElement = menuItemElement.nextSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement);
},

_menuKeyDown: function(event)
{
switch (event.keyIdentifier) {
case "Up":
this._highlightPrevious(); break;
case "Down":
this._highlightNext(); break;
case "Left":
if (this._parentMenu) {
this._highlightMenuItem(null);
this._parentMenu._focus();
}
break;
case "Right":
if (!this._highlightedMenuItemElement)
break;
if (this._highlightedMenuItemElement._subItems) {
this._showSubMenu(this._highlightedMenuItemElement, this._buildMouseEventForSubMenu(this._highlightedMenuItemElement));
this._subMenu._focus();
this._subMenu._highlightNext();
}
break;
case "U+001B": 
this._discardMenu(true, event); break;
case "Enter":
if (!isEnterKey(event))
break;

case "U+0020": 
if (this._highlightedMenuItemElement)
this._triggerAction(this._highlightedMenuItemElement, event);
break;
}
event.consume(true);
},

_glassPaneMouseUp: function(event)
{

if (event.x === this._x && event.y === this._y && new Date().getTime() - this._time < 300)
return;
this._discardMenu(true, event);
event.consume();
},


_discardMenu: function(closeParentMenus, event)
{
if (this._subMenu && !closeParentMenus)
return;
if (this._glassPaneElement) {
var glassPane = this._glassPaneElement;
delete this._glassPaneElement;

document.body.removeChild(glassPane);
if (this._parentMenu) {
delete this._parentMenu._subMenu;
if (closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus, event);
}

if (event)
event.consume(true);
} else if (this._parentMenu && this._contextMenuElement.parentElement) {
this._discardSubMenus();
if (closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus, event);

if (event)
event.consume(true);
}
},

_discardSubMenus: function()
{
if (this._subMenu)
this._subMenu._discardSubMenus();
if (this._contextMenuElement.parentElement)
this._contextMenuElement.parentElement.removeChild(this._contextMenuElement);
if (this._parentMenu)
delete this._parentMenu._subMenu;
}
}

if (!InspectorFrontendHost.showContextMenu) {

InspectorFrontendHost.showContextMenu = function(event, items)
{
new WebInspector.SoftContextMenu(items).show(event);
}

}






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.Key;


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: "<Left>" },           
Up: { code: 38, name: "<Up>" },             
Right: { code: 39, name: "<Right>" },          
Down: { code: 40, name: "<Down>" },           
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: "\'" },
H: { code: 72, name: "H" }
};


WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers)
{
if (typeof keyCode === "string")
keyCode = keyCode.charCodeAt(0) - 32;
modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None;
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.eventHasCtrlOrMeta = function(event)
{
return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
}


WebInspector.KeyboardShortcut.hasNoModifiers = function(event)
{
return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey;
}


WebInspector.KeyboardShortcut.Descriptor;


WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers)
{
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.KeyboardShortcut.SelectAll = WebInspector.KeyboardShortcut.makeKey("a", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);






WebInspector.SuggestBoxDelegate = function()
{
}

WebInspector.SuggestBoxDelegate.prototype = {

applySuggestion: function(suggestion, isIntermediateSuggestion) { },


acceptSuggestion: function() { },
}


WebInspector.SuggestBox = function(suggestBoxDelegate, anchorElement, className)
{
this._suggestBoxDelegate = suggestBoxDelegate;
this._anchorElement = anchorElement;
this._length = 0;
this._selectedIndex = -1;
this._selectedElement = null;
this._boundOnScroll = this._onScrollOrResize.bind(this, true);
this._boundOnResize = this._onScrollOrResize.bind(this, false);
window.addEventListener("scroll", this._boundOnScroll, true);
window.addEventListener("resize", this._boundOnResize, true);

this._bodyElement = anchorElement.ownerDocument.body;
this._element = anchorElement.ownerDocument.createElement("div");
this._element.className = "suggest-box " + (className || "");
this._element.addEventListener("mousedown", this._onBoxMouseDown.bind(this), true);
this.containerElement = this._element.createChild("div", "container");
this.contentElement = this.containerElement.createChild("div", "content");
}

WebInspector.SuggestBox.prototype = {

visible: function()
{
return !!this._element.parentElement;
},


_onScrollOrResize: function(isScroll, event)
{
if (isScroll && this._element.isAncestor(event.target) || !this.visible())
return;
this._updateBoxPosition(this._anchorBox);
},


_updateBoxPosition: function(anchorBox)
{
this._anchorBox = anchorBox;


this.contentElement.style.display = "inline-block";
document.body.appendChild(this.contentElement);
this.contentElement.positionAt(0, 0);
var contentWidth = this.contentElement.offsetWidth;
var contentHeight = this.contentElement.offsetHeight;
this.contentElement.style.display = "block";
this.containerElement.appendChild(this.contentElement);

const spacer = 6;
const suggestBoxPaddingX = 21;
const suggestBoxPaddingY = 2;

var maxWidth = document.body.offsetWidth - anchorBox.x - spacer;
var width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
var paddedWidth = contentWidth + suggestBoxPaddingX;
var boxX = anchorBox.x;
if (width < paddedWidth) {

maxWidth = document.body.offsetWidth - spacer;
width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
boxX = document.body.offsetWidth - width;
}

var boxY;
var aboveHeight = anchorBox.y;
var underHeight = document.body.offsetHeight - anchorBox.y - anchorBox.height;
var maxHeight = Math.max(underHeight, aboveHeight) - spacer;
var height = Math.min(contentHeight, maxHeight - suggestBoxPaddingY) + suggestBoxPaddingY;
if (underHeight >= aboveHeight) {

boxY = anchorBox.y + anchorBox.height;
this._element.removeStyleClass("above-anchor");
this._element.addStyleClass("under-anchor");
} else {

boxY = anchorBox.y - height;
this._element.removeStyleClass("under-anchor");
this._element.addStyleClass("above-anchor");
}

this._element.positionAt(boxX, boxY);
this._element.style.width = width + "px";
this._element.style.height = height + "px";
},


_onBoxMouseDown: function(event)
{
event.preventDefault();
},

hide: function()
{
if (!this.visible())
return;

this._element.parentElement.removeChild(this._element);
delete this._selectedElement;
},

removeFromElement: function()
{
window.removeEventListener("scroll", this._boundOnScroll, true);
window.removeEventListener("resize", this._boundOnResize, true);
this.hide();
},


_applySuggestion: function(text, isIntermediateSuggestion)
{
if (!this.visible() || !(text || this._selectedElement))
return false;

var suggestion = text || this._selectedElement.textContent;
if (!suggestion)
return false;

this._suggestBoxDelegate.applySuggestion(suggestion, isIntermediateSuggestion);
return true;
},


acceptSuggestion: function(text)
{
var result = this._applySuggestion(text, false);
this.hide();
if (!result)
return false;

this._suggestBoxDelegate.acceptSuggestion();

return true;
},


_selectClosest: function(shift, isCircular)
{
if (!this._length)
return false;

var index = this._selectedIndex + shift;

if (isCircular)
index = (this._length + index) % this._length;
else
index = Number.constrain(index, 0, this._length - 1);

this._selectItem(index);
this._applySuggestion(undefined, true);
return true;
},


_onItemMouseDown: function(text, event)
{
this.acceptSuggestion(text);
event.consume(true);
},


_createItemElement: function(prefix, text)
{
var element = document.createElement("div");
element.className = "suggest-box-content-item source-code";
element.tabIndex = -1;
if (prefix && prefix.length && !text.indexOf(prefix)) {
var prefixElement = element.createChild("span", "prefix");
prefixElement.textContent = prefix;
var suffixElement = element.createChild("span", "suffix");
suffixElement.textContent = text.substring(prefix.length);
} else {
var suffixElement = element.createChild("span", "suffix");
suffixElement.textContent = text;
}
element.addEventListener("mousedown", this._onItemMouseDown.bind(this, text), false);
return element;
},


_updateItems: function(items, selectedIndex, userEnteredText)
{
this._length = items.length;
this.contentElement.removeChildren();

for (var i = 0; i < items.length; ++i) {
var item = items[i];
var currentItemElement = this._createItemElement(userEnteredText, item);
this.contentElement.appendChild(currentItemElement);
}

this._selectedElement = null;
if (typeof selectedIndex === "number")
this._selectItem(selectedIndex);
},


_selectItem: function(index)
{
if (this._selectedElement)
this._selectedElement.classList.remove("selected");

this._selectedIndex = index;
this._selectedElement = this.contentElement.children[index];
this._selectedElement.classList.add("selected");

this._selectedElement.scrollIntoViewIfNeeded(false);
},


_canShowBox: function(completions, canShowForSingleItem, userEnteredText)
{
if (!completions || !completions.length)
return false;

if (completions.length > 1)
return true;


return canShowForSingleItem && completions[0] !== userEnteredText;
},

_rememberRowCountPerViewport: function()
{
if (!this.contentElement.firstChild)
return;

this._rowCountPerViewport = Math.floor(this.containerElement.offsetHeight / this.contentElement.firstChild.offsetHeight);
},


updateSuggestions: function(anchorBox, completions, selectedIndex, canShowForSingleItem, userEnteredText)
{
if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) {
this._updateItems(completions, selectedIndex, userEnteredText);
this._updateBoxPosition(anchorBox);
if (!this.visible())
this._bodyElement.appendChild(this._element);
this._rememberRowCountPerViewport();
} else
this.hide();
},


upKeyPressed: function()
{
return this._selectClosest(-1, true);
},


downKeyPressed: function()
{
return this._selectClosest(1, true);
},


pageUpKeyPressed: function()
{
return this._selectClosest(-this._rowCountPerViewport, false);
},


pageDownKeyPressed: function()
{
return this._selectClosest(this._rowCountPerViewport, false);
},


enterKeyPressed: function()
{
var hasSelectedItem = !!this._selectedElement;
this.acceptSuggestion();



return hasSelectedItem;
},


tabKeyPressed: function()
{
return this.enterKeyPressed();
}
}






WebInspector.TextPrompt = function(completions, stopCharacters)
{

this._proxyElement;
this._proxyElementDisplay = "inline-block";
this._loadCompletions = completions;
this._completionStopCharacters = stopCharacters || " =:[({;,!+-*/&|^<>.";
this._suggestForceable = true;
}

WebInspector.TextPrompt.Events = {
ItemApplied: "text-prompt-item-applied",
ItemAccepted: "text-prompt-item-accepted"
};

WebInspector.TextPrompt.prototype = {
get proxyElement()
{
return this._proxyElement;
},

setSuggestForceable: function(x)
{
this._suggestForceable = x;
},

setSuggestBoxEnabled: function(className)
{
this._suggestBoxClassName = className;
},

renderAsBlock: function()
{
this._proxyElementDisplay = "block";
},


attach: function(element)
{
return this._attachInternal(element);
},


attachAndStartEditing: function(element, blurListener)
{
this._attachInternal(element);
this._startEditing(blurListener);
return this.proxyElement;
},

_attachInternal: function(element)
{
if (this.proxyElement)
throw "Cannot attach an attached TextPrompt";
this._element = element;

this._boundOnKeyDown = this.onKeyDown.bind(this);
this._boundOnMouseWheel = this.onMouseWheel.bind(this);
this._boundSelectStart = this._selectStart.bind(this);
this._proxyElement = element.ownerDocument.createElement("span");
this._proxyElement.style.display = this._proxyElementDisplay;
element.parentElement.insertBefore(this.proxyElement, element);
this.proxyElement.appendChild(element);
this._element.addStyleClass("text-prompt");
this._element.addEventListener("keydown", this._boundOnKeyDown, false);
this._element.addEventListener("mousewheel", this._boundOnMouseWheel, false);
this._element.addEventListener("selectstart", this._boundSelectStart, false);

if (typeof this._suggestBoxClassName === "string")
this._suggestBox = new WebInspector.SuggestBox(this, this._element, this._suggestBoxClassName);

return this.proxyElement;
},

detach: function()
{
this._removeFromElement();
this.proxyElement.parentElement.insertBefore(this._element, this.proxyElement);
this.proxyElement.parentElement.removeChild(this.proxyElement);
this._element.removeStyleClass("text-prompt");
this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
this._element.removeEventListener("mousewheel", this._boundOnMouseWheel, false);
this._element.removeEventListener("selectstart", this._boundSelectStart, false);
delete this._proxyElement;
WebInspector.restoreFocusFromElement(this._element);
},

get text()
{
return this._element.textContent;
},

set text(x)
{
this._removeSuggestionAids();
if (!x) {

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

this.moveCaretToEndOfPrompt();
this._element.scrollIntoView();
},

_removeFromElement: function()
{
this.clearAutoComplete(true);
this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
this._element.removeEventListener("selectstart", this._boundSelectStart, false);
if (this._isEditing)
this._stopEditing();
if (this._suggestBox)
this._suggestBox.removeFromElement();
},

_startEditing: function(blurListener)
{
this._isEditing = true;
this._element.addStyleClass("editing");
if (blurListener) {
this._blurListener = blurListener;
this._element.addEventListener("blur", this._blurListener, false);
}
this._oldTabIndex = this._element.tabIndex;
if (this._element.tabIndex < 0)
this._element.tabIndex = 0;
WebInspector.setCurrentFocusElement(this._element);
},

_stopEditing: function()
{
this._element.tabIndex = this._oldTabIndex;
if (this._blurListener)
this._element.removeEventListener("blur", this._blurListener, false);
this._element.removeStyleClass("editing");
delete this._isEditing;
},

_removeSuggestionAids: function()
{
this.clearAutoComplete();
this.hideSuggestBox();
},

_selectStart: function(event)
{
if (this._selectionTimeout)
clearTimeout(this._selectionTimeout);

this._removeSuggestionAids();

function moveBackIfOutside()
{
delete this._selectionTimeout;
if (!this.isCaretInsidePrompt() && window.getSelection().isCollapsed) {
this.moveCaretToEndOfPrompt();
this.autoCompleteSoon();
}
}

this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
},


defaultKeyHandler: function(event, force)
{
this.clearAutoComplete();
this.autoCompleteSoon(force);
return false;
},

onMouseWheel: function(event)
{

},

onKeyDown: function(event)
{
var handled = false;
var invokeDefault = true;

switch (event.keyIdentifier) {
case "Up":
handled = this.upKeyPressed(event);
break;
case "Down":
handled = this.downKeyPressed(event);
break;
case "PageUp":
handled = this.pageUpKeyPressed(event);
break;
case "PageDown":
handled = this.pageDownKeyPressed(event);
break;
case "U+0009": 
handled = this.tabKeyPressed(event);
break;
case "Enter":
handled = this.enterKeyPressed(event);
break;
case "Left":
case "Home":
this._removeSuggestionAids();
invokeDefault = false;
break;
case "Right":
case "End":
if (this.isCaretAtEndOfPrompt())
handled = this.acceptAutoComplete();
else
this._removeSuggestionAids();
invokeDefault = false;
break;
case "U+001B": 
if (this.isSuggestBoxVisible()) {
this._suggestBox.hide();
handled = true;
}
break;
case "U+0020": 
if (this._suggestForceable && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
this.defaultKeyHandler(event, true);
handled = true;
}
break;
case "Alt":
case "Meta":
case "Shift":
case "Control":
invokeDefault = false;
break;
}

if (!handled && invokeDefault)
handled = this.defaultKeyHandler(event);

if (handled)
event.consume(true);

return handled;
},

acceptAutoComplete: function()
{
var result = false;
if (this.isSuggestBoxVisible())
result = this._suggestBox.acceptSuggestion();
if (!result)
result = this.acceptSuggestion();

return result;
},


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

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.normalize();

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(force)
{
var immediately = this.isSuggestBoxVisible() || force;
if (!this._completeTimeout)
this._completeTimeout = setTimeout(this.complete.bind(this, true, force), immediately ? 0 : 250);
},


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

var selectionRange = selection.getRangeAt(0);
var isEmptyInput = selectionRange.commonAncestorContainer === this._element; 

var shouldExit;


if (auto && isEmptyInput && !force)
shouldExit = true;
else if (!auto && !isEmptyInput && !selectionRange.commonAncestorContainer.isDescendant(this._element))
shouldExit = true;
else if (auto && !force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible())
shouldExit = true;
else if (!selection.isCollapsed)
shouldExit = true;
else if (!force) {

var wordSuffixRange = selectionRange.startContainer.rangeOfWord(selectionRange.endOffset, this._completionStopCharacters, this._element, "forward");
if (wordSuffixRange.toString().length)
shouldExit = true;
}
if (shouldExit) {
this.hideSuggestBox();
return;
}

var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this._completionStopCharacters, this._element, "backward");
this._waitingForCompletions = true;
this._loadCompletions(this.proxyElement, wordPrefixRange, force, this._completionsReady.bind(this, selection, auto, wordPrefixRange, !!reverse));
},

_boxForAnchorAtStart: function(selection, textRange)
{
var rangeCopy = selection.getRangeAt(0).cloneRange();
var anchorElement = document.createElement("span");
anchorElement.textContent = "\u200B";
textRange.insertNode(anchorElement);
var box = anchorElement.boxInWindow(window);
anchorElement.parentElement.removeChild(anchorElement);
selection.removeAllRanges();
selection.addRange(rangeCopy);
return box;
},


_buildCommonPrefix: function(completions, wordPrefixLength)
{
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;
}
}
}
return commonPrefix;
},


_completionsReady: function(selection, auto, originalWordPrefixRange, reverse, completions, selectedIndex)
{
if (!this._waitingForCompletions || !completions.length) {
this.hideSuggestBox();
return;
}
delete this._waitingForCompletions;

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;

selectedIndex = selectedIndex || 0;

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

if (this._suggestBox)
this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection, fullWordRange), completions, selectedIndex, !this.isCaretAtEndOfPrompt(), this._userEnteredText);

var wordPrefixLength = originalWordPrefixRange.toString().length;

if (auto) {
var completionText = completions[selectedIndex];
var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);

this._commonPrefix = commonPrefix;
} else {
if (completions.length === 1) {
var completionText = completions[selectedIndex];
wordPrefixLength = completionText.length;
} else {
var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);
wordPrefixLength = commonPrefix.length;

if (selection.isCollapsed)
var completionText = completions[selectedIndex];
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[selectedIndex];
else if (nextIndex < 0)
var completionText = completions[completions.length - 1];
else
var completionText = completions[nextIndex];
}
}
}

if (auto) {
if (this.isCaretAtEndOfPrompt()) {
this._userEnteredRange.deleteContents();
this._element.normalize();
var finalSelectionRange = document.createRange();
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);
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
}
} else
this._applySuggestion(completionText, completions.length > 1, originalWordPrefixRange);
},

_completeCommonPrefix: function()
{
if (!this.autoCompleteElement || !this._commonPrefix || !this._userEnteredText || !this._commonPrefix.startsWith(this._userEnteredText))
return;

if (!this.isSuggestBoxVisible()) {
this.acceptAutoComplete();
return;
}

this.autoCompleteElement.textContent = this._commonPrefix.substring(this._userEnteredText.length);
this.acceptSuggestion(true)
},


applySuggestion: function(completionText, isIntermediateSuggestion)
{
this._applySuggestion(completionText, isIntermediateSuggestion);
},


_applySuggestion: function(completionText, isIntermediateSuggestion, originalPrefixRange)
{
var wordPrefixLength;
if (originalPrefixRange)
wordPrefixLength = originalPrefixRange.toString().length;
else
wordPrefixLength = this._userEnteredText ? this._userEnteredText.length : 0;

this._userEnteredRange.deleteContents();
this._element.normalize();
var finalSelectionRange = document.createRange();
var completionTextNode = document.createTextNode(completionText);
this._userEnteredRange.insertNode(completionTextNode);
if (this.autoCompleteElement && this.autoCompleteElement.parentNode) {
this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
delete this.autoCompleteElement;
}

if (isIntermediateSuggestion)
finalSelectionRange.setStart(completionTextNode, wordPrefixLength);
else
finalSelectionRange.setStart(completionTextNode, completionText.length);

finalSelectionRange.setEnd(completionTextNode, completionText.length);

var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
if (isIntermediateSuggestion)
this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied, { itemText: completionText });
},


acceptSuggestion: function(prefixAccepted)
{
if (this._isAcceptingSuggestion)
return false;

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);

if (!prefixAccepted) {
this.hideSuggestBox();
this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepted);
} else
this.autoCompleteSoon(true);

return true;
},

hideSuggestBox: function()
{
if (this.isSuggestBoxVisible())
this._suggestBox.hide();
},

isSuggestBoxVisible: function()
{
return this._suggestBox && this._suggestBox.visible();
},

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.isSelfOrDescendant(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 && (!this.autoCompleteElement || !this.autoCompleteElement.isAncestor(node)))
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)
{
this._completeCommonPrefix();


return true;
},

enterKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.enterKeyPressed();

return false;
},

upKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.upKeyPressed();

return false;
},

downKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.downKeyPressed();

return false;
},

pageUpKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.pageUpKeyPressed();

return false;
},

pageDownKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.pageDownKeyPressed();

return false;
},

__proto__: WebInspector.Object.prototype
}



WebInspector.TextPromptWithHistory = function(completions, stopCharacters)
{
WebInspector.TextPrompt.call(this, completions, stopCharacters);


this._data = [];


this._historyOffset = 1;


this._coalesceHistoryDupes = true;
}

WebInspector.TextPromptWithHistory.prototype = {
get historyData()
{

return this._data;
},

setCoalesceHistoryDupes: function(x)
{
this._coalesceHistoryDupes = x;
},


setHistoryData: function(data)
{
this._data = [].concat(data);
this._historyOffset = 1;
},


pushHistoryItem: function(text)
{
if (this._uncommittedIsTop) {
this._data.pop();
delete this._uncommittedIsTop;
}

this._historyOffset = 1;
if (this._coalesceHistoryDupes && text === this._currentHistoryItem())
return;
this._data.push(text);
},


_pushCurrentText: function()
{
if (this._uncommittedIsTop)
this._data.pop(); 
this._uncommittedIsTop = true;
this.clearAutoComplete(true);
this._data.push(this.text);
},


_previous: function()
{
if (this._historyOffset > this._data.length)
return undefined;
if (this._historyOffset === 1)
this._pushCurrentText();
++this._historyOffset;
return this._currentHistoryItem();
},


_next: function()
{
if (this._historyOffset === 1)
return undefined;
--this._historyOffset;
return this._currentHistoryItem();
},

_currentHistoryItem: function()
{
return this._data[this._data.length - this._historyOffset];
},


defaultKeyHandler: function(event, force)
{
var newText;
var isPrevious;

switch (event.keyIdentifier) {
case "Up":
if (!this.isCaretOnFirstLine())
break;
newText = this._previous();
isPrevious = true;
break;
case "Down":
if (!this.isCaretOnLastLine())
break;
newText = this._next();
break;
case "U+0050": 
if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
newText = this._previous();
isPrevious = true;
}
break;
case "U+004E": 
if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey)
newText = this._next();
break;
}

if (newText !== undefined) {
event.consume(true);
this.text = newText;

if (isPrevious) {
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);
}
}

return true;
}

return WebInspector.TextPrompt.prototype.defaultKeyHandler.apply(this, arguments);
},

__proto__: WebInspector.TextPrompt.prototype
}







WebInspector.Popover = function(popoverHelper)
{
WebInspector.View.call(this);
this.markAsRoot();
this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll";

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

this._contentDiv = document.createElement("div");
this._contentDiv.className = "content";
this.element.appendChild(this._contentDiv);

this._popoverHelper = popoverHelper;
}

WebInspector.Popover.prototype = {

show: function(element, anchor, preferredWidth, preferredHeight, arrowDirection)
{
this._innerShow(null, element, anchor, preferredWidth, preferredHeight, arrowDirection);
},


showView: function(view, anchor, preferredWidth, preferredHeight)
{
this._innerShow(view, view.element, anchor, preferredWidth, preferredHeight);
},


_innerShow: function(view, contentElement, anchor, preferredWidth, preferredHeight, arrowDirection)
{
if (this._disposed)
return;
this.contentElement = contentElement;


if (WebInspector.Popover._popover)
WebInspector.Popover._popover.detach();
WebInspector.Popover._popover = this;


var preferredSize = view ? view.measurePreferredSize() : this.contentElement.measurePreferredSize();
preferredWidth = preferredWidth || preferredSize.width;
preferredHeight = preferredHeight || preferredSize.height;

WebInspector.View.prototype.show.call(this, document.body);

if (view)
view.show(this._contentDiv);
else
this._contentDiv.appendChild(this.contentElement);

this._positionElement(anchor, preferredWidth, preferredHeight, arrowDirection);

if (this._popoverHelper) {
contentElement.addEventListener("mousemove", this._popoverHelper._killHidePopoverTimer.bind(this._popoverHelper), true);
this.element.addEventListener("mouseout", this._popoverHelper._popoverMouseOut.bind(this._popoverHelper), true);
}
},

hide: function()
{
this.detach();
delete WebInspector.Popover._popover;
},

get disposed()
{
return this._disposed;
},

dispose: function()
{
if (this.isShowing())
this.hide();
this._disposed = true;
},

setCanShrink: function(canShrink)
{
this._hasFixedHeight = !canShrink;
this._contentDiv.addStyleClass("fixed-height");
},


_positionElement: function(anchorElement, preferredWidth, preferredHeight, arrowDirection)
{
const borderWidth = 25;
const scrollerWidth = this._hasFixedHeight ? 0 : 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 = anchorElement instanceof AnchorBox ? anchorElement : anchorElement.boxInWindow(window);
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) || (arrowDirection === WebInspector.Popover.Orientation.Bottom)) {

if ((anchorBox.y > newElementPosition.height + arrowHeight + borderRadius) || (arrowDirection === WebInspector.Popover.Orientation.Bottom))
newElementPosition.y = anchorBox.y - newElementPosition.height - arrowHeight;
else {
newElementPosition.y = borderRadius;
newElementPosition.height = anchorBox.y - borderRadius * 2 - arrowHeight;
if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
newElementPosition.y = borderRadius;
newElementPosition.height = preferredHeight;
}
}
verticalAlignment = WebInspector.Popover.Orientation.Bottom;
} else {

newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight;
if ((newElementPosition.y + newElementPosition.height + arrowHeight - borderWidth >= totalHeight) && (arrowDirection !== WebInspector.Popover.Orientation.Top)) {
newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height - borderRadius * 2 - arrowHeight;
if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
newElementPosition.y = totalHeight - preferredHeight - borderRadius;
newElementPosition.height = preferredHeight;
}
}

verticalAlignment = WebInspector.Popover.Orientation.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;
arrowRightPosition = Math.min(arrowRightPosition, newElementPosition.width - borderRadius - arrowOffset);
this._popupArrowElement.style.right = arrowRightPosition + "px";
} else {
newElementPosition.x = borderRadius;
newElementPosition.width = totalWidth - borderRadius * 2;
newElementPosition.height += scrollerWidth;
horizontalAlignment = "left";
if (verticalAlignment === WebInspector.Popover.Orientation.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 custom-popup-vertical-scroll custom-popup-horizontal-scroll " + 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";
},

__proto__: WebInspector.View.prototype
}


WebInspector.PopoverHelper = function(panelElement, getAnchor, showPopover, onHide, disableOnClick)
{
this._panelElement = panelElement;
this._getAnchor = getAnchor;
this._showPopover = showPopover;
this._onHide = onHide;
this._disableOnClick = !!disableOnClick;
panelElement.addEventListener("mousedown", this._mouseDown.bind(this), false);
panelElement.addEventListener("mousemove", this._mouseMove.bind(this), false);
panelElement.addEventListener("mouseout", this._mouseOut.bind(this), false);
this.setTimeout(1000);
}

WebInspector.PopoverHelper.prototype = {
setTimeout: function(timeout)
{
this._timeout = timeout;
},


_eventInHoverElement: function(event)
{
if (!this._hoverElement)
return false;
var box = this._hoverElement instanceof AnchorBox ? this._hoverElement : this._hoverElement.boxInWindow();
return (box.x <= event.clientX && event.clientX <= box.x + box.width &&
box.y <= event.clientY && event.clientY <= box.y + box.height);
},

_mouseDown: function(event)
{
if (this._disableOnClick || !this._eventInHoverElement(event))
this.hidePopover();
else {
this._killHidePopoverTimer();
this._handleMouseAction(event, true);
}
},

_mouseMove: function(event)
{

if (this._eventInHoverElement(event))
return;

this._startHidePopoverTimer();
this._handleMouseAction(event, false);
},

_popoverMouseOut: function(event)
{
if (!this.isPopoverVisible())
return;
if (event.relatedTarget && !event.relatedTarget.isSelfOrDescendant(this._popover._contentDiv))
this._startHidePopoverTimer();
},

_mouseOut: function(event)
{
if (!this.isPopoverVisible())
return;
if (!this._eventInHoverElement(event))
this._startHidePopoverTimer();
},

_startHidePopoverTimer: function()
{

if (!this._popover || this._hidePopoverTimer)
return;

function doHide()
{
this._hidePopover();
delete this._hidePopoverTimer;
}
this._hidePopoverTimer = setTimeout(doHide.bind(this), this._timeout / 2);
},

_handleMouseAction: function(event, isMouseDown)
{
this._resetHoverTimer();
if (event.which && this._disableOnClick)
return;
this._hoverElement = this._getAnchor(event.target, event);
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;
}
},

isPopoverVisible: function()
{
return !!this._popover;
},

hidePopover: function()
{
this._resetHoverTimer();
this._hidePopover();
},

_hidePopover: function()
{
if (!this._popover)
return;

if (this._onHide)
this._onHide();

this._popover.dispose();
delete this._popover;
this._hoverElement = null;
},

_mouseHover: function(element)
{
delete this._hoverTimer;

this._hidePopover();
this._popover = new WebInspector.Popover(this);
this._showPopover(element, this._popover);
},

_killHidePopoverTimer: function()
{
if (this._hidePopoverTimer) {
clearTimeout(this._hidePopoverTimer);
delete this._hidePopoverTimer;



this._resetHoverTimer();
}
}
}


WebInspector.Popover.Orientation = {
Top: "top",
Bottom: "bottom"
}


WebInspector.PopoverContentHelper = function(title)
{
this._contentTable = document.createElement("table");
var titleCell = this._createCell(WebInspector.UIString("%s - Details", title), "popover-details-title");
titleCell.colSpan = 2;
var titleRow = document.createElement("tr");
titleRow.appendChild(titleCell);
this._contentTable.appendChild(titleRow);
}

WebInspector.PopoverContentHelper.prototype = {
contentTable: function()
{
return this._contentTable;
},


_createCell: function(content, styleName)
{
var text = document.createElement("label");
text.appendChild(document.createTextNode(content));
var cell = document.createElement("td");
cell.className = "popover-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, "popover-details-row-title"));
row.appendChild(this._createCell(content, "popover-details-row-data"));
this._contentTable.appendChild(row);
},


appendElementRow: function(title, content, titleStyle)
{
var row = document.createElement("tr");
var titleCell = this._createCell(title, "popover-details-row-title");
if (titleStyle)
titleCell.addStyleClass(titleStyle);
row.appendChild(titleCell);
var cell = document.createElement("td");
cell.className = "details";
cell.appendChild(content);
row.appendChild(cell);
this._contentTable.appendChild(row);
},

appendStackTrace: function(title, stackTrace, callFrameLinkifier)
{
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 = "details";
row.appendChild(this._createCell(stackFrame.functionName ? stackFrame.functionName : WebInspector.UIString("(anonymous function)"), "function-name"));
row.appendChild(this._createCell(" @ "));
var linkCell = document.createElement("td");
var urlElement = callFrameLinkifier(stackFrame);
linkCell.appendChild(urlElement);
row.appendChild(linkCell);
framesTable.appendChild(row);
}
this.appendElementRow(title, framesTable, "popover-stacktrace-title");
}
}






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.textContent = 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;
},

discard: function()
{
}
}






WebInspector.TabbedPane = function()
{
WebInspector.View.call(this);
this.registerRequiredCSS("tabbedPane.css");
this.element.addStyleClass("tabbed-pane");
this._headerElement = this.element.createChild("div", "tabbed-pane-header");
this._headerContentsElement = this._headerElement.createChild("div", "tabbed-pane-header-contents");
this._tabsElement = this._headerContentsElement.createChild("div", "tabbed-pane-header-tabs");
this._contentElement = this.element.createChild("div", "tabbed-pane-content scroll-target");
this._tabs = [];
this._tabsHistory = [];
this._tabsById = {};
this.element.addEventListener("click", this.focus.bind(this), true);
this.element.addEventListener("mouseup", this.onMouseUp.bind(this), false);

this._dropDownButton = this._createDropDownButton();
}

WebInspector.TabbedPane.EventTypes = {
TabSelected: "TabSelected",
TabClosed: "TabClosed"
}

WebInspector.TabbedPane.prototype = {

get visibleView()
{
return this._currentTab ? this._currentTab.view : null;
},


get selectedTabId()
{
return this._currentTab ? this._currentTab.id : null;
},


set shrinkableTabs(shrinkableTabs)
{
this._shrinkableTabs = shrinkableTabs;
},


set verticalTabLayout(verticalTabLayout)
{
this._verticalTabLayout = verticalTabLayout;
},


set closeableTabs(closeableTabs)
{
this._closeableTabs = closeableTabs;
},

defaultFocusedElement: function()
{
return this.visibleView ? this.visibleView.defaultFocusedElement() : null;
},


setTabDelegate: function(delegate)
{
var tabs = this._tabs.slice();
for (var i = 0; i < tabs.length; ++i)
tabs[i].setDelegate(delegate);
this._delegate = delegate;
},


onMouseUp: function(event)
{

if (event.button === 1)
event.consume(true);
},


appendTab: function(id, tabTitle, view, tabTooltip, userGesture)
{
var tab = new WebInspector.TabbedPaneTab(this, id, tabTitle, this._closeableTabs, view, tabTooltip);
tab.setDelegate(this._delegate);
this._tabsById[id] = tab;

this._tabs.push(tab);
this._tabsHistory.push(tab);

if (this._tabsHistory[0] === tab)
this.selectTab(tab.id, userGesture);

this._updateTabElements();
},


closeTab: function(id, userGesture)
{
this.closeTabs([id], userGesture);
},


closeTabs: function(ids, userGesture)
{
for (var i = 0; i < ids.length; ++i)
this._innerCloseTab(ids[i], userGesture);
this._updateTabElements();
if (this._tabsHistory.length)
this.selectTab(this._tabsHistory[0].id, userGesture);
},


_innerCloseTab: function(id, userGesture)
{
if (this._currentTab && this._currentTab.id === id)
this._hideCurrentTab();

var tab = this._tabsById[id];
delete this._tabsById[id];

this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
this._tabs.splice(this._tabs.indexOf(tab), 1);
if (tab._shown)
this._hideTabElement(tab);

var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabClosed, eventData);
return true;
},


allTabs: function()
{
var result = [];
var tabs = this._tabs.slice();
for (var i = 0; i < tabs.length; ++i)
result.push(tabs[i].id);
return result;
},


otherTabs: function(id)
{
var result = [];
var tabs = this._tabs.slice();
for (var i = 0; i < tabs.length; ++i) {
if (tabs[i].id !== id)
result.push(tabs[i].id);
}
return result;
},


selectTab: function(id, userGesture)
{
var tab = this._tabsById[id];
if (!tab)
return;
if (this._currentTab && this._currentTab.id === id)
return;

this._hideCurrentTab();
this._showTab(tab);
this._currentTab = tab;

this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
this._tabsHistory.splice(0, 0, tab);

this._updateTabElements();

var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabSelected, eventData);
return true;
},


lastOpenedTabIds: function(tabsCount)
{
function tabToTabId(tab) {
return tab.id;
}

return this._tabsHistory.slice(0, tabsCount).map(tabToTabId);
},


changeTabTitle: function(id, tabTitle)
{
var tab = this._tabsById[id];
tab.title = tabTitle;
this._updateTabElements();
},


changeTabView: function(id, view)
{
var tab = this._tabsById[id];
if (this._currentTab && this._currentTab.id === tab.id) {
this._hideTab(tab);
tab.view = view;
this._showTab(tab);
} else
tab.view = view;
},


changeTabTooltip: function(id, tabTooltip)
{
var tab = this._tabsById[id];
tab.tooltip = tabTooltip;
},

onResize: function()
{
this._updateTabElements();
},

_updateTabElements: function()
{
WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements);
},


setPlaceholderText: function(text)
{
this._noTabsMessage = text;
},

_innerUpdateTabElements: function()
{
if (!this.isShowing())
return;

if (!this._tabs.length) {
this._contentElement.addStyleClass("has-no-tabs");
if (this._noTabsMessage && !this._noTabsMessageElement) {
this._noTabsMessageElement = this._contentElement.createChild("div", "tabbed-pane-placeholder fill");
this._noTabsMessageElement.textContent = this._noTabsMessage;
}
} else {
this._contentElement.removeStyleClass("has-no-tabs");
if (this._noTabsMessageElement) {
this._noTabsMessageElement.removeSelf();
delete this._noTabsMessageElement;
}
}

if (!this._measuredDropDownButtonWidth)
this._measureDropDownButton();

this._updateWidths();
this._updateTabsDropDown();
},


_showTabElement: function(index, tab)
{
if (index >= this._tabsElement.children.length)
this._tabsElement.appendChild(tab.tabElement);
else
this._tabsElement.insertBefore(tab.tabElement, this._tabsElement.children[index]);
tab._shown = true;
},


_hideTabElement: function(tab)
{
this._tabsElement.removeChild(tab.tabElement);
tab._shown = false;
},

_createDropDownButton: function()
{
var dropDownContainer = document.createElement("div");
dropDownContainer.addStyleClass("tabbed-pane-header-tabs-drop-down-container");
var dropDownButton = dropDownContainer.createChild("div", "tabbed-pane-header-tabs-drop-down");
dropDownButton.appendChild(document.createTextNode("\u00bb"));
this._tabsSelect = dropDownButton.createChild("select", "tabbed-pane-header-tabs-drop-down-select");
this._tabsSelect.addEventListener("change", this._tabsSelectChanged.bind(this), false);
return dropDownContainer;
},

_totalWidth: function()
{
return this._headerContentsElement.getBoundingClientRect().width;
},

_updateTabsDropDown: function()
{
var tabsToShowIndexes = this._tabsToShowIndexes(this._tabs, this._tabsHistory, this._totalWidth(), this._measuredDropDownButtonWidth);

for (var i = 0; i < this._tabs.length; ++i) {
if (this._tabs[i]._shown && tabsToShowIndexes.indexOf(i) === -1)
this._hideTabElement(this._tabs[i]);
}
for (var i = 0; i < tabsToShowIndexes.length; ++i) {
var tab = this._tabs[tabsToShowIndexes[i]];
if (!tab._shown)
this._showTabElement(i, tab);
}

this._populateDropDownFromIndex();
},

_populateDropDownFromIndex: function()
{
if (this._dropDownButton.parentElement)
this._headerContentsElement.removeChild(this._dropDownButton);

this._tabsSelect.removeChildren();
var tabsToShow = [];
for (var i = 0; i < this._tabs.length; ++i) {
if (!this._tabs[i]._shown)
tabsToShow.push(this._tabs[i]);
continue;
}

function compareFunction(tab1, tab2)
{
return tab1.title.localeCompare(tab2.title);
}
tabsToShow.sort(compareFunction);

for (var i = 0; i < tabsToShow.length; ++i) {
var option = new Option(tabsToShow[i].title);
option.tab = tabsToShow[i];
this._tabsSelect.appendChild(option);
}
if (this._tabsSelect.options.length) {
this._headerContentsElement.appendChild(this._dropDownButton);
this._tabsSelect.selectedIndex = -1;
}
},

_tabsSelectChanged: function()
{
var options = this._tabsSelect.options;
var selectedOption = options[this._tabsSelect.selectedIndex];
this.selectTab(selectedOption.tab.id, true);
},

_measureDropDownButton: function()
{
this._dropDownButton.addStyleClass("measuring");
this._headerContentsElement.appendChild(this._dropDownButton);
this._measuredDropDownButtonWidth = this._dropDownButton.getBoundingClientRect().width;
this._headerContentsElement.removeChild(this._dropDownButton);
this._dropDownButton.removeStyleClass("measuring");
},

_updateWidths: function()
{
var measuredWidths = this._measureWidths();
var maxWidth = this._shrinkableTabs ? this._calculateMaxWidth(measuredWidths.slice(), this._totalWidth()) : Number.MAX_VALUE;

var i = 0;
for (var tabId in this._tabs) {
var tab = this._tabs[tabId];
tab.setWidth(this._verticalTabLayout ? -1 : Math.min(maxWidth, measuredWidths[i++]));
}
},

_measureWidths: function()
{

var measuringTabElements = [];
for (var tabId in this._tabs) {
var tab = this._tabs[tabId];
if (typeof tab._measuredWidth === "number")
continue;
var measuringTabElement = tab._createTabElement(true);
measuringTabElement.__tab = tab;
measuringTabElements.push(measuringTabElement);
this._tabsElement.appendChild(measuringTabElement);
}


for (var i = 0; i < measuringTabElements.length; ++i)
measuringTabElements[i].__tab._measuredWidth = measuringTabElements[i].getBoundingClientRect().width;


for (var i = 0; i < measuringTabElements.length; ++i)
measuringTabElements[i].parentElement.removeChild(measuringTabElements[i]);


var measuredWidths = [];
for (var tabId in this._tabs)
measuredWidths.push(this._tabs[tabId]._measuredWidth);

return measuredWidths;
},


_calculateMaxWidth: function(measuredWidths, totalWidth)
{
if (!measuredWidths.length)
return 0;

measuredWidths.sort(function(x, y) { return x - y });

var totalMeasuredWidth = 0;
for (var i = 0; i < measuredWidths.length; ++i)
totalMeasuredWidth += measuredWidths[i];

if (totalWidth >= totalMeasuredWidth)
return measuredWidths[measuredWidths.length - 1];

var totalExtraWidth = 0;
for (var i = measuredWidths.length - 1; i > 0; --i) {
var extraWidth = measuredWidths[i] - measuredWidths[i - 1];
totalExtraWidth += (measuredWidths.length - i) * extraWidth;

if (totalWidth + totalExtraWidth >= totalMeasuredWidth)
return measuredWidths[i - 1] + (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i); 
}

return totalWidth / measuredWidths.length;
},


_tabsToShowIndexes: function(tabsOrdered, tabsHistory, totalWidth, measuredDropDownButtonWidth)
{
var tabsToShowIndexes = [];

var totalTabsWidth = 0;
for (var i = 0; i < tabsHistory.length; ++i) {
totalTabsWidth += tabsHistory[i].width();
var minimalRequiredWidth = totalTabsWidth;
if (i !== tabsHistory.length - 1)
minimalRequiredWidth += measuredDropDownButtonWidth;
if (!this._verticalTabLayout && minimalRequiredWidth > totalWidth)
break;
tabsToShowIndexes.push(tabsOrdered.indexOf(tabsHistory[i]));
}

tabsToShowIndexes.sort(function(x, y) { return x - y });

return tabsToShowIndexes;
},

_hideCurrentTab: function()
{
if (!this._currentTab)
return;

this._hideTab(this._currentTab);
delete this._currentTab;
},


_showTab: function(tab)
{
tab.tabElement.addStyleClass("selected");
tab.view.show(this._contentElement);
},


_hideTab: function(tab)
{
tab.tabElement.removeStyleClass("selected");
tab.view.detach();
},

canHighlightLine: function()
{
return this._currentTab && this._currentTab.view && this._currentTab.view.canHighlightLine();
},

highlightLine: function(line)
{
if (this.canHighlightLine())
this._currentTab.view.highlightLine(line);
},


elementsToRestoreScrollPositionsFor: function()
{
return [ this._contentElement ];
},


_insertBefore: function(tab, index)
{
this._tabsElement.insertBefore(tab._tabElement, this._tabsElement.childNodes[index]);
var oldIndex = this._tabs.indexOf(tab);
this._tabs.splice(oldIndex, 1);
if (oldIndex < index)
--index;
this._tabs.splice(index, 0, tab);
},

__proto__: WebInspector.View.prototype
}



WebInspector.TabbedPaneTab = function(tabbedPane, id, title, closeable, view, tooltip)
{
this._closeable = closeable;
this._tabbedPane = tabbedPane;
this._id = id;
this._title = title;
this._tooltip = tooltip;
this._view = view;
this._shown = false;
this._measuredWidth;
this._tabElement;
}

WebInspector.TabbedPaneTab.prototype = {

get id()
{
return this._id;
},


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

set title(title)
{
if (title === this._title)
return;
this._title = title;
if (this._titleElement)
this._titleElement.textContent = title;
delete this._measuredWidth;
},


get view()
{
return this._view;
},

set view(view)
{
this._view = view;
},


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

set tooltip(tooltip)
{
this._tooltip = tooltip;
if (this._titleElement)
this._titleElement.title = tooltip || "";
},


get tabElement()
{
if (typeof(this._tabElement) !== "undefined")
return this._tabElement;

this._createTabElement(false);
return this._tabElement;
},


width: function()
{
return this._width;
},


setWidth: function(width)
{
this.tabElement.style.width = width === -1 ? "" : (width + "px");
this._width = width;
},


setDelegate: function(delegate)
{
this._delegate = delegate;
},


_createTabElement: function(measuring)
{
var tabElement = document.createElement("div");
tabElement.addStyleClass("tabbed-pane-header-tab");
tabElement.id = "tab-" + this._id;
tabElement.tabIndex = -1;

var titleElement = tabElement.createChild("span", "tabbed-pane-header-tab-title");
titleElement.textContent = this.title;
titleElement.title = this.tooltip || "";
if (!measuring)
this._titleElement = titleElement;

if (this._closeable)
tabElement.createChild("div", "close-button-gray");

if (measuring)
tabElement.addStyleClass("measuring");
else {
this._tabElement = tabElement;
tabElement.addEventListener("click", this._tabClicked.bind(this), false);
tabElement.addEventListener("mousedown", this._tabMouseDown.bind(this), false);
if (this._closeable) {
tabElement.addEventListener("contextmenu", this._tabContextMenu.bind(this), false);
WebInspector.installDragHandle(tabElement, this._startTabDragging.bind(this), this._tabDragging.bind(this), this._endTabDragging.bind(this), "pointer");
}
}

return tabElement;
},


_tabClicked: function(event)
{
if (this._closeable && (event.button === 1 || event.target.hasStyleClass("close-button-gray")))
this._closeTabs([this.id]);
},


_tabMouseDown: function(event)
{
if (event.target.hasStyleClass("close-button-gray") || event.button === 1)
return;
this._tabbedPane.selectTab(this.id, true);
},


_closeTabs: function(ids)
{
if (this._delegate) {
this._delegate.closeTabs(this._tabbedPane, ids);
return;
}
this._tabbedPane.closeTabs(ids, true);
},

_tabContextMenu: function(event)
{
function close()
{
this._closeTabs([this.id]);
}

function closeOthers()
{
this._closeTabs(this._tabbedPane.otherTabs(this.id));
}

function closeAll()
{
this._closeTabs(this._tabbedPane.allTabs(this.id));
}

var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Close"), close.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Close others" : "Close Others"), closeOthers.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Close all" : "Close All"), closeAll.bind(this));
contextMenu.show();
},


_startTabDragging: function(event)
{
if (event.target.hasStyleClass("close-button-gray"))
return false;
this._dragStartX = event.pageX;
return true;
},


_tabDragging: function(event)
{
var tabElements = this._tabbedPane._tabsElement.childNodes;
for (var i = 0; i < tabElements.length; ++i) {
var tabElement = tabElements[i];
if (tabElement === this._tabElement)
continue;

var intersects = tabElement.offsetLeft + tabElement.clientWidth > this._tabElement.offsetLeft &&
this._tabElement.offsetLeft + this._tabElement.clientWidth > tabElement.offsetLeft;
if (!intersects)
continue;

if (Math.abs(event.pageX - this._dragStartX) < tabElement.clientWidth / 2 + 5)
break;

if (event.pageX - this._dragStartX > 0) {
tabElement = tabElement.nextSibling;
++i;
}

var oldOffsetLeft = this._tabElement.offsetLeft;
this._tabbedPane._insertBefore(this, i);
this._dragStartX += this._tabElement.offsetLeft - oldOffsetLeft;
break;
}

if (!this._tabElement.previousSibling && event.pageX - this._dragStartX < 0) {
this._tabElement.style.setProperty("left", "0px");
return;
}
if (!this._tabElement.nextSibling && event.pageX - this._dragStartX > 0) {
this._tabElement.style.setProperty("left", "0px");
return;
}

this._tabElement.style.setProperty("position", "relative");
this._tabElement.style.setProperty("left", (event.pageX - this._dragStartX) + "px");
},


_endTabDragging: function(event)
{
this._tabElement.style.removeProperty("position");
this._tabElement.style.removeProperty("left");
delete this._dragStartX;
}
}


WebInspector.TabbedPaneTabDelegate = function()
{
}

WebInspector.TabbedPaneTabDelegate.prototype = {

closeTabs: function(tabbedPane, ids) { }
}






WebInspector.ViewportControl = function(provider)
{
this.element = document.createElement("div");
this.element.className = "fill";
this.element.style.overflow = "auto";
this._topGapElement = this.element.createChild("div");
this._contentElement = this.element.createChild("div");
this._bottomGapElement = this.element.createChild("div");

this._provider = provider;
this.element.addEventListener("scroll", this._onScroll.bind(this), false);
this._firstVisibleIndex = 0;
this._lastVisibleIndex = -1;
}


WebInspector.ViewportControl.Provider = function() 
{
}

WebInspector.ViewportControl.Provider.prototype = { 

itemCount: function() { return 0; },


itemElement: function(index) { return null; }
}

WebInspector.ViewportControl.prototype = {

contentElement: function()
{
return this._contentElement;
},

refresh: function()
{
if (!this.element.clientHeight)
return;  

this._contentElement.removeChildren();
var itemCount = this._provider.itemCount();
if (!itemCount) {
this._firstVisibleIndex = -1;
this._lastVisibleIndex = -1;
return;
}

if (!this._rowHeight) {
var firstElement = this._provider.itemElement(0);
this._rowHeight = firstElement.measurePreferredSize(this._contentElement).height;
}

var visibleFrom = this.element.scrollTop;
var visibleTo = visibleFrom + this.element.clientHeight;

this._firstVisibleIndex = Math.floor(visibleFrom / this._rowHeight);
this._lastVisibleIndex = Math.min(Math.ceil(visibleTo / this._rowHeight), itemCount) - 1;

this._topGapElement.style.height = (this._rowHeight * this._firstVisibleIndex) + "px";
this._bottomGapElement.style.height = (this._rowHeight * (itemCount - this._lastVisibleIndex - 1)) + "px"; 

for (var i = this._firstVisibleIndex; i <= this._lastVisibleIndex; ++i)
this._contentElement.appendChild(this._provider.itemElement(i));
},


_onScroll: function(event)
{
this.refresh();
},


rowsPerViewport: function()
{
return Math.floor(this.element.clientHeight / this._rowHeight);
},


firstVisibleIndex: function()
{
return this._firstVisibleIndex;
},


lastVisibleIndex: function()
{
return this._lastVisibleIndex;
},


renderedElementAt: function(index)
{
if (index < this._firstVisibleIndex)
return null;
if (index > this._lastVisibleIndex)
return null;
return this._contentElement.childNodes[index - this._firstVisibleIndex];
},


scrollItemIntoView: function(index, makeLast)
{
if (index > this._firstVisibleIndex && index < this._lastVisibleIndex)
return;

if (makeLast)
this.element.scrollTop = this._rowHeight * (index + 1) - this.element.clientHeight;
else
this.element.scrollTop = this._rowHeight * index;
}
}






WebInspector.Drawer = function()
{
this.element = document.getElementById("drawer");
this.element.style.height = 0;

this._savedHeight = 200; 
this._mainElement = document.getElementById("main");
this._toolbarElement = document.getElementById("toolbar");

this._floatingStatusBarContainer = document.getElementById("floating-status-bar-container");
WebInspector.installDragHandle(this._floatingStatusBarContainer, this._startStatusBarDragging.bind(this), this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), "row-resize");

this._drawerContentsElement = document.createElement("div");
this._drawerContentsElement.id = "drawer-contents";
this._drawerContentsElement.className = "drawer-contents";
this.element.appendChild(this._drawerContentsElement);
this._viewStatusBar = document.createElement("div");
this._viewStatusBar.addEventListener("webkitTransitionEnd", this.immediatelyFinishAnimation.bind(this), false);
this._viewStatusBar.style.opacity = 0;
this._bottomStatusBar = document.getElementById("bottom-status-bar-container");

var drawerIsOverlay = WebInspector.experimentsSettings.drawerOverlay.isEnabled();
this._elementToAdjust = drawerIsOverlay ?  this._floatingStatusBarContainer : this._mainElement;

document.body.enableStyleClass("drawer-overlay", drawerIsOverlay);
}

WebInspector.Drawer.AnimationType = {
Immediately: 0,
Normal: 1,
Slow: 2
}

WebInspector.Drawer.prototype = {
get visible()
{
return !!this._view;
},

_constrainHeight: function(height)
{
return Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop() - Preferences.minConsoleHeight);
},

show: function(view, animationType)
{
this.immediatelyFinishAnimation();

var drawerWasVisible = this.visible;

if (this._view) {
this._view.detach();
this._drawerContentsElement.removeChildren();
}

this._view = view;

var statusBarItems = this._view.statusBarItems || [];
this._viewStatusBar.removeChildren();
for (var i = 0; i < statusBarItems.length; ++i)
this._viewStatusBar.appendChild(statusBarItems[i]);

document.body.addStyleClass("drawer-visible");
this._floatingStatusBarContainer.insertBefore(document.getElementById("panel-status-bar"), this._floatingStatusBarContainer.firstElementChild);
this._bottomStatusBar.appendChild(this._viewStatusBar);
this._view.detach();
this._view.markAsRoot();
this._view.show(this._drawerContentsElement);

if (drawerWasVisible)
return;

var height = this._constrainHeight(this._savedHeight || this.element.offsetHeight);

this._floatingStatusBarContainer.style.paddingLeft = this._bottomStatusBar.offsetLeft + "px";

function animationFinished()
{
WebInspector.inspectorView.currentPanel().doResize();
if (this._view && this._view.afterShow)
this._view.afterShow();
}

this._animationFinished = animationFinished.bind(this);


console.assert(this._viewStatusBar.style.opacity === "0");

function adjustStyles()
{
this._animationStyles(animationType).forEach(document.body.addStyleClass, document.body);

this.element.style.height = height + "px";
this._elementToAdjust.style.bottom = height + "px";
this._floatingStatusBarContainer.style.paddingLeft = 0;
this._viewStatusBar.style.opacity = 1;
}

if (animationType === WebInspector.Drawer.AnimationType.Immediately) {
adjustStyles.call(this);
this.immediatelyFinishAnimation();
} else
setTimeout(adjustStyles.bind(this), 0);
},

hide: function(animationType)
{
this.immediatelyFinishAnimation();
if (!this.visible)
return;

this._savedHeight = this.element.offsetHeight;

WebInspector.restoreFocusFromElement(this.element);



document.body.removeStyleClass("drawer-visible");
WebInspector.inspectorView.currentPanel().statusBarResized();
document.body.addStyleClass("drawer-visible");

function animationFinished()
{
WebInspector.inspectorView.currentPanel().doResize();
this._view.detach();
delete this._view;
this._bottomStatusBar.removeChildren();
this._bottomStatusBar.appendChild(document.getElementById("panel-status-bar"));
this._drawerContentsElement.removeChildren();
document.body.removeStyleClass("drawer-visible");
}

this._animationFinished = animationFinished.bind(this);


console.assert(this._viewStatusBar.style.opacity === "1");

function adjustStyles()
{
this._animationStyles(animationType).forEach(document.body.addStyleClass, document.body);

this.element.style.height = 0;
this._elementToAdjust.style.bottom = 0;
this._floatingStatusBarContainer.style.paddingLeft = this._bottomStatusBar.offsetLeft + "px";
this._viewStatusBar.style.opacity = 0;
}

if (animationType === WebInspector.Drawer.AnimationType.Immediately) {
adjustStyles.call(this);
this.immediatelyFinishAnimation();
} else
setTimeout(adjustStyles.bind(this), 0);
},

resize: function()
{
if (!this.visible)
return;

this._view.storeScrollPositions();
var height = this._constrainHeight(parseInt(this.element.style.height, 10));
this._elementToAdjust.style.bottom = height + "px";
this.element.style.height = height + "px";
this._view.doResize();
},

immediatelyFinishAnimation: function()
{
document.body.removeStyleClass("animate");
document.body.removeStyleClass("animate-slow");
if (this._animationFinished) {
this._animationFinished();
delete this._animationFinished;
}
},

_animationStyles: function(animationType)
{
switch (animationType) {
case WebInspector.Drawer.AnimationType.Slow:
return ["animate", "animate-slow"];
case WebInspector.Drawer.AnimationType.Normal:
return ["animate"];
default:
return [];
}
},


_startStatusBarDragging: function(event)
{
if (!this.visible || event.target !== this._floatingStatusBarContainer)
return false;

this._view.storeScrollPositions();
this._statusBarDragOffset = event.pageY - this.element.totalOffsetTop();
return true;
},

_statusBarDragging: function(event)
{
var height = window.innerHeight - event.pageY + this._statusBarDragOffset;
height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop() - Preferences.minConsoleHeight);

this._elementToAdjust.style.bottom = height + "px";
this.element.style.height = height + "px";
if (WebInspector.inspectorView.currentPanel())
WebInspector.inspectorView.currentPanel().doResize();
this._view.doResize();

event.consume(true);
},

_endStatusBarDragging: function(event)
{
this._savedHeight = this.element.offsetHeight;
delete this._statusBarDragOffset;

event.consume();
}
}


WebInspector.drawer = null;






WebInspector.ConsoleModel = function()
{
this.messages = [];
this.warnings = 0;
this.errors = 0;
this._interruptRepeatCount = false;
InspectorBackend.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this));
}

WebInspector.ConsoleModel.Events = {
ConsoleCleared: "console-cleared",
MessageAdded: "console-message-added",
RepeatCountUpdated: "repeat-count-updated"
}

WebInspector.ConsoleModel.prototype = {
enableAgent: function()
{
if (WebInspector.settings.monitoringXHREnabled.get())
ConsoleAgent.setMonitoringXHREnabled(true);

this._enablingConsole = true;
function callback()
{
delete this._enablingConsole;
}
ConsoleAgent.enable(callback.bind(this));
},


enablingConsole: function()
{
return !!this._enablingConsole;
},


addMessage: function(msg)
{
this.messages.push(msg);
this._previousMessage = msg;
this._incrementErrorWarningCount(msg);
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg);
this._interruptRepeatCount = false;
},


_incrementErrorWarningCount: function(msg)
{
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
this.warnings += msg.repeatDelta;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
this.errors += msg.repeatDelta;
break;
}
},

requestClearMessages: function()
{
ConsoleAgent.clearMessages();
this.clearMessages();
},

clearMessages: function()
{
this.messages = [];
delete this._previousMessage;

this.errors = 0;
this.warnings = 0;

this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);
},

interruptRepeatCount: function()
{
this._interruptRepeatCount = true;
},


_messageRepeatCountUpdated: function(count)
{
var msg = this._previousMessage;
if (!msg)
return;

var prevRepeatCount = msg.totalRepeatCount;

if (!this._interruptRepeatCount) {
msg.repeatDelta = count - prevRepeatCount;
msg.repeatCount = msg.repeatCount + msg.repeatDelta;
msg.totalRepeatCount = count;
msg.updateRepeatCount();

this._incrementErrorWarningCount(msg);
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.RepeatCountUpdated, msg);
} else {
var msgCopy = msg.clone();
msgCopy.totalRepeatCount = count;
msgCopy.repeatCount = (count - prevRepeatCount) || 1;
msgCopy.repeatDelta = msgCopy.repeatCount;
this.addMessage(msgCopy);
}
},

__proto__: WebInspector.Object.prototype
}


WebInspector.ConsoleMessage = function(source, level, url, line, repeatCount)
{
this.source = source;
this.level = level;
this.url = url || null;
this.line = line || 0;
this.message = "";

repeatCount = repeatCount || 1;
this.repeatCount = repeatCount;
this.repeatDelta = repeatCount;
this.totalRepeatCount = repeatCount;
}

WebInspector.ConsoleMessage.prototype = {

isErrorOrWarning: function()
{
return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
},

updateRepeatCount: function()
{

},


clone: function()
{

},


location: function()
{

}
}


WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
{
}


WebInspector.ConsoleMessage.MessageSource = {
XML: "xml",
JS: "javascript",
Network: "network",
ConsoleAPI: "console-api",
Storage: "storage",
AppCache: "appcache",
Rendering: "rendering",
CSS: "css",
Security: "security",
Other: "other",
Deprecation: "deprecation"
}

WebInspector.ConsoleMessage.MessageType = {
Log: "log",
Dir: "dir",
DirXML: "dirxml",
Table: "table",
Trace: "trace",
Clear: "clear",
StartGroup: "startGroup",
StartGroupCollapsed: "startGroupCollapsed",
EndGroup: "endGroup",
Assert: "assert",
Result: "result",
Profile: "profile",
ProfileEnd: "profileEnd"
}

WebInspector.ConsoleMessage.MessageLevel = {
Log: "log",
Warning: "warning",
Error: "error",
Debug: "debug"
}



WebInspector.ConsoleDispatcher = function(console)
{
this._console = console;
}

WebInspector.ConsoleDispatcher.prototype = {

messageAdded: function(payload)
{
var consoleMessage = WebInspector.ConsoleMessage.create(
payload.source,
payload.level,
payload.text,
payload.type,
payload.url,
payload.line,
payload.repeatCount,
payload.parameters,
payload.stackTrace,
payload.networkRequestId,
this._console._enablingConsole);
this._console.addMessage(consoleMessage);
},


messageRepeatCountUpdated: function(count)
{
this._console._messageRepeatCountUpdated(count);
},

messagesCleared: function()
{
if (!WebInspector.settings.preserveConsoleLog.get())
this._console.clearMessages();
}
}


WebInspector.console = null;






WebInspector.ConsoleMessageImpl = function(source, level, message, linkifier, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
{
WebInspector.ConsoleMessage.call(this, source, level, url, line, repeatCount);

this._linkifier = linkifier;
this.type = type || WebInspector.ConsoleMessage.MessageType.Log;
this._messageText = message;
this._parameters = parameters;
this._stackTrace = stackTrace;
this._request = requestId ? WebInspector.networkLog.requestForId(requestId) : null;
this._isOutdated = isOutdated;
this._dataGrids = [];
this._dataGridParents = new Map();

this._customFormatters = {
"object": this._formatParameterAsObject,
"array":  this._formatParameterAsArray,
"node":   this._formatParameterAsNode,
"string": this._formatParameterAsString
};
}

WebInspector.ConsoleMessageImpl.prototype = {
wasShown: function()
{
for (var i = 0; this._dataGrids && i < this._dataGrids.length; ++i) {
var dataGrid = this._dataGrids[i];
var parentElement = this._dataGridParents.get(dataGrid);
dataGrid.show(parentElement);
}
},

willHide: function()
{
for (var i = 0; this._dataGrids && i < this._dataGrids.length; ++i) {
var dataGrid = this._dataGrids[i];
this._dataGridParents.put(dataGrid, dataGrid.element.parentElement);
dataGrid.detach();
}
},

_formatMessage: function()
{
this._formattedMessage = document.createElement("span");
this._formattedMessage.className = "console-message-text source-code";

if (this.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) {
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Trace:
this._messageElement = document.createTextNode("console.trace()");
break;
case WebInspector.ConsoleMessage.MessageType.Clear:
this._messageElement = document.createTextNode(WebInspector.UIString("Console was cleared"));
this._formattedMessage.addStyleClass("console-info");
break;
case WebInspector.ConsoleMessage.MessageType.Assert:
var args = [WebInspector.UIString("Assertion failed:")];
if (this._parameters)
args = args.concat(this._parameters);
this._messageElement = this._format(args);
break;
case WebInspector.ConsoleMessage.MessageType.Dir:
var obj = this._parameters ? this._parameters[0] : undefined;
var args = ["%O", obj];
this._messageElement = this._format(args);
break;
case WebInspector.ConsoleMessage.MessageType.Profile:
var title = WebInspector.ProfilesPanelDescriptor.resolveProfileTitle(this._messageText);
this._messageElement = document.createTextNode(WebInspector.UIString("Profile '%s' started.", title));
break;
case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
var hashIndex = this._messageText.lastIndexOf("#");
var title = WebInspector.ProfilesPanelDescriptor.resolveProfileTitle(this._messageText.substring(0, hashIndex));
var uid = this._messageText.substring(hashIndex + 1);
var format = WebInspector.UIString("Profile '%s' finished.", "%_");
var link = WebInspector.linkifyURLAsNode("webkit-profile://CPU/" + uid, title);
this._messageElement = document.createElement("span");
this._formatWithSubstitutionString(format, [link], this._messageElement);
break;
default:
var args = this._parameters || [this._messageText];
this._messageElement = this._format(args);
}
} else if (this.source === WebInspector.ConsoleMessage.MessageSource.Network) {
if (this._request) {
this._stackTrace = this._request.initiator.stackTrace;
if (this._request.initiator && this._request.initiator.url) {
this.url = this._request.initiator.url;
this.line = this._request.initiator.lineNumber;
}
this._messageElement = document.createElement("span");
if (this.level === WebInspector.ConsoleMessage.MessageLevel.Error) {
this._messageElement.appendChild(document.createTextNode(this._request.requestMethod + " "));
this._messageElement.appendChild(WebInspector.linkifyRequestAsNode(this._request));
if (this._request.failed)
this._messageElement.appendChild(document.createTextNode(" " + this._request.localizedFailDescription));
else
this._messageElement.appendChild(document.createTextNode(" " + this._request.statusCode + " (" + this._request.statusText + ")"));
} else {
var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(this._messageText, WebInspector.linkifyRequestAsNode.bind(null, this._request, ""));
this._messageElement.appendChild(fragment);
}
} else {
if (this.url) {
var isExternal = !WebInspector.resourceForURL(this.url);
this._anchorElement = WebInspector.linkifyURLAsNode(this.url, this.url, "console-message-url", isExternal);
}
this._messageElement = this._format([this._messageText]);
}
} else {
var args = this._parameters || [this._messageText];
this._messageElement = this._format(args);
}

if (this.source !== WebInspector.ConsoleMessage.MessageSource.Network || this._request) {
if (this._stackTrace && this._stackTrace.length && this._stackTrace[0].url) {
this._anchorElement = this._linkifyCallFrame(this._stackTrace[0]);
} else if (this.url && this.url !== "undefined") {
this._anchorElement = this._linkifyLocation(this.url, this.line, 0);
}
}

this._formattedMessage.appendChild(this._messageElement);
if (this._anchorElement) {
this._formattedMessage.appendChild(document.createTextNode(" "));
this._formattedMessage.appendChild(this._anchorElement);
}

var dumpStackTrace = !!this._stackTrace && this._stackTrace.length && (this.source === WebInspector.ConsoleMessage.MessageSource.Network || this.level === WebInspector.ConsoleMessage.MessageLevel.Error || this.type === WebInspector.ConsoleMessage.MessageType.Trace);
if (dumpStackTrace) {
var ol = document.createElement("ol");
ol.className = "outline-disclosure";
var treeOutline = new TreeOutline(ol);

var content = this._formattedMessage;
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;
}


this._message = this._messageElement.textContent;
},

get message()
{

var formattedMessage = this.formattedMessage;
return this._message;
},

get formattedMessage()
{
if (!this._formattedMessage)
this._formatMessage();
return this._formattedMessage;
},


request: function()
{
return this._request;
},

_linkifyLocation: function(url, lineNumber, columnNumber)
{

lineNumber = lineNumber ? lineNumber - 1 : 0;
columnNumber = columnNumber ? columnNumber - 1 : 0;
return this._linkifier.linkifyLocation(url, lineNumber, columnNumber, "console-message-url");
},

_linkifyCallFrame: function(callFrame)
{
return this._linkifyLocation(callFrame.url, callFrame.lineNumber, callFrame.columnNumber);
},

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 (parameters[i] instanceof WebInspector.RemoteObject)
continue;

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[0].description, parameters.slice(1), formattedResult);
parameters = result.unusedSubstitutions;
if (parameters.length)
formattedResult.appendChild(document.createTextNode(" "));
}

if (this.type === WebInspector.ConsoleMessage.MessageType.Table) {
formattedResult.appendChild(this._formatParameterAsTable(parameters));
return formattedResult;
}


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

if (shouldFormatMessage && parameters[i].type === "string")
formattedResult.appendChild(document.createTextNode(parameters[i].description));
else
formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
if (i < parameters.length - 1)
formattedResult.appendChild(document.createTextNode(" "));
}
return formattedResult;
},


_formatParameter: function(output, forceObjectFormat, includePreview)
{
var type;
if (forceObjectFormat)
type = "object";
else if (output instanceof WebInspector.RemoteObject)
type = output.subtype || output.type;
else
type = typeof output;

var formatter = this._customFormatters[type];
if (!formatter) {
formatter = this._formatParameterAsValue;
output = output.description;
}

var span = document.createElement("span");
span.className = "console-formatted-" + type + " source-code";
formatter.call(this, output, span, includePreview);
return span;
},

_formatParameterAsValue: function(val, elem)
{
elem.appendChild(document.createTextNode(val));
},

_formatParameterAsObject: function(obj, elem, includePreview)
{
this._formatParameterAsArrayOrObject(obj, obj.description, elem, includePreview);
},


_formatParameterAsArrayOrObject: function(obj, description, elem, includePreview)
{
var titleElement = document.createElement("span");
if (description)
titleElement.createTextChild(description);
if (includePreview && obj.preview) {
titleElement.addStyleClass("console-object-preview");
var lossless = this._appendObjectPreview(obj, description, titleElement);
if (lossless) {
elem.appendChild(titleElement);
return;
}
}
var section = new WebInspector.ObjectPropertiesSection(obj, titleElement);
section.enableContextMenu();
elem.appendChild(section.element);

var note = section.titleElement.createChild("span", "object-info-state-note");
note.title = WebInspector.UIString("Object state below is captured upon first expansion");
},


_appendObjectPreview: function(obj, description, titleElement)
{
var preview = obj.preview;
var isArray = obj.subtype === "array";

if (description)
titleElement.createTextChild(" ");
titleElement.createTextChild(isArray ? "[" : "{");
for (var i = 0; i < preview.properties.length; ++i) {
if (i > 0)
titleElement.createTextChild(", ");

var property = preview.properties[i];
if (!isArray || property.name != i) {
titleElement.createChild("span", "name").textContent = property.name;
titleElement.createTextChild(": ");
}

titleElement.appendChild(this._renderPropertyPreview(property));
}
if (preview.overflow)
titleElement.createChild("span").textContent = "\u2026";
titleElement.createTextChild(isArray ? "]" : "}");
return preview.lossless;
},


_renderPropertyPreview: function(property)
{
var span = document.createElement("span");
span.className = "console-formatted-" + property.type;

if (property.type === "function") {
span.textContent = "function";
return span;
}

if (property.type === "object" && property.subtype === "regexp") {
span.addStyleClass("console-formatted-string");
span.textContent = property.value;
return span;
}

if (property.type === "object" && property.subtype === "node" && property.value) {
span.addStyleClass("console-formatted-preview-node");
WebInspector.DOMPresentationUtils.createSpansForNodeTitle(span, property.value);
return span;
}

if (property.type === "string") {
span.textContent = "\"" + property.value + "\"";
return span;
}

span.textContent = property.value;
return span;
},

_formatParameterAsNode: function(object, elem)
{
function printNode(nodeId)
{
if (!nodeId) {


this._formatParameterAsObject(object, elem, false);
return;
}
var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true);
treeOutline.setVisible(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);
treeOutline.element.treeElementForTest = treeOutline.children[0];
}
object.pushNodeToFrontend(printNode.bind(this));
},


useArrayPreviewInFormatter: function(array)
{
return this.type !== WebInspector.ConsoleMessage.MessageType.DirXML && !!array.preview;
},


_formatParameterAsArray: function(array, elem)
{
if (this.useArrayPreviewInFormatter(array)) {
this._formatParameterAsArrayOrObject(array, "", elem, true);
return;
}

const maxFlatArrayLength = 100;
if (this._isOutdated || array.arrayLength() > maxFlatArrayLength)
this._formatParameterAsObject(array, elem, false);
else
array.getOwnProperties(this._printArray.bind(this, array, elem));
},


_formatParameterAsTable: function(parameters)
{
var element = document.createElement("span");
var table = parameters[0];
if (!table || !table.preview)
return element;

var columnNames = [];
var preview = table.preview;
var rows = [];
for (var i = 0; i < preview.properties.length; ++i) {
var rowProperty = preview.properties[i];
var rowPreview = rowProperty.valuePreview;
if (!rowPreview)
continue;

var rowValue = {};
const maxColumnsToRender = 20;
for (var j = 0; j < rowPreview.properties.length && columnNames.length < maxColumnsToRender; ++j) {
var cellProperty = rowPreview.properties[j];
if (columnNames.indexOf(cellProperty.name) === -1)
columnNames.push(cellProperty.name);
rowValue[cellProperty.name] = this._renderPropertyPreview(cellProperty);
}
rows.push([rowProperty.name, rowValue]);
}

var flatValues = [];
for (var i = 0; i < rows.length; ++i) {
var rowName = rows[i][0];
var rowValue = rows[i][1];
flatValues.push(rowName);
for (var j = 0; j < columnNames.length; ++j)
flatValues.push(rowValue[columnNames[j]]);
}

if (!flatValues.length)
return element;
columnNames.unshift(WebInspector.UIString("(index)"));
var dataGrid = WebInspector.DataGrid.createSortableDataGrid(columnNames, flatValues);
dataGrid.renderInline();
this._dataGrids.push(dataGrid);
this._dataGridParents.put(dataGrid, element);
return element;
},

_formatParameterAsString: 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(array, elem, properties)
{
if (!properties)
return;

var elements = [];
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
var name = property.name;
if (!isNaN(name))
elements[name] = this._formatAsArrayEntry(property.value);
}

elem.appendChild(document.createTextNode("["));
var lastNonEmptyIndex = -1;

function appendUndefined(elem, index)
{
if (index - lastNonEmptyIndex <= 1)
return;
var span = elem.createChild("span", "console-formatted-undefined");
span.textContent = WebInspector.UIString("undefined × %d", index - lastNonEmptyIndex - 1);
}

var length = array.arrayLength();
for (var i = 0; i < length; ++i) {
var element = elements[i];
if (!element)
continue;

if (i - lastNonEmptyIndex > 1) {
appendUndefined(elem, i);
elem.appendChild(document.createTextNode(", "));
}

elem.appendChild(element);
lastNonEmptyIndex = i;
if (i < length - 1)
elem.appendChild(document.createTextNode(", "));
}
appendUndefined(elem, length);

elem.appendChild(document.createTextNode("]"));
},

_formatAsArrayEntry: function(output)
{

return this._formatParameter(output, output.subtype && output.subtype === "array", false);
},

_formatWithSubstitutionString: function(format, parameters, formattedResult)
{
var formatters = {};

function parameterFormatter(force, obj)
{
return this._formatParameter(obj, force, false);
}

function stringFormatter(obj)
{
return obj.description;
}

function floatFormatter(obj)
{
if (typeof obj.value !== "number")
return "NaN";
return obj.value;
}

function integerFormatter(obj)
{
if (typeof obj.value !== "number")
return "NaN";
return Math.floor(obj.value);
}

function bypassFormatter(obj)
{
return (obj instanceof Node) ? obj : "";
}

var currentStyle = null;
function styleFormatter(obj)
{
currentStyle = {};
var buffer = document.createElement("span");
buffer.setAttribute("style", obj.description);
for (var i = 0; i < buffer.style.length; i++) {
var property = buffer.style[i];
if (isWhitelistedProperty(property))
currentStyle[property] = buffer.style[property];
}
}

function isWhitelistedProperty(property)
{
var prefixes = ["background", "border", "color", "font", "line", "margin", "padding", "text", "-webkit-background", "-webkit-border", "-webkit-font", "-webkit-margin", "-webkit-padding", "-webkit-text"];
for (var i = 0; i < prefixes.length; i++) {
if (property.startsWith(prefixes[i]))
return true;
}
return false;
}


formatters.o = parameterFormatter.bind(this, false);
formatters.s = stringFormatter;
formatters.f = floatFormatter;

formatters.i = integerFormatter;
formatters.d = integerFormatter;


formatters.c = styleFormatter;


formatters.O = parameterFormatter.bind(this, true);

formatters._ = bypassFormatter;

function append(a, b)
{
if (b instanceof Node)
a.appendChild(b);
else if (typeof b !== "undefined") {
var toAppend = WebInspector.linkifyStringAsFragment(String(b));
if (currentStyle) {
var wrapper = document.createElement('span');
for (var key in currentStyle)
wrapper.style[key] = currentStyle[key];
wrapper.appendChild(toAppend);
toAppend = wrapper;
}
a.appendChild(toAppend);
}
return a;
}


return String.format(format, parameters, formatters, formattedResult, append);
},

clearHighlight: function()
{
if (!this._formattedMessage)
return;

var highlightedMessage = this._formattedMessage;
delete this._formattedMessage;
delete this._anchorElement;
delete this._messageElement;
this._formatMessage();
this._element.replaceChild(this._formattedMessage, highlightedMessage);
},

highlightSearchResults: function(regexObject)
{
if (!this._formattedMessage)
return;

this._highlightSearchResultsInElement(regexObject, this._messageElement);
if (this._anchorElement)
this._highlightSearchResultsInElement(regexObject, this._anchorElement);

this._element.scrollIntoViewIfNeeded();
},

_highlightSearchResultsInElement: function(regexObject, element)
{
regexObject.lastIndex = 0;
var text = element.textContent;
var match = regexObject.exec(text);
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}
WebInspector.highlightSearchResults(element, matchRanges);
},

matchesRegex: function(regexObject)
{
return regexObject.test(this._message) || (this._anchorElement && regexObject.test(this._anchorElement.textContent));
},

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.level) {
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");

element.appendChild(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);

if (frame.url) {
content.appendChild(document.createTextNode(" "));
var urlElement = this._linkifyCallFrame(frame);
content.appendChild(urlElement);
}

var treeElement = new TreeElement(content);
parentTreeElement.appendChild(treeElement);
}
},

updateRepeatCount: function() {
if (!this._element)
return;

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.XML:
sourceString = "XML";
break;
case WebInspector.ConsoleMessage.MessageSource.JS:
sourceString = "JS";
break;
case WebInspector.ConsoleMessage.MessageSource.Network:
sourceString = "Network";
break;
case WebInspector.ConsoleMessage.MessageSource.ConsoleAPI:
sourceString = "ConsoleAPI";
break;
case WebInspector.ConsoleMessage.MessageSource.Storage:
sourceString = "Storage";
break;
case WebInspector.ConsoleMessage.MessageSource.AppCache:
sourceString = "AppCache";
break;
case WebInspector.ConsoleMessage.MessageSource.Rendering:
sourceString = "Rendering";
break;
case WebInspector.ConsoleMessage.MessageSource.CSS:
sourceString = "CSS";
break;
case WebInspector.ConsoleMessage.MessageSource.Security:
sourceString = "Security";
break;
case WebInspector.ConsoleMessage.MessageSource.Other:
sourceString = "Other";
break;
}

var typeString;
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Log:
typeString = "Log";
break;
case WebInspector.ConsoleMessage.MessageType.Dir:
typeString = "Dir";
break;
case WebInspector.ConsoleMessage.MessageType.DirXML:
typeString = "Dir XML";
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;
case WebInspector.ConsoleMessage.MessageType.Profile:
case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
typeString = "Profiling";
break;
}

var levelString;
switch (this.level) {
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;
},

get text()
{
return this._messageText;
},

location: function()
{

var lineNumber = this.stackTrace ? this.stackTrace[0].lineNumber - 1 : this.line - 1;
var columnNumber = this.stackTrace && this.stackTrace[0].columnNumber ? this.stackTrace[0].columnNumber - 1 : 0;
return WebInspector.debuggerModel.createRawLocationByURL(this.url, lineNumber, columnNumber);
},

isEqual: function(msg)
{
if (!msg)
return false;

if (this._stackTrace) {
if (!msg._stackTrace)
return false;
var l = this._stackTrace;
var r = msg._stackTrace;
if (l.length !== r.length) 
return false;
for (var i = 0; i < l.length; i++) {
if (l[i].url !== r[i].url ||
l[i].functionName !== r[i].functionName ||
l[i].lineNumber !== r[i].lineNumber ||
l[i].columnNumber !== r[i].columnNumber)
return false;
}
}

return (this.source === msg.source)
&& (this.type === msg.type)
&& (this.level === msg.level)
&& (this.line === msg.line)
&& (this.url === msg.url)
&& (this.message === msg.message)
&& (this._request === msg._request);
},

get stackTrace()
{
return this._stackTrace;
},


clone: function()
{
return WebInspector.ConsoleMessage.create(this.source, this.level, this._messageText, this.type, this.url, this.line, this.repeatCount, this._parameters, this._stackTrace, this._request ? this._request.requestId : undefined, this._isOutdated);
},

__proto__: WebInspector.ConsoleMessage.prototype
}






WebInspector.ConsoleView = function(hideContextSelector)
{
WebInspector.View.call(this);

this.element.id = "console-view";
this._messageLevelFilters = {};
this._messageURLFilters = WebInspector.settings.messageURLFilters.get();
this._visibleMessages = [];
this._messages = [];
this._urlToMessageCount = {};

this._clearConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear console log."), "clear-status-bar-item");
this._clearConsoleButton.addEventListener("click", this._requestClearMessages, this);

this._frameSelector = new WebInspector.StatusBarComboBox(this._frameChanged.bind(this), "console-context");
this._contextSelector = new WebInspector.StatusBarComboBox(this._contextChanged.bind(this), "console-context");

if (hideContextSelector) {
this._frameSelector.element.addStyleClass("hidden");
this._contextSelector.element.addStyleClass("hidden");
}

this.messagesElement = document.createElement("div");
this.messagesElement.id = "console-messages";
this.messagesElement.className = "monospace";
this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);
this.element.appendChild(this.messagesElement);
this._scrolledToBottom = true;

this.promptElement = document.createElement("div");
this.promptElement.id = "console-prompt";
this.promptElement.className = "source-code";
this.promptElement.spellcheck = false;
this.messagesElement.appendChild(this.promptElement);
this.messagesElement.appendChild(document.createElement("br"));

this.topGroup = new WebInspector.ConsoleGroup(null);
this.messagesElement.insertBefore(this.topGroup.element, this.promptElement);
this.currentGroup = this.topGroup;

this._filterBarElement = document.createElement("div");
this._filterBarElement.className = "scope-bar status-bar-item";

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, label)
{
var categoryElement = document.createElement("li");
categoryElement.category = category;
categoryElement.className = category;
categoryElement.addEventListener("click", updateFilterHandler, false);
categoryElement.textContent = label;

this._filterBarElement.appendChild(categoryElement);

return categoryElement;
}

this.allElement = createFilterElement.call(this, "all", WebInspector.UIString("All"));
createDividerElement.call(this);
this.errorElement = createFilterElement.call(this, "error", WebInspector.UIString("Errors"));
this.warningElement = createFilterElement.call(this, "warning", WebInspector.UIString("Warnings"));
this.logElement = createFilterElement.call(this, "log", WebInspector.UIString("Logs"));
this.debugElement = createFilterElement.call(this, "debug", WebInspector.UIString("Debug"));

this.filter(this.allElement, false);
this._registerShortcuts();
this.registerRequiredCSS("textPrompt.css");

this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);

WebInspector.settings.monitoringXHREnabled.addChangeListener(this._monitoringXHREnabledSettingChanged.bind(this));

WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);

this._linkifier = new WebInspector.Linkifier();

this.prompt = new WebInspector.TextPromptWithHistory(WebInspector.runtimeModel.completionsForTextPrompt.bind(WebInspector.runtimeModel));
this.prompt.setSuggestBoxEnabled("generic-suggest");
this.prompt.renderAsBlock();
this.prompt.attach(this.promptElement);
this.prompt.proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false);
this.prompt.setHistoryData(WebInspector.settings.consoleHistory.get());

WebInspector.runtimeModel.contextLists().forEach(this._addFrame, this);
WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, this._frameAdded, this);
WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, this._frameRemoved, this);
}

WebInspector.ConsoleView.Events = {
ConsoleCleared: "console-cleared",
EntryAdded: "console-entry-added",
}

WebInspector.ConsoleView.prototype = {
get statusBarItems()
{
return [this._clearConsoleButton.element, this._frameSelector.element, this._contextSelector.element, this._filterBarElement];
},


_frameAdded: function(event)
{
var contextList =   (event.data);
this._addFrame(contextList);
},


_addFrame: function(contextList)
{
var option = this._frameSelector.createOption(contextList.displayName, contextList.url);
option._contextList = contextList;
contextList._consoleOption = option;
contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextsUpdated, this._frameUpdated, this);
contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextAdded, this._contextAdded, this);
this._frameChanged();
},


_frameRemoved: function(event)
{
var contextList =   (event.data);
this._frameSelector.removeOption(contextList._consoleOption);
this._frameChanged();
},

_frameChanged: function()
{
var context = this._currentFrame();
if (!context) {
WebInspector.runtimeModel.setCurrentExecutionContext(null);
this._contextSelector.element.addStyleClass("hidden");
return;
}

var executionContexts = context.executionContexts();
if (executionContexts.length)
WebInspector.runtimeModel.setCurrentExecutionContext(executionContexts[0]);

if (executionContexts.length === 1) {
this._contextSelector.element.addStyleClass("hidden");
return;
}
this._contextSelector.element.removeStyleClass("hidden");
this._contextSelector.removeOptions();
for (var i = 0; i < executionContexts.length; i++)
this._appendContextOption(executionContexts[i]);
},


_appendContextOption: function(executionContext)
{
if (!WebInspector.runtimeModel.currentExecutionContext())
WebInspector.runtimeModel.setCurrentExecutionContext(executionContext);
var option = this._contextSelector.createOption(executionContext.name, executionContext.id);
option._executionContext = executionContext;
},


_contextChanged: function(event)
{
var option = this._contextSelector.selectedOption();
WebInspector.runtimeModel.setCurrentExecutionContext(option ? option._executionContext : null);
},


_frameUpdated: function(event)
{
var contextList =   event.data;
var option = contextList._consoleOption;
option.text = contextList.displayName;
option.title = contextList.url;
},


_contextAdded: function(event)
{
var contextList =   event.data;
if (contextList === this._currentFrame())
this._frameChanged();
},


_currentFrame: function()
{
var option = this._frameSelector.selectedOption();
return option ? option._contextList : undefined;
},

_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._messageLevelFilters = {};

this.allElement.removeStyleClass("selected");
this.errorElement.removeStyleClass("selected");
this.warningElement.removeStyleClass("selected");
this.logElement.removeStyleClass("selected");
this.debugElement.removeStyleClass("selected");
}

if (target.category === "all") {
unselectAll.call(this);
target.addStyleClass("selected");
this._messageLevelFilters = {error: true, warning: true, log: true, debug: true};
} else {

if (this.allElement.hasStyleClass("selected")) {
this._messageLevelFilters = {};
this.allElement.removeStyleClass("selected");
}

if (!selectMultiple) {


unselectAll.call(this);

target.addStyleClass("selected");

this._messageLevelFilters = {};
this._messageLevelFilters[target.category] = true;
} else {

if (target.hasStyleClass("selected")) {


target.removeStyleClass("selected");

if (this._messageLevelFilters[target.category])
delete this._messageLevelFilters[target.category];

} else {


target.addStyleClass("selected");

this._messageLevelFilters[target.category] = true;
}
}
}

this._updateMessageList();
},

willHide: function()
{
this.prompt.hideSuggestBox();
this.prompt.clearAutoComplete(true);
},

wasShown: function()
{
if (!this.prompt.isCaretInsidePrompt())
this.prompt.moveCaretToEndOfPrompt();
},

afterShow: function()
{
WebInspector.setCurrentFocusElement(this.promptElement);
},

storeScrollPositions: function()
{
WebInspector.View.prototype.storeScrollPositions.call(this);
this._scrolledToBottom = this.messagesElement.isScrolledToBottom();
},

restoreScrollPositions: function()
{
if (this._scrolledToBottom)
this._immediatelyScrollIntoView();
else
WebInspector.View.prototype.restoreScrollPositions.call(this);
},

onResize: function()
{
this.restoreScrollPositions();
},

_isScrollIntoViewScheduled: function()
{
return !!this._scrollIntoViewTimer;
},

_scheduleScrollIntoView: function()
{
if (this._scrollIntoViewTimer)
return;

function scrollIntoView()
{
delete this._scrollIntoViewTimer;
this.promptElement.scrollIntoView(true);
}
this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20);
},

_immediatelyScrollIntoView: function()
{
this.promptElement.scrollIntoView(true);
this._cancelScheduledScrollIntoView();
},

_cancelScheduledScrollIntoView: function()
{
if (!this._isScrollIntoViewScheduled())
return;

clearTimeout(this._scrollIntoViewTimer);
delete this._scrollIntoViewTimer;
},


_consoleMessageAdded: function(event)
{
var message =   (event.data);
this._messages.push(message);

if (this._urlToMessageCount[message.url])
this._urlToMessageCount[message.url]++;
else
this._urlToMessageCount[message.url] = 1;

if (this._shouldBeVisible(message))
this._appendConsoleMessage(message);
},

_appendConsoleMessage: function(message)
{


if (!this._isScrollIntoViewScheduled() && ((message instanceof WebInspector.ConsoleCommandResult) || this.messagesElement.isScrolledToBottom()))
this._scheduleScrollIntoView();

this._visibleMessages.push(message);

if (message.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
var parentGroup = this.currentGroup.parentGroup
if (parentGroup)
this.currentGroup = parentGroup;
} else {
if (message.type === WebInspector.ConsoleMessage.MessageType.StartGroup || message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
var group = new WebInspector.ConsoleGroup(this.currentGroup);
this.currentGroup.messagesElement.appendChild(group.element);
this.currentGroup = group;
message.group = group;
}
this.currentGroup.addMessage(message);
}

this.dispatchEventToListeners(WebInspector.ConsoleView.Events.EntryAdded, message);
},

_consoleCleared: function()
{
this._scrolledToBottom = true;
for (var i = 0; i < this._visibleMessages.length; ++i)
this._visibleMessages[i].willHide();
this._visibleMessages = [];
this._messages = [];

this.currentGroup = this.topGroup;
this.topGroup.messagesElement.removeChildren();

this.dispatchEventToListeners(WebInspector.ConsoleView.Events.ConsoleCleared);

this._linkifier.reset();
},

_handleContextMenuEvent: function(event)
{
if (!window.getSelection().isCollapsed) {


return;
}

if (event.target.enclosingNodeOrSelfWithNodeName("a"))
return;

var contextMenu = new WebInspector.ContextMenu(event);

function monitoringXHRItemAction()
{
WebInspector.settings.monitoringXHREnabled.set(!WebInspector.settings.monitoringXHREnabled.get());
}
contextMenu.appendCheckboxItem(WebInspector.UIString("Log XMLHttpRequests"), monitoringXHRItemAction.bind(this), WebInspector.settings.monitoringXHREnabled.get());

function preserveLogItemAction()
{
WebInspector.settings.preserveConsoleLog.set(!WebInspector.settings.preserveConsoleLog.get());
}
contextMenu.appendCheckboxItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Preserve log upon navigation" : "Preserve Log upon Navigation"), preserveLogItemAction.bind(this), WebInspector.settings.preserveConsoleLog.get());

var sourceElement = event.target.enclosingNodeOrSelfWithClass("console-message");

var filterSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Filter"));

if (sourceElement && sourceElement.message.url)
filterSubMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Hide messages from %s" : "Hide Messages from %s", new WebInspector.ParsedURL(sourceElement.message.url).displayName), this._addMessageURLFilter.bind(this, sourceElement.message.url));

filterSubMenu.appendSeparator();
var unhideAll = filterSubMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Unhide all" : "Unhide All"), this._removeMessageURLFilter.bind(this));
filterSubMenu.appendSeparator();

var hasFilters = false;
for (var url in this._messageURLFilters) {
if (this._messageURLFilters.hasOwnProperty(url)) {
filterSubMenu.appendCheckboxItem(String.sprintf("%s (%d)", new WebInspector.ParsedURL(url).displayName, this._urlToMessageCount[url]), this._removeMessageURLFilter.bind(this, url), true);
hasFilters = true;
}
}

filterSubMenu.setEnabled(hasFilters || (sourceElement && sourceElement.message.url));
unhideAll.setEnabled(hasFilters);

contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear console" : "Clear Console"), this._requestClearMessages.bind(this));

var messageElement = event.target.enclosingNodeOrSelfWithClass("console-message");
var request = (messageElement && messageElement.message) ? messageElement.message.request() : null;
if (request && request.type === WebInspector.resourceTypes.XHR) {
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString("Replay XHR"), NetworkAgent.replayXHR.bind(null, request.requestId));
}

contextMenu.show();
},


_addMessageURLFilter: function(url)
{
this._messageURLFilters[url] = true;
WebInspector.settings.messageURLFilters.set(this._messageURLFilters);
this._updateMessageList();
},


_removeMessageURLFilter: function(url)
{
if (!url)
this._messageURLFilters = {};
else
delete this._messageURLFilters[url];

WebInspector.settings.messageURLFilters.set(this._messageURLFilters);

this._updateMessageList();
},


_shouldBeVisible: function(message)
{
return (message.type === WebInspector.ConsoleMessage.MessageType.StartGroup || message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed || message.type === WebInspector.ConsoleMessage.MessageType.EndGroup) ||
((!message.url || !this._messageURLFilters[message.url]) && (!message.level || this._messageLevelFilters[message.level]));
},


_updateMessageList: function()
{
var group = this.topGroup;
var sourceMessages = this._messages;
var visibleMessageIndex = 0;
var newVisibleMessages = [];
var anchor = null;
for (var i = 0; i < sourceMessages.length; i++) {
var sourceMessage = sourceMessages[i];
var visibleMessage = this._visibleMessages[visibleMessageIndex];

if (visibleMessage === sourceMessage) {
visibleMessageIndex++;
if (this._shouldBeVisible(visibleMessage)) {
newVisibleMessages.push(visibleMessage);
if (sourceMessage.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
anchor = group.element;
group = group.parentGroup || group;
} else if (sourceMessage.type === WebInspector.ConsoleMessage.MessageType.StartGroup || sourceMessage.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
group = sourceMessage.group;
anchor = group.messagesElement.firstChild;
}
} else {
visibleMessage.willHide();
visibleMessage.toMessageElement().removeSelf();
}
} else {
if (this._shouldBeVisible(sourceMessage)) {
group.addMessage(sourceMessage, anchor ? anchor.nextSibling : group.messagesElement.firstChild);
newVisibleMessages.push(sourceMessage);
anchor = sourceMessage.toMessageElement();
}
}
}

this._visibleMessages = newVisibleMessages;
},

_monitoringXHREnabledSettingChanged: function(event)
{
ConsoleAgent.setMonitoringXHREnabled(event.data);
},

_messagesClicked: function(event)
{
if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
this.prompt.moveCaretToEndOfPrompt();
},

_registerShortcuts: function()
{
this._shortcuts = {};

var shortcut = WebInspector.KeyboardShortcut;
var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));

var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
this._shortcuts[shortcutL.key] = this._requestClearMessages.bind(this);
var keys = [shortcutL];
if (WebInspector.isMac()) {
var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta);
this._shortcuts[shortcutK.key] = this._requestClearMessages.bind(this);
keys.unshift(shortcutK);
}
section.addAlternateKeys(keys, WebInspector.UIString("Clear console"));

section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tab), WebInspector.UIString("Autocomplete common prefix"));
section.addKey(shortcut.makeDescriptor(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion"));

keys = [
shortcut.makeDescriptor(shortcut.Keys.Down),
shortcut.makeDescriptor(shortcut.Keys.Up)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line"));

if (WebInspector.isMac()) {
keys = [
shortcut.makeDescriptor("N", shortcut.Modifiers.Alt),
shortcut.makeDescriptor("P", shortcut.Modifiers.Alt)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command"));
}

section.addKey(shortcut.makeDescriptor(shortcut.Keys.Enter), WebInspector.UIString("Execute command"));
},

_requestClearMessages: function()
{
WebInspector.console.requestClearMessages();
},

_promptKeyDown: function(event)
{
if (isEnterKey(event)) {
this._enterKeyPressed(event);
return;
}

var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcut];
if (handler) {
handler();
event.preventDefault();
return;
}
},

evaluateUsingTextPrompt: function(expression, showResultOnly)
{
this._appendCommand(expression, this.prompt.text, false, showResultOnly);
},

_enterKeyPressed: function(event)
{
if (event.altKey || event.ctrlKey || event.shiftKey)
return;

event.consume(true);

this.prompt.clearAutoComplete(true);

var str = this.prompt.text;
if (!str.length)
return;
this._appendCommand(str, "", true, false);
},

_printResult: function(result, wasThrown, originatingCommand)
{
if (!result)
return;
var message = new WebInspector.ConsoleCommandResult(result, wasThrown, originatingCommand, this._linkifier);
this._messages.push(message);
this._appendConsoleMessage(message);
},

_appendCommand: function(text, newPromptText, useCommandLineAPI, showResultOnly)
{
if (!showResultOnly) {
var commandMessage = new WebInspector.ConsoleCommand(text);
WebInspector.console.interruptRepeatCount();
this._messages.push(commandMessage);
this._appendConsoleMessage(commandMessage);
}
this.prompt.text = newPromptText;

function printResult(result, wasThrown)
{
if (!result)
return;

if (!showResultOnly) {
this.prompt.pushHistoryItem(text);
WebInspector.settings.consoleHistory.set(this.prompt.historyData.slice(-30));
}

this._printResult(result, wasThrown, commandMessage);
}
WebInspector.runtimeModel.evaluate(text, "console", useCommandLineAPI, false, false, true, printResult.bind(this));

WebInspector.userMetrics.ConsoleEvaluated.record();
},

elementsToRestoreScrollPositionsFor: function()
{
return [this.messagesElement];
},

__proto__: WebInspector.View.prototype
}


WebInspector.ConsoleCommand = function(command)
{
this.command = command;
}

WebInspector.ConsoleCommand.prototype = {
wasShown: function()
{
},

willHide: function()
{
},

clearHighlight: function()
{
var highlightedMessage = this._formattedCommand;
delete this._formattedCommand;
this._formatCommand();
this._element.replaceChild(this._formattedCommand, highlightedMessage);
},

highlightSearchResults: function(regexObject)
{
regexObject.lastIndex = 0;
var text = this.command;
var match = regexObject.exec(text);
var offset = 0;
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}
WebInspector.highlightSearchResults(this._formattedCommand, matchRanges);
this._element.scrollIntoViewIfNeeded();
},

matchesRegex: function(regexObject)
{
return regexObject.test(this.command);
},

toMessageElement: function()
{
if (!this._element) {
this._element = document.createElement("div");
this._element.command = this;
this._element.className = "console-user-command";

this._formatCommand();
this._element.appendChild(this._formattedCommand);
}
return this._element;
},

_formatCommand: function()
{
this._formattedCommand = document.createElement("span");
this._formattedCommand.className = "console-message-text source-code";
this._formattedCommand.textContent = this.command;
},
}


WebInspector.ConsoleCommandResult = function(result, wasThrown, originatingCommand, linkifier)
{
var level = (wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
this.originatingCommand = originatingCommand;
WebInspector.ConsoleMessageImpl.call(this, WebInspector.ConsoleMessage.MessageSource.JS, level, "", linkifier, WebInspector.ConsoleMessage.MessageType.Result, undefined, undefined, undefined, [result]);
}

WebInspector.ConsoleCommandResult.prototype = {

useArrayPreviewInFormatter: function(array)
{
return false;
},

toMessageElement: function()
{
var element = WebInspector.ConsoleMessageImpl.prototype.toMessageElement.call(this);
element.addStyleClass("console-user-command-result");
return element;
},

__proto__: WebInspector.ConsoleMessageImpl.prototype
}


WebInspector.ConsoleGroup = function(parentGroup)
{
this.parentGroup = parentGroup;

var element = document.createElement("div");
element.className = "console-group";
element.group = this;
this.element = element;

if (parentGroup) {
var bracketElement = document.createElement("div");
bracketElement.className = "console-group-bracket";
element.appendChild(bracketElement);
}

var messagesElement = document.createElement("div");
messagesElement.className = "console-group-messages";
element.appendChild(messagesElement);
this.messagesElement = messagesElement;
}

WebInspector.ConsoleGroup.prototype = {

addMessage: function(message, node)
{
var element = message.toMessageElement();

if (message.type === WebInspector.ConsoleMessage.MessageType.StartGroup || message.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 && message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
groupElement.addStyleClass("collapsed");
} else {
this.messagesElement.insertBefore(element, node || null);
message.wasShown();
}

if (element.previousSibling && message.originatingCommand && element.previousSibling.command === message.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.consume(true);
}
}


WebInspector.consoleView = null;

WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
{
return new WebInspector.ConsoleMessageImpl(source, level, message, WebInspector.consoleView._linkifier, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated);
}






WebInspector.Panel = function(name)
{
WebInspector.View.call(this);
WebInspector.panels[name] = this;

this.element.addStyleClass("panel");
this.element.addStyleClass(name);
this._panelName = name;

this._shortcuts =   ({});

WebInspector.settings[this._sidebarWidthSettingName()] = WebInspector.settings.createSetting(this._sidebarWidthSettingName(), undefined);
}


WebInspector.Panel.counterRightMargin = 25;

WebInspector.Panel.prototype = {
get name()
{
return this._panelName;
},

show: function()
{
WebInspector.View.prototype.show.call(this, WebInspector.inspectorView.panelsElement());
},

wasShown: function()
{
var panelStatusBar = document.getElementById("panel-status-bar")
var drawerViewAnchor = document.getElementById("drawer-view-anchor");
var statusBarItems = this.statusBarItems;
if (statusBarItems) {
this._statusBarItemContainer = document.createElement("div");
for (var i = 0; i < statusBarItems.length; ++i)
this._statusBarItemContainer.appendChild(statusBarItems[i]);
panelStatusBar.insertBefore(this._statusBarItemContainer, drawerViewAnchor);
}
var statusBarText = this.statusBarText();
if (statusBarText) {
this._statusBarTextElement = statusBarText;
panelStatusBar.appendChild(statusBarText);
}

this.focus();
},

willHide: function()
{
if (this._statusBarItemContainer && this._statusBarItemContainer.parentNode)
this._statusBarItemContainer.parentNode.removeChild(this._statusBarItemContainer);
delete this._statusBarItemContainer;

if (this._statusBarTextElement && this._statusBarTextElement.parentNode)
this._statusBarTextElement.parentNode.removeChild(this._statusBarTextElement);
delete this._statusBarTextElement;
},

reset: function()
{
this.searchCanceled();
},

defaultFocusedElement: function()
{
return this.sidebarTreeElement || this.element;
},

searchCanceled: function()
{
WebInspector.searchController.updateSearchMatchesCount(0, this);
},


performSearch: function(query)
{

this.searchCanceled();
},

jumpToNextSearchResult: function()
{
},

jumpToPreviousSearchResult: function()
{
},


canSearchAndReplace: function()
{
return false;
},


replaceSelectionWith: function(text)
{
},


replaceAllWith: function(query, text)
{
},


canFilter: function()
{
return false;
},


performFilter: function(query)
{
},


createSidebarView: function(parentElement, position, defaultWidth, defaultHeight)
{
if (this.splitView)
return;

if (!parentElement)
parentElement = this.element;

this.splitView = new WebInspector.SidebarView(position, this._sidebarWidthSettingName(), defaultWidth, defaultHeight);
this.splitView.show(parentElement);
this.splitView.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this.sidebarResized.bind(this));

this.sidebarElement = this.splitView.sidebarElement;
},


createSidebarViewWithTree: function(parentElement, position, defaultWidth)
{
if (this.splitView)
return;

this.createSidebarView(parentElement, position);

this.sidebarTreeElement = document.createElement("ol");
this.sidebarTreeElement.className = "sidebar-tree";
this.splitView.sidebarElement.appendChild(this.sidebarTreeElement);
this.splitView.sidebarElement.addStyleClass("sidebar");

this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
this.sidebarTree.panel = this;
},

_sidebarWidthSettingName: function()
{
return this._panelName + "SidebarWidth";
},



get statusBarItems()
{
},


sidebarResized: function(event)
{
},

statusBarResized: function()
{
},


canShowAnchorLocation: function(anchor)
{
return false;
},


showAnchorLocation: function(anchor)
{
},

elementsToRestoreScrollPositionsFor: function()
{
return [];
},


handleShortcut: function(event)
{
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcutKey];
if (handler && handler(event))
event.handled = true;
},


registerShortcuts: function(keys, handler)
{
for (var i = 0; i < keys.length; ++i)
this._shortcuts[keys[i].key] = handler;
},

__proto__: WebInspector.View.prototype
}


WebInspector.PanelDescriptor = function(name, title, className, scriptName, panel)
{
this._name = name;
this._title = title;
this._className = className;
this._scriptName = scriptName;
this._panel = panel;
}

WebInspector.PanelDescriptor.prototype = {

name: function()
{
return this._name;
},


title: function()
{
return this._title;
},


iconURL: function()
{
return this._iconURL;
},


setIconURL: function(iconURL)
{
this._iconURL = iconURL;
},


panel: function()
{
if (this._panel)
return this._panel;
if (this._scriptName)
loadScript(this._scriptName);
this._panel = new WebInspector[this._className];
return this._panel;
},

registerShortcuts: function() {}
}






WebInspector.InspectorView = function()
{
WebInspector.View.call(this);
this.markAsRoot();
this.element.id = "main-panels";
this.element.setAttribute("spellcheck", false);
this._history = [];
this._historyIterator = -1;
document.addEventListener("keydown", this._keyDown.bind(this), false);
document.addEventListener("keypress", this._keyPress.bind(this), false);
this._panelOrder = [];
this._panelDescriptors = {};


this._openBracketIdentifiers = ["U+005B", "U+00DB"].keySet();
this._closeBracketIdentifiers = ["U+005D", "U+00DD"].keySet();
this._footerElementContainer = this.element.createChild("div", "inspector-footer status-bar hidden");
this._panelsElement = this.element.createChild("div", "fill");
}

WebInspector.InspectorView.Events = {
PanelSelected: "PanelSelected"
}

WebInspector.InspectorView.prototype = {

addPanel: function(panelDescriptor)
{
this._panelOrder.push(panelDescriptor.name());
this._panelDescriptors[panelDescriptor.name()] = panelDescriptor;
WebInspector.toolbar.addPanel(panelDescriptor);
},


panel: function(panelName)
{
var panelDescriptor = this._panelDescriptors[panelName];
if (!panelDescriptor && this._panelOrder.length)
panelDescriptor = this._panelDescriptors[this._panelOrder[0]];
return panelDescriptor ? panelDescriptor.panel() : null;
},


showPanel: function(panelName)
{
var panel = this.panel(panelName);
if (panel)
this.setCurrentPanel(panel);
return panel;
},


currentPanel: function()
{
return this._currentPanel;
},


setCurrentPanel: function(x)
{
if (this._currentPanel === x)
return;


WebInspector.searchController.cancelSearch();

if (this._currentPanel)
this._currentPanel.detach();

this._currentPanel = x;

if (x) {
x.show();
this.dispatchEventToListeners(WebInspector.InspectorView.Events.PanelSelected);
}
for (var panelName in WebInspector.panels) {
if (WebInspector.panels[panelName] === x) {
WebInspector.settings.lastActivePanel.set(panelName);
this._pushToHistory(panelName);
WebInspector.userMetrics.panelShown(panelName);
}
}
},


defaultFocusedElement: function()
{
return this._currentPanel ? this._currentPanel.defaultFocusedElement() : null;
},

_keyPress: function(event)
{


if (event.charCode < 32 && WebInspector.isWin())
return;
clearTimeout(this._keyDownTimer);
delete this._keyDownTimer;
},

_keyDown: function(event)
{
if (!WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event))
return;


var panelShortcutEnabled = WebInspector.settings.shortcutPanelSwitch.get();
if (panelShortcutEnabled && !event.shiftKey && !event.altKey && event.keyCode > 0x30 && event.keyCode < 0x3A) {
var panelName = this._panelOrder[event.keyCode - 0x31];
if (panelName) {
this.showPanel(panelName);
event.consume(true);
}
return;
}




if (!WebInspector.isWin() || (!this._openBracketIdentifiers[event.keyIdentifier] && !this._closeBracketIdentifiers[event.keyIdentifier])) {
this._keyDownInternal(event);
return;
}

this._keyDownTimer = setTimeout(this._keyDownInternal.bind(this, event), 0);
},

_keyDownInternal: function(event)
{
if (this._openBracketIdentifiers[event.keyIdentifier]) {
var isRotateLeft = !event.shiftKey && !event.altKey;
if (isRotateLeft) {
var index = this._panelOrder.indexOf(this.currentPanel().name);
index = (index === 0) ? this._panelOrder.length - 1 : index - 1;
this.showPanel(this._panelOrder[index]);
event.consume(true);
return;
}

var isGoBack = event.altKey;
if (isGoBack && this._canGoBackInHistory()) {
this._goBackInHistory();
event.consume(true);
}
return;
}

if (this._closeBracketIdentifiers[event.keyIdentifier]) {
var isRotateRight = !event.shiftKey && !event.altKey;
if (isRotateRight) {
var index = this._panelOrder.indexOf(this.currentPanel().name);
index = (index + 1) % this._panelOrder.length;
this.showPanel(this._panelOrder[index]);
event.consume(true);
return;
}

var isGoForward = event.altKey;
if (isGoForward && this._canGoForwardInHistory()) {
this._goForwardInHistory();
event.consume(true);
}
return;
}
},

_canGoBackInHistory: function()
{
return this._historyIterator > 0;
},

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

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

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

_pushToHistory: 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;
},

panelsElement: function()
{
return this._panelsElement;
},


setFooterElement: function(element)
{
if (element) {
this._footerElementContainer.removeStyleClass("hidden");
this._footerElementContainer.appendChild(element);
this._panelsElement.style.bottom = this._footerElementContainer.offsetHeight + "px";
} else {
this._footerElementContainer.addStyleClass("hidden");
this._footerElementContainer.removeChildren();
this._panelsElement.style.bottom = 0;
}
this.doResize();
},


showPanelForAnchorNavigation: function(panel)
{
WebInspector.searchController.disableSearchUntilExplicitAction();
this.setCurrentPanel(panel);
},

__proto__: WebInspector.View.prototype
}


WebInspector.inspectorView = null;






WebInspector.AdvancedSearchController = function()
{
this._shortcut = WebInspector.AdvancedSearchController.createShortcut();
this._searchId = 0;

WebInspector.settings.advancedSearchConfig = WebInspector.settings.createSetting("advancedSearchConfig", new WebInspector.SearchConfig("", true, false));

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
}


WebInspector.AdvancedSearchController.createShortcut = function()
{
if (WebInspector.isMac())
return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt);
else
return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift);
}

WebInspector.AdvancedSearchController.prototype = {

handleShortcut: function(event)
{
if (WebInspector.KeyboardShortcut.makeKeyFromEvent(event) === this._shortcut.key) {
if (!this._searchView || !this._searchView.isShowing() || this._searchView._search !== document.activeElement) {
WebInspector.showPanel("scripts");
this.show();
} else
this.close();
event.consume(true);
return true;
}
return false;
},

_frameNavigated: function()
{
this.resetSearch();
},


registerSearchScope: function(searchScope)
{

this._searchScope = searchScope;
},

show: function()
{
if (!this._searchView)
this._searchView = new WebInspector.SearchView(this);

this._searchView.syncToSelection();

if (this._searchView.isShowing())
this._searchView.focus();
else
WebInspector.showViewInDrawer(this._searchView._searchPanelElement, this._searchView, this.stopSearch.bind(this));
},

close: function()
{
this.stopSearch();
WebInspector.closeViewInDrawer();
},


_onSearchResult: function(searchId, searchResult)
{
if (searchId !== this._searchId)
return;

this._searchView.addSearchResult(searchResult);
if (!searchResult.searchMatches.length)
return;

if (!this._searchResultsPane) 
this._searchResultsPane = this._currentSearchScope.createSearchResultsPane(this._searchConfig);        
this._searchView.resultsPane = this._searchResultsPane; 
this._searchResultsPane.addSearchResult(searchResult);
},


_onSearchFinished: function(searchId, finished)
{
if (searchId !== this._searchId)
return;

if (!this._searchResultsPane)
this._searchView.nothingFound();

this._searchView.searchFinished(finished);
},


startSearch: function(searchConfig)
{
this.resetSearch();
++this._searchId;

this._searchConfig = searchConfig;

this._currentSearchScope = this._searchScope;

var totalSearchResultsCount = this._currentSearchScope.performSearch(searchConfig, this._onSearchResult.bind(this, this._searchId), this._onSearchFinished.bind(this, this._searchId));
this._searchView.searchStarted(totalSearchResultsCount);
},

resetSearch: function()
{
this.stopSearch();

if (this._searchResultsPane) {
this._searchView.resetResults();
delete this._searchResultsPane;
}
},

stopSearch: function()
{
if (this._currentSearchScope)
this._currentSearchScope.stopSearch();
}
}


WebInspector.SearchView = function(controller)
{
WebInspector.View.call(this);
this.registerRequiredCSS("textEditor.css");

this._controller = controller;

this.element.className = "search-view";

this._searchPanelElement = document.createElement("span");
this._searchPanelElement.className = "search-drawer-header";
this._searchPanelElement.addEventListener("keydown", this._onKeyDown.bind(this), false);

this._searchResultsElement = this.element.createChild("div");
this._searchResultsElement.className = "search-results";

this._searchLabel = this._searchPanelElement.createChild("span");
this._searchLabel.textContent = WebInspector.UIString("Search sources");
this._search = this._searchPanelElement.createChild("input");
this._search.setAttribute("type", "search");
this._search.addStyleClass("search-config-search");
this._search.setAttribute("results", "0");
this._search.setAttribute("size", 30);

this._ignoreCaseLabel = this._searchPanelElement.createChild("label");
this._ignoreCaseLabel.addStyleClass("search-config-label");
this._ignoreCaseCheckbox = this._ignoreCaseLabel.createChild("input");
this._ignoreCaseCheckbox.setAttribute("type", "checkbox");
this._ignoreCaseCheckbox.addStyleClass("search-config-checkbox");
this._ignoreCaseLabel.appendChild(document.createTextNode(WebInspector.UIString("Ignore case")));

this._regexLabel = this._searchPanelElement.createChild("label");
this._regexLabel.addStyleClass("search-config-label");
this._regexCheckbox = this._regexLabel.createChild("input");
this._regexCheckbox.setAttribute("type", "checkbox");
this._regexCheckbox.addStyleClass("search-config-checkbox");
this._regexLabel.appendChild(document.createTextNode(WebInspector.UIString("Regular expression")));

this._searchStatusBarElement = document.createElement("div");
this._searchStatusBarElement.className = "search-status-bar-item";
this._searchMessageElement = this._searchStatusBarElement.createChild("div");
this._searchMessageElement.className = "search-status-bar-message";

this._searchResultsMessageElement = document.createElement("span");
this._searchResultsMessageElement.className = "search-results-status-bar-message";

this._load();
}


WebInspector.SearchView.maxQueriesCount = 20;

WebInspector.SearchView.prototype = {

get statusBarItems()
{
return [this._searchStatusBarElement, this._searchResultsMessageElement];
},


get searchConfig()
{
return new WebInspector.SearchConfig(this._search.value, this._ignoreCaseCheckbox.checked, this._regexCheckbox.checked);
},

syncToSelection: function()
{
var selection = window.getSelection();
if (selection.rangeCount)
this._search.value = selection.toString().replace(/\r?\n.*/, "");
},


set resultsPane(resultsPane)
{
this.resetResults();
this._searchResultsElement.appendChild(resultsPane.element);
},


searchStarted: function(totalSearchResultsCount)
{
this.resetResults();
this._resetCounters();

this._searchMessageElement.textContent = WebInspector.UIString("Searching...");
this._progressIndicator = new WebInspector.ProgressIndicator();
this._progressIndicator.setTotalWork(totalSearchResultsCount);
this._progressIndicator.show(this._searchStatusBarElement);

this._updateSearchResultsMessage();

if (!this._searchingView)
this._searchingView = new WebInspector.EmptyView(WebInspector.UIString("Searching..."));
this._searchingView.show(this._searchResultsElement);
},

_updateSearchResultsMessage: function()
{
if (this._searchMatchesCount && this._searchResultsCount)
this._searchResultsMessageElement.textContent = WebInspector.UIString("Found %d matches in %d files.", this._searchMatchesCount, this._nonEmptySearchResultsCount);
else
this._searchResultsMessageElement.textContent = "";
},

resetResults: function()
{
if (this._searchingView)
this._searchingView.detach();
if (this._notFoundView)
this._notFoundView.detach();
this._searchResultsElement.removeChildren();
},

_resetCounters: function()
{
this._searchMatchesCount = 0;
this._searchResultsCount = 0;
this._nonEmptySearchResultsCount = 0;
},

nothingFound: function()
{
this.resetResults();

if (!this._notFoundView)
this._notFoundView = new WebInspector.EmptyView(WebInspector.UIString("No matches found."));
this._notFoundView.show(this._searchResultsElement);
this._searchResultsMessageElement.textContent = WebInspector.UIString("No matches found.");
},


addSearchResult: function(searchResult)
{
this._searchMatchesCount += searchResult.searchMatches.length;
this._searchResultsCount++;
if (searchResult.searchMatches.length)
this._nonEmptySearchResultsCount++;
this._updateSearchResultsMessage();
if (this._progressIndicator.isCanceled())
this._onCancel();
else
this._progressIndicator.setWorked(this._searchResultsCount);
},


searchFinished: function(finished)
{
this._progressIndicator.done();
this._searchMessageElement.textContent = finished ? WebInspector.UIString("Search finished.") : WebInspector.UIString("Search interrupted.");
},

focus: function()
{
WebInspector.setCurrentFocusElement(this._search);
this._search.select();
},

wasShown: function()
{
this.focus();
},

willHide: function()
{
this._controller.stopSearch();
},


_onKeyDown: function(event)
{
switch (event.keyCode) {
case WebInspector.KeyboardShortcut.Keys.Enter.code:
this._onAction();
break;
case WebInspector.KeyboardShortcut.Keys.Esc.code:
this._controller.close();
event.consume(true);
break;
}        
},

_save: function()
{
var searchConfig = new WebInspector.SearchConfig(this.searchConfig.query, this.searchConfig.ignoreCase, this.searchConfig.isRegex); 
WebInspector.settings.advancedSearchConfig.set(searchConfig);
},

_load: function()
{
var searchConfig = WebInspector.settings.advancedSearchConfig.get();
this._search.value = searchConfig.query;
this._ignoreCaseCheckbox.checked = searchConfig.ignoreCase;
this._regexCheckbox.checked = searchConfig.isRegex;
},

_onCancel: function()
{
this._controller.stopSearch();
this.focus();
},

_onAction: function()
{
if (!this.searchConfig.query || !this.searchConfig.query.length)
return;

this._save();
this._controller.startSearch(this.searchConfig);
},

__proto__: WebInspector.View.prototype
}



WebInspector.SearchConfig = function(query, ignoreCase, isRegex)
{
this.query = query;
this.ignoreCase = ignoreCase;
this.isRegex = isRegex;
}


WebInspector.SearchScope = function()
{
}

WebInspector.SearchScope.prototype = {

performSearch: function(searchConfig, searchResultCallback, searchFinishedCallback) { },

stopSearch: function() { },


createSearchResultsPane: function(searchConfig) { }
}


WebInspector.SearchResult = function(offset, length)
{
this.offset = offset;
this.length = length;    
}


WebInspector.SearchResultsPane = function(searchConfig)
{
this._searchConfig = searchConfig;
this.element = document.createElement("div");
}

WebInspector.SearchResultsPane.prototype = {

get searchConfig()
{
return this._searchConfig;
},


addSearchResult: function(searchResult) { }
}


WebInspector.FileBasedSearchResultsPane = function(searchConfig)
{
WebInspector.SearchResultsPane.call(this, searchConfig);

this._searchResults = [];

this.element.id ="search-results-pane-file-based";

this._treeOutlineElement = document.createElement("ol");
this._treeOutlineElement.className = "search-results-outline-disclosure";
this.element.appendChild(this._treeOutlineElement);
this._treeOutline = new TreeOutline(this._treeOutlineElement);

this._matchesExpandedCount = 0;
}

WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount = 20;
WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce = 20;

WebInspector.FileBasedSearchResultsPane.prototype = {

_createAnchor: function(uiSourceCode, lineNumber, columnNumber)
{
var anchor = document.createElement("a");
anchor.preferredPanel = "scripts";
anchor.href = sanitizeHref(uiSourceCode.originURL());
anchor.uiSourceCode = uiSourceCode;
anchor.lineNumber = lineNumber;
return anchor;
},


addSearchResult: function(searchResult)
{
this._searchResults.push(searchResult);
var uiSourceCode = searchResult.uiSourceCode;
var searchMatches = searchResult.searchMatches;

var fileTreeElement = this._addFileTreeElement(uiSourceCode.originURL(), searchMatches.length, this._searchResults.length - 1);
},


_fileTreeElementExpanded: function(searchResult, fileTreeElement)
{
if (fileTreeElement._initialized)
return;

var toIndex = Math.min(searchResult.searchMatches.length, WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce);
if (toIndex < searchResult.searchMatches.length) {
this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex - 1);
this._appendShowMoreMatchesElement(fileTreeElement, searchResult, toIndex - 1);
} else
this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex);

fileTreeElement._initialized = true;
},


_appendSearchMatches: function(fileTreeElement, searchResult, fromIndex, toIndex)
{
var uiSourceCode = searchResult.uiSourceCode;
var searchMatches = searchResult.searchMatches;

var regex = createSearchRegex(this._searchConfig.query, !this._searchConfig.ignoreCase, this._searchConfig.isRegex);
for (var i = fromIndex; i < toIndex; ++i) {
var lineNumber = searchMatches[i].lineNumber;
var lineContent = searchMatches[i].lineContent;
var matchRanges = this._regexMatchRanges(lineContent, regex);

var anchor = this._createAnchor(uiSourceCode, lineNumber, matchRanges[0].offset);

var numberString = numberToStringWithSpacesPadding(lineNumber + 1, 4);
var lineNumberSpan = document.createElement("span");
lineNumberSpan.addStyleClass("webkit-line-number");
lineNumberSpan.addStyleClass("search-match-line-number");
lineNumberSpan.textContent = numberString;
anchor.appendChild(lineNumberSpan);

var contentSpan = this._createContentSpan(lineContent, matchRanges);
anchor.appendChild(contentSpan);

var searchMatchElement = new TreeElement("", null, false);
fileTreeElement.appendChild(searchMatchElement);
searchMatchElement.listItemElement.className = "search-match source-code";
searchMatchElement.listItemElement.appendChild(anchor);
}
},


_appendShowMoreMatchesElement: function(fileTreeElement, searchResult, startMatchIndex)
{
var matchesLeftCount = searchResult.searchMatches.length - startMatchIndex;
var showMoreMatchesText = WebInspector.UIString("Show all matches (%d more).", matchesLeftCount);
var showMoreMatchesElement = new TreeElement(showMoreMatchesText, null, false);
fileTreeElement.appendChild(showMoreMatchesElement);
showMoreMatchesElement.listItemElement.addStyleClass("show-more-matches");
showMoreMatchesElement.onselect = this._showMoreMatchesElementSelected.bind(this, searchResult, startMatchIndex, showMoreMatchesElement);
},


_showMoreMatchesElementSelected: function(searchResult, startMatchIndex, showMoreMatchesElement)
{
var fileTreeElement = showMoreMatchesElement.parent;
fileTreeElement.removeChild(showMoreMatchesElement);
this._appendSearchMatches(fileTreeElement, searchResult, startMatchIndex, searchResult.searchMatches.length);
},


_addFileTreeElement: function(fileName, searchMatchesCount, searchResultIndex)
{
var fileTreeElement = new TreeElement("", null, true);
fileTreeElement.toggleOnClick = true;
fileTreeElement.selectable = false;

this._treeOutline.appendChild(fileTreeElement);
fileTreeElement.listItemElement.addStyleClass("search-result");

var fileNameSpan = document.createElement("span");
fileNameSpan.className = "search-result-file-name";
fileNameSpan.textContent = fileName;
fileTreeElement.listItemElement.appendChild(fileNameSpan);

var matchesCountSpan = document.createElement("span");
matchesCountSpan.className = "search-result-matches-count";
if (searchMatchesCount === 1)
matchesCountSpan.textContent = WebInspector.UIString("(%d match)", searchMatchesCount);
else
matchesCountSpan.textContent = WebInspector.UIString("(%d matches)", searchMatchesCount);

fileTreeElement.listItemElement.appendChild(matchesCountSpan);

var searchResult = this._searchResults[searchResultIndex];
fileTreeElement.onexpand = this._fileTreeElementExpanded.bind(this, searchResult, fileTreeElement);


if (this._matchesExpandedCount < WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount)
fileTreeElement.expand();
this._matchesExpandedCount += searchResult.searchMatches.length;

return fileTreeElement; 
},


_regexMatchRanges: function(lineContent, regex)
{
regex.lastIndex = 0;
var match;
var offset = 0;
var matchRanges = [];
while ((regex.lastIndex < lineContent.length) && (match = regex.exec(lineContent)))
matchRanges.push(new WebInspector.SearchResult(match.index, match[0].length));

return matchRanges;
},


_createContentSpan: function(lineContent, matchRanges)
{
var contentSpan = document.createElement("span");
contentSpan.className = "search-match-content";
contentSpan.textContent = lineContent;
WebInspector.highlightRangesWithStyleClass(contentSpan, matchRanges, "highlighted-match");
return contentSpan;
},

__proto__: WebInspector.SearchResultsPane.prototype
}


WebInspector.FileBasedSearchResultsPane.SearchResult = function(uiSourceCode, searchMatches) {
this.uiSourceCode = uiSourceCode;
this.searchMatches = searchMatches;
}


WebInspector.advancedSearchController = null;






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 = this.element.createChild("div", "resources-dividers");

this._gridHeaderElement = document.createElement("div"); 
this._eventDividersElement = this._gridHeaderElement.createChild("div", "resources-event-dividers");
this._dividersLabelBarElement = this._gridHeaderElement.createChild("div", "resources-dividers-label-bar");
this.element.appendChild(this._gridHeaderElement);

this._leftCurtainElement = this.element.createChild("div", "timeline-cpu-curtain-left");
this._rightCurtainElement = this.element.createChild("div", "timeline-cpu-curtain-right");
}

WebInspector.TimelineGrid.prototype = {
get itemsGraphsElement()
{
return this._itemsGraphsElement;
},

get dividersElement()
{
return this._dividersElement;
},

get dividersLabelBarElement()
{
return this._dividersLabelBarElement;
},

get gridHeaderElement()
{
return this._gridHeaderElement;
},

removeDividers: function()
{
this._dividersElement.removeChildren();
this._dividersLabelBarElement.removeChildren();
},

updateDividers: function(calculator)
{
var dividersElementClientWidth = this._dividersElement.clientWidth;
var dividerCount = Math.round(dividersElementClientWidth / 64);
var slice = calculator.boundarySpan() / dividerCount;

this._currentDividerSlice = slice;


var divider = this._dividersElement.firstChild;
var dividerLabelBar = this._dividersLabelBarElement.firstChild;

var firstDivider = calculator.paddingLeft > 0 ? 0 : 1;
var sliceRemainder = (calculator.minimumBoundary() - calculator.zeroTime()) % slice;
for (var i = firstDivider; 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);
}

var left;
if (!slice) {
left = dividersElementClientWidth / dividerCount * i;
dividerLabelBar._labelElement.textContent = "";
} else {
left = calculator.computePosition(calculator.minimumBoundary() + slice * i - sliceRemainder);
dividerLabelBar._labelElement.textContent = calculator.formatTime(slice * i - sliceRemainder);
}
var percentLeft = 100 * left / dividersElementClientWidth;
this._setDividerAndBarLeft(divider, dividerLabelBar, percentLeft);

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._gridHeaderElement.removeChild(this._eventDividersElement);
for (var i = 0; i < dividers.length; ++i) {
if (dividers[i])
this._eventDividersElement.appendChild(dividers[i]);
}
this._gridHeaderElement.appendChild(this._eventDividersElement);
},

removeEventDividers: function()
{
this._eventDividersElement.removeChildren();
},

hideEventDividers: function()
{
this._eventDividersElement.addStyleClass("hidden");
},

showEventDividers: function()
{
this._eventDividersElement.removeStyleClass("hidden");
},

hideCurtains: function()
{
this._leftCurtainElement.addStyleClass("hidden");
this._rightCurtainElement.addStyleClass("hidden");
},


showCurtains: function(gapOffset, gapWidth)
{
this._leftCurtainElement.style.width = gapOffset + "px";
this._leftCurtainElement.removeStyleClass("hidden");
this._rightCurtainElement.style.left = (gapOffset + gapWidth) + "px";
this._rightCurtainElement.removeStyleClass("hidden");
},

setScrollAndDividerTop: function(scrollTop, dividersTop)
{
this._dividersElement.style.top = scrollTop + "px";
this._leftCurtainElement.style.top = scrollTop + "px";
this._rightCurtainElement.style.top = scrollTop + "px";
}
}


WebInspector.TimelineGrid.Calculator = function() { }

WebInspector.TimelineGrid.Calculator.prototype = {

computePosition: function(time) { },


formatTime: function(time) { },


minimumBoundary: function() { },


zeroTime: function() { },


maximumBoundary: function() { },


boundarySpan: function() { }
}






WebInspector.OverviewGrid = function(prefix)
{
this.element = document.createElement("div");
this.element.className = "fill";
this.element.id = prefix + "-overview-container";

this._grid = new WebInspector.TimelineGrid();
this._grid.element.id = prefix + "-overview-grid";
this._grid.setScrollAndDividerTop(0, 0);

this.element.appendChild(this._grid.element);

this._window = new WebInspector.OverviewGrid.Window(this.element, this._grid.dividersLabelBarElement);
}

WebInspector.OverviewGrid.prototype = {

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


updateDividers: function(calculator)
{
this._grid.updateDividers(calculator);
},


addEventDividers: function(dividers)
{
this._grid.addEventDividers(dividers);
},

removeEventDividers: function()
{
this._grid.removeEventDividers();
},


setWindowPosition: function(start, end)
{
this._window._setWindowPosition(start, end);
},

reset: function()
{
this._window.reset();
},


windowLeft: function()
{
return this._window.windowLeft;
},


windowRight: function()
{
return this._window.windowRight;
},


setWindow: function(left, right)
{
this._window._setWindow(left, right);
},


addEventListener: function(eventType, listener, thisObject)
{
this._window.addEventListener(eventType, listener, thisObject);
},


zoom: function(zoomFactor, referencePoint)
{
this._window._zoom(zoomFactor, referencePoint);
}
}


WebInspector.OverviewGrid.MinSelectableSize = 12;

WebInspector.OverviewGrid.WindowScrollSpeedFactor = .3;

WebInspector.OverviewGrid.ResizerOffset = 3.5; 


WebInspector.OverviewGrid.Window = function(parentElement, dividersLabelBarElement)
{
this._parentElement = parentElement;
this._dividersLabelBarElement = dividersLabelBarElement;

WebInspector.installDragHandle(this._parentElement, this._startWindowSelectorDragging.bind(this), this._windowSelectorDragging.bind(this), this._endWindowSelectorDragging.bind(this), "ew-resize");
WebInspector.installDragHandle(this._dividersLabelBarElement, this._startWindowDragging.bind(this), this._windowDragging.bind(this), null, "move");

this.windowLeft = 0.0;
this.windowRight = 1.0;

this._parentElement.addEventListener("mousewheel", this._onMouseWheel.bind(this), true);
this._parentElement.addEventListener("dblclick", this._resizeWindowMaximum.bind(this), true);

this._overviewWindowElement = document.createElement("div");
this._overviewWindowElement.className = "overview-grid-window";
parentElement.appendChild(this._overviewWindowElement);

this._overviewWindowBordersElement = document.createElement("div");
this._overviewWindowBordersElement.className = "overview-grid-window-rulers";
parentElement.appendChild(this._overviewWindowBordersElement);

var overviewDividersBackground = document.createElement("div");
overviewDividersBackground.className = "overview-grid-dividers-background";
parentElement.appendChild(overviewDividersBackground);

this._leftResizeElement = document.createElement("div");
this._leftResizeElement.className = "overview-grid-window-resizer";
this._leftResizeElement.style.left = 0;
parentElement.appendChild(this._leftResizeElement);
WebInspector.installDragHandle(this._leftResizeElement, this._resizerElementStartDragging.bind(this), this._leftResizeElementDragging.bind(this), null, "ew-resize");

this._rightResizeElement = document.createElement("div");
this._rightResizeElement.className = "overview-grid-window-resizer overview-grid-window-resizer-right";
this._rightResizeElement.style.right = 0;
parentElement.appendChild(this._rightResizeElement);
WebInspector.installDragHandle(this._rightResizeElement, this._resizerElementStartDragging.bind(this), this._rightResizeElementDragging.bind(this), null, "ew-resize");
}

WebInspector.OverviewGrid.Events = {
WindowChanged: "WindowChanged"
}

WebInspector.OverviewGrid.Window.prototype = {
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%";
},


_resizerElementStartDragging: function(event)
{
this._resizerParentOffsetLeft = event.pageX - event.offsetX - event.target.offsetLeft;
event.preventDefault();
return true;
},


_leftResizeElementDragging: function(event)
{
this._resizeWindowLeft(event.pageX - this._resizerParentOffsetLeft);
event.preventDefault();
},


_rightResizeElementDragging: function(event)
{
this._resizeWindowRight(event.pageX - this._resizerParentOffsetLeft);
event.preventDefault();
},


_startWindowSelectorDragging: function(event)
{
this._offsetLeft = event.pageX - event.offsetX;
var position = event.pageX - this._offsetLeft;
this._overviewWindowSelector = new WebInspector.OverviewGrid.WindowSelector(this._parentElement, position);
return true;
},


_windowSelectorDragging: function(event)
{
this._overviewWindowSelector._updatePosition(event.pageX - this._offsetLeft);
event.preventDefault();
},


_endWindowSelectorDragging: function(event)
{
var window = this._overviewWindowSelector._close(event.pageX - this._offsetLeft);
delete this._overviewWindowSelector;
if (window.end === window.start) { 
var middle = window.end;
window.start = Math.max(0, middle - WebInspector.OverviewGrid.MinSelectableSize / 2);
window.end = Math.min(this._parentElement.clientWidth, middle + WebInspector.OverviewGrid.MinSelectableSize / 2);
} else if (window.end - window.start < WebInspector.OverviewGrid.MinSelectableSize) {
if (this._parentElement.clientWidth - window.end > WebInspector.OverviewGrid.MinSelectableSize)
window.end = window.start + WebInspector.OverviewGrid.MinSelectableSize;
else
window.start = window.end - WebInspector.OverviewGrid.MinSelectableSize;
}
this._setWindowPosition(window.start, window.end);
},


_startWindowDragging: function(event)
{
this._dragStartPoint = event.pageX;
this._dragStartLeft = this.windowLeft;
this._dragStartRight = this.windowRight;
return true;
},


_windowDragging: function(event)
{
event.preventDefault();
var delta = (event.pageX - this._dragStartPoint) / this._parentElement.clientWidth;
if (this._dragStartLeft + delta < 0)
delta = -this._dragStartLeft;

if (this._dragStartRight + delta > 1)
delta = 1 - this._dragStartRight;

this._setWindow(this._dragStartLeft + delta, this._dragStartRight + delta);
},


_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._parentElement.clientWidth - 10)
end = this._parentElement.clientWidth;
else if (end < this._leftResizeElement.offsetLeft + WebInspector.OverviewGrid.MinSelectableSize)
end = this._leftResizeElement.offsetLeft + WebInspector.OverviewGrid.MinSelectableSize;
this._setWindowPosition(null, end);
},

_resizeWindowMaximum: function()
{
this._setWindowPosition(0, this._parentElement.clientWidth);
},


_setWindow: function(windowLeft, windowRight)
{
var clientWidth = this._parentElement.clientWidth;
const rulerAdjustment = 1 / clientWidth;

this.windowLeft = windowLeft;
this._leftResizeElement.style.left = this.windowLeft * 100 + "%";
this.windowRight = windowRight;
this._rightResizeElement.style.left = this.windowRight * 100 + "%";

this._overviewWindowElement.style.left = this.windowLeft * 100 + "%";
this._overviewWindowBordersElement.style.left = (this.windowLeft - rulerAdjustment) * 100 + "%";
this._overviewWindowElement.style.width = (this.windowRight - this.windowLeft) * 100 + "%";
this._overviewWindowBordersElement.style.right = (1 - this.windowRight + 2 * rulerAdjustment) * 100 + "%";

this.dispatchEventToListeners(WebInspector.OverviewGrid.Events.WindowChanged);
},


_setWindowPosition: function(start, end)
{
var clientWidth = this._parentElement.clientWidth;
var windowLeft = typeof start === "number" ? start / clientWidth : this.windowLeft;
var windowRight = typeof end === "number" ? end / clientWidth : this.windowRight;
this._setWindow(windowLeft, windowRight);
},


_onMouseWheel: function(event)
{
if (typeof event.wheelDeltaY === "number" && event.wheelDeltaY) {
const zoomFactor = 1.1;
const mouseWheelZoomSpeed = 1 / 120;

var reference = event.offsetX / event.target.clientWidth;
this._zoom(Math.pow(zoomFactor, -event.wheelDeltaY * mouseWheelZoomSpeed), reference);
}
if (typeof event.wheelDeltaX === "number" && event.wheelDeltaX) {
var offset = Math.round(event.wheelDeltaX * WebInspector.OverviewGrid.WindowScrollSpeedFactor);
var windowLeft = this._leftResizeElement.offsetLeft + WebInspector.OverviewGrid.ResizerOffset;
var windowRight = this._rightResizeElement.offsetLeft + WebInspector.OverviewGrid.ResizerOffset;

if (windowLeft - offset < 0)
offset = windowLeft;

if (windowRight - offset > this._parentElement.clientWidth)
offset = windowRight - this._parentElement.clientWidth;

this._setWindowPosition(windowLeft - offset, windowRight - offset);

event.preventDefault();
}
},


_zoom: function(factor, reference)
{
var left = this.windowLeft;
var right = this.windowRight;
var windowSize = right - left;
var newWindowSize = factor * windowSize;
var minWindowSize = WebInspector.OverviewGrid.MinSelectableSize / this._parentElement.clientWidth;

newWindowSize = Number.constrain(newWindowSize, minWindowSize, 1);
factor = newWindowSize / windowSize;

left = reference + (left - reference) * factor;
left = Number.constrain(left, 0, 1 - newWindowSize);

right = reference + (right - reference) * factor;
right = Number.constrain(right, newWindowSize, 1);
this._setWindow(left, right);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.OverviewGrid.WindowSelector = function(parent, position)
{
this._startPosition = position;
this._width = parent.offsetWidth;
this._windowSelector = document.createElement("div");
this._windowSelector.className = "overview-grid-window-selector";
this._windowSelector.style.left = this._startPosition + "px";
this._windowSelector.style.right = this._width - this._startPosition + "px";
parent.appendChild(this._windowSelector);
}

WebInspector.OverviewGrid.WindowSelector.prototype = {
_createSelectorElement: function(parent, left, width, height)
{
var selectorElement = document.createElement("div");
selectorElement.className = "overview-grid-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.ContentProvider = function() { }

WebInspector.ContentProvider.prototype = {

contentURL: function() { },


contentType: function() { },


requestContent: function(callback) { },


searchInContent: function(query, caseSensitive, isRegex, callback) { }
}


WebInspector.ContentProvider.SearchMatch = function(lineNumber, lineContent) {
this.lineNumber = lineNumber;
this.lineContent = lineContent;
}


WebInspector.ContentProvider.performSearchInContent = function(content, query, caseSensitive, isRegex)
{
var regex = createSearchRegex(query, caseSensitive, isRegex);

var result = [];
var lineEndings = content.lineEndings();
for (var i = 0; i < lineEndings.length; ++i) {
var lineStart = i > 0 ? lineEndings[i - 1] + 1 : 0;
var lineEnd = lineEndings[i];
var lineContent = content.substring(lineStart, lineEnd);
if (lineContent.length > 0 && lineContent.charAt(lineContent.length - 1) === "\r")
lineContent = lineContent.substring(0, lineContent.length - 1)

regex.lastIndex = 0;
if (regex.exec(lineContent))
result.push(new WebInspector.ContentProvider.SearchMatch(i, lineContent));
}
return result;
}






WebInspector.Resource = function(request, url, documentURL, frameId, loaderId, type, mimeType, isHidden)
{
this._request = request;
this.url = url;
this._documentURL = documentURL;
this._frameId = frameId;
this._loaderId = loaderId;
this._type = type || WebInspector.resourceTypes.Other;
this._mimeType = mimeType;
this._isHidden = isHidden;

this._content;
this._contentEncoded;
this._pendingContentCallbacks = [];
if (this._request && !this._request.finished)
this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
}

WebInspector.Resource.Events = {
MessageAdded: "message-added",
MessagesCleared: "messages-cleared",
}

WebInspector.Resource.prototype = {

get request()
{
return this._request;
},


get url()
{
return this._url;
},

set url(x)
{
this._url = x;
this._parsedURL = new WebInspector.ParsedURL(x);
},

get parsedURL()
{
return this._parsedURL;
},


get documentURL()
{
return this._documentURL;
},


get frameId()
{
return this._frameId;
},


get loaderId()
{
return this._loaderId;
},


get displayName()
{
return this._parsedURL.displayName;
},


get type()
{
return this._request ? this._request.type : this._type;
},


get mimeType()
{
return this._request ? this._request.mimeType : this._mimeType;
},


get messages()
{
return this._messages || [];
},


addMessage: function(msg)
{
if (!msg.isErrorOrWarning() || !msg.message)
return;

if (!this._messages)
this._messages = [];
this._messages.push(msg);
this.dispatchEventToListeners(WebInspector.Resource.Events.MessageAdded, msg);
},


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

set errors(x)
{
this._errors = x;
},


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

set warnings(x)
{
this._warnings = x;
},

clearErrorsAndWarnings: function()
{
this._messages = [];
this._warnings = 0;
this._errors = 0;
this.dispatchEventToListeners(WebInspector.Resource.Events.MessagesCleared);
},


get content()
{
return this._content;
},


get contentEncoded()
{
return this._contentEncoded;
},


contentURL: function()
{
return this._url;
},


contentType: function()
{
return this.type;
},


requestContent: function(callback)
{
if (typeof this._content !== "undefined") {
callback(this._content, !!this._contentEncoded, this.canonicalMimeType());
return;
}

this._pendingContentCallbacks.push(callback);
if (!this._request || this._request.finished)
this._innerRequestContent();
},

canonicalMimeType: function()
{
return this.type.canonicalMimeType() || this.mimeType;
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{

function callbackWrapper(error, searchMatches)
{
callback(searchMatches || []);
}

if (this.frameId)
PageAgent.searchInResource(this.frameId, this.url, query, caseSensitive, isRegex, callbackWrapper);
else
callback([]);
},


populateImageSource: function(image)
{
function onResourceContent()
{
var imageSrc = WebInspector.contentAsDataURL(this._content, this.mimeType, this._contentEncoded);
if (imageSrc === null)
imageSrc = this.url;
image.src = imageSrc;
}

this.requestContent(onResourceContent.bind(this));
},

_requestFinished: function()
{
this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
if (this._pendingContentCallbacks.length)
this._innerRequestContent();
},


_innerRequestContent: function()
{
if (this._contentRequested)
return;
this._contentRequested = true;


function contentLoaded(content, contentEncoded)
{
this._content = content;
this._contentEncoded = contentEncoded;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._content, this._contentEncoded, this.canonicalMimeType());
this._pendingContentCallbacks.length = 0;
delete this._contentRequested;
}


function resourceContentLoaded(error, content, contentEncoded)
{
if (error)
console.error("Resource content request failed: " + error);
contentLoaded.call(this, error ? null : content, contentEncoded);
}

if (this.request) {

function requestContentLoaded(content, contentEncoded, mimeType)
{
contentLoaded.call(this, content, contentEncoded);
}

this.request.requestContent(requestContentLoaded.bind(this));
return;
}
PageAgent.getResourceContent(this.frameId, this.url, resourceContentLoaded.bind(this));
},


isHidden: function()
{
return !!this._isHidden;
},

__proto__: WebInspector.Object.prototype
}







WebInspector.NetworkRequest = function(requestId, url, documentURL, frameId, loaderId)
{
this._requestId = requestId;
this.url = url;
this._documentURL = documentURL;
this._frameId = frameId;
this._loaderId = loaderId;
this._startTime = -1;
this._endTime = -1;

this.statusCode = 0;
this.statusText = "";
this.requestMethod = "";
this.requestTime = 0;
this.receiveHeadersEnd = 0;

this._type = WebInspector.resourceTypes.Other;
this._contentEncoded = false;
this._pendingContentCallbacks = [];
this._frames = [];
}

WebInspector.NetworkRequest.Events = {
FinishedLoading: "FinishedLoading",
TimingChanged: "TimingChanged",
RequestHeadersChanged: "RequestHeadersChanged",
ResponseHeadersChanged: "ResponseHeadersChanged",
}


WebInspector.NetworkRequest.InitiatorType = {
Other: "other",
Parser: "parser",
Redirect: "redirect",
Script: "script"
}


WebInspector.NetworkRequest.NameValue;

WebInspector.NetworkRequest.prototype = {

get requestId()
{
return this._requestId;
},

set requestId(requestId)
{
this._requestId = requestId;
},


get url()
{
return this._url;
},

set url(x)
{
if (this._url === x)
return;

this._url = x;
this._parsedURL = new WebInspector.ParsedURL(x);
delete this._parsedQueryParameters;
delete this._name;
delete this._path;
},


get documentURL()
{
return this._documentURL;
},

get parsedURL()
{
return this._parsedURL;
},


get frameId()
{
return this._frameId;
},


get loaderId()
{
return this._loaderId;
},


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()
{
if (this.cached)
return 0;
if (this.statusCode === 304) 
return this.responseHeadersSize;
if (this._transferSize !== undefined)
return this._transferSize;










var bodySize = Number(this.responseHeaderValue("Content-Length") || this.resourceSize);
return this.responseHeadersSize + bodySize;
},


increaseTransferSize: function(x)
{
this._transferSize = (this._transferSize || 0) + x;
},


get finished()
{
return this._finished;
},

set finished(x)
{
if (this._finished === x)
return;

this._finished = x;

if (x) {
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.FinishedLoading, this);
if (this._pendingContentCallbacks.length)
this._innerRequestContent();
}
},


get failed()
{
return this._failed;
},

set failed(x)
{
this._failed = x;
},


get canceled()
{
return this._canceled;
},

set canceled(x)
{
this._canceled = 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(WebInspector.NetworkRequest.Events.TimingChanged, this);
}
},


get mimeType()
{
return this._mimeType;
},

set mimeType(x)
{
this._mimeType = x;
},


get displayName()
{
return this._parsedURL.displayName;
},

name: function()
{
if (this._name)
return this._name;
this._parseNameAndPathFromURL();
return this._name;
},

path: function()
{
if (this._path)
return this._path;
this._parseNameAndPathFromURL();
return this._path;
},

_parseNameAndPathFromURL: function()
{
if (this._parsedURL.isDataURL()) {
this._name = this._parsedURL.dataURLDisplayName();
this._path = "";
} else if (this._parsedURL.isAboutBlank()) {
this._name = this._parsedURL.url;
this._path = "";
} else {
this._path = this._parsedURL.host + this._parsedURL.folderPathComponents;
this._path = this._path.trimURL(WebInspector.inspectedPageDomain ? WebInspector.inspectedPageDomain : "");
if (this._parsedURL.lastPathComponent || this._parsedURL.queryParams)
this._name = this._parsedURL.lastPathComponent + (this._parsedURL.queryParams ? "?" + this._parsedURL.queryParams : "");
else if (this._parsedURL.folderPathComponents) {
this._name = this._parsedURL.folderPathComponents.substring(this._parsedURL.folderPathComponents.lastIndexOf("/") + 1) + "/";
this._path = this._path.substring(0, this._path.lastIndexOf("/"));
} else {
this._name = this._parsedURL.host;
this._path = "";
}
}
},


get folder()
{
var path = this._parsedURL.path;
var indexOfQuery = path.indexOf("?");
if (indexOfQuery !== -1)
path = path.substring(0, indexOfQuery);
var lastSlashIndex = path.lastIndexOf("/");
return lastSlashIndex !== -1 ? path.substring(0, lastSlashIndex) : "";
},


get type()
{
return this._type;
},

set type(x)
{
this._type = x;
},


get domain()
{
return this._parsedURL.host;
},


get redirectSource()
{
if (this.redirects && this.redirects.length > 0)
return this.redirects[this.redirects.length - 1];
return this._redirectSource;
},

set redirectSource(x)
{
this._redirectSource = x;
delete this._initiatorInfo;
},


get requestHeaders()
{
return this._requestHeaders || [];
},

set requestHeaders(x)
{
this._requestHeaders = x;
delete this._sortedRequestHeaders;
delete this._requestCookies;

this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
},


get requestHeadersText()
{
if (typeof this._requestHeadersText === "undefined") {
this._requestHeadersText = this.requestMethod + " " + this.url + " HTTP/1.1\r\n";
for (var i = 0; i < this.requestHeaders.length; ++i)
this._requestHeadersText += this.requestHeaders[i].name + ": " + this.requestHeaders[i].value + "\r\n";
}
return this._requestHeadersText;
},

set requestHeadersText(x)
{
this._requestHeadersText = x;

this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
},


get requestHeadersSize()
{
return this.requestHeadersText.length;
},


get sortedRequestHeaders()
{
if (this._sortedRequestHeaders !== undefined)
return this._sortedRequestHeaders;

this._sortedRequestHeaders = [];
this._sortedRequestHeaders = this.requestHeaders.slice();
this._sortedRequestHeaders.sort(function(a,b) { return a.name.toLowerCase().compareTo(b.name.toLowerCase()) });
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 requestHttpVersion()
{
var firstLine = this.requestHeadersText.split(/\r\n/)[0];
var match = firstLine.match(/(HTTP\/\d+\.\d+)$/);
return match ? match[1] : undefined;
},


get responseHeaders()
{
return this._responseHeaders || [];
},

set responseHeaders(x)
{
this._responseHeaders = x;
delete this._sortedResponseHeaders;
delete this._responseCookies;

this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
},


get responseHeadersText()
{
if (typeof this._responseHeadersText === "undefined") {
this._responseHeadersText = "HTTP/1.1 " + this.statusCode + " " + this.statusText + "\r\n";
for (var i = 0; i < this.responseHeaders.length; ++i)
this._responseHeadersText += this.responseHeaders[i].name + ": " + this.responseHeaders[i].value + "\r\n";
}
return this._responseHeadersText;
},

set responseHeadersText(x)
{
this._responseHeadersText = x;

this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
},


get responseHeadersSize()
{
return this.responseHeadersText.length;
},


get sortedResponseHeaders()
{
if (this._sortedResponseHeaders !== undefined)
return this._sortedResponseHeaders;

this._sortedResponseHeaders = [];
this._sortedResponseHeaders = this.responseHeaders.slice();
this._sortedResponseHeaders.sort(function(a, b) { return a.name.toLowerCase().compareTo(b.name.toLowerCase()); });
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;
},


queryString: function()
{
if (this._queryString)
return this._queryString;
var queryString = this.url.split("?", 2)[1];
if (!queryString)
return null;
this._queryString = queryString.split("#", 2)[0];
return this._queryString;
},


get queryParameters()
{
if (this._parsedQueryParameters)
return this._parsedQueryParameters;
var queryString = this.queryString();
if (!queryString)
return null;
this._parsedQueryParameters = this._parseParameters(queryString);
return this._parsedQueryParameters;
},


get formParameters()
{
if (this._parsedFormParameters)
return this._parsedFormParameters;
if (!this.requestFormData)
return null;
var requestContentType = this.requestContentType();
if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
return null;
this._parsedFormParameters = this._parseParameters(this.requestFormData);
return this._parsedFormParameters;
},


get responseHttpVersion()
{
var match = this.responseHeadersText.match(/^(HTTP\/\d+\.\d+)/);
return match ? match[1] : undefined;
},


_parseParameters: function(queryString)
{
function parseNameValue(pair)
{
var splitPair = pair.split("=", 2);
return {name: splitPair[0], value: splitPair[1] || ""};
}
return queryString.split("&").map(parseNameValue);
},


_headerValue: function(headers, headerName)
{
headerName = headerName.toLowerCase();

var values = [];
for (var i = 0; i < headers.length; ++i) {
if (headers[i].name.toLowerCase() === headerName)
values.push(headers[i].value);
}
if (!values.length)
return undefined;

if (headerName === "set-cookie")
return values.join("\n");
return values.join(", ");
},


get content()
{
return this._content;
},


get contentEncoded()
{
return this._contentEncoded;
},


contentURL: function()
{
return this._url;
},


contentType: function()
{
return this._type;
},


requestContent: function(callback)
{



if (this.type === WebInspector.resourceTypes.WebSocket) {
callback(null, false, this._mimeType);
return;
}
if (typeof this._content !== "undefined") {
callback(this.content || null, this._contentEncoded, this.type.canonicalMimeType() || this._mimeType);
return;
}
this._pendingContentCallbacks.push(callback);
if (this.finished)
this._innerRequestContent();
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
callback([]);
},


isHttpFamily: function()
{
return !!this.url.match(/^https?:/i);
},


requestContentType: function()
{
return this.requestHeaderValue("Content-Type");
},


isPingRequest: function()
{
return "text/ping" === this.requestContentType();
},


hasErrorStatusCode: function()
{
return this.statusCode >= 400;
},


populateImageSource: function(image)
{

function onResourceContent(content, contentEncoded, mimeType)
{
var imageSrc = this.asDataURL();
if (imageSrc === null)
imageSrc = this.url;
image.src = imageSrc;
}

this.requestContent(onResourceContent.bind(this));
},


asDataURL: function()
{
return WebInspector.contentAsDataURL(this._content, this.mimeType, this._contentEncoded);
},

_innerRequestContent: function()
{
if (this._contentRequested)
return;
this._contentRequested = true;


function onResourceContent(error, content, contentEncoded)
{
this._content = error ? null : content;
this._contentEncoded = contentEncoded;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._content, this._contentEncoded, this._mimeType);
this._pendingContentCallbacks.length = 0;
delete this._contentRequested;
}
NetworkAgent.getResponseBody(this._requestId, onResourceContent.bind(this));
},


initiatorInfo: function()
{
if (this._initiatorInfo)
return this._initiatorInfo;

var type = WebInspector.NetworkRequest.InitiatorType.Other;
var url = "";
var lineNumber = -Infinity;
var columnNumber = -Infinity;

if (this.redirectSource) {
type = WebInspector.NetworkRequest.InitiatorType.Redirect;
url = this.redirectSource.url;
} else if (this.initiator) {
if (this.initiator.type === NetworkAgent.InitiatorType.Parser) {
type = WebInspector.NetworkRequest.InitiatorType.Parser;
url = this.initiator.url;
lineNumber = this.initiator.lineNumber;
} else if (this.initiator.type === NetworkAgent.InitiatorType.Script) {
var topFrame = this.initiator.stackTrace[0];
if (topFrame.url) {
type = WebInspector.NetworkRequest.InitiatorType.Script;
url = topFrame.url;
lineNumber = topFrame.lineNumber;
columnNumber = topFrame.columnNumber;
}
}
}

this._initiatorInfo = {type: type, url: url, source: WebInspector.displayNameForURL(url), lineNumber: lineNumber, columnNumber: columnNumber};
return this._initiatorInfo;
},


frames: function()
{
return this._frames;
},


frame: function(position)
{
return this._frames[position];
},


addFrameError: function(errorMessage, time)
{
this._pushFrame({errorMessage: errorMessage, time: time});
},


addFrame: function(response, time, sent)
{
response.time = time;
if (sent)
response.sent = sent;
this._pushFrame(response);
},


_pushFrame: function(frameOrError)
{
if (this._frames.length >= 100)
this._frames.splice(0, 10);
this._frames.push(frameOrError);
},

__proto__: WebInspector.Object.prototype
}







WebInspector.UISourceCode = function(project, path, originURL, url, contentType, isEditable)
{
this._project = project;
this._path = path;
this._originURL = originURL;
this._url = url;
this._contentType = contentType;
this._isEditable = isEditable;

this._requestContentCallbacks = [];
this._liveLocations = new Set();

this._consoleMessages = [];


this.history = [];
if (this.isEditable() && this._url)
this._restoreRevisionHistory();
this._formatterMapping = new WebInspector.IdentityFormatterSourceMapping();
}

WebInspector.UISourceCode.Events = {
FormattedChanged: "FormattedChanged",
WorkingCopyChanged: "WorkingCopyChanged",
WorkingCopyCommitted: "WorkingCopyCommitted",
TitleChanged: "TitleChanged",
ConsoleMessageAdded: "ConsoleMessageAdded",
ConsoleMessageRemoved: "ConsoleMessageRemoved",
ConsoleMessagesCleared: "ConsoleMessagesCleared",
SourceMappingChanged: "SourceMappingChanged",
}

WebInspector.UISourceCode.prototype = {

get url()
{
return this._url;
},


path: function()
{
return this._path;
},


name: function()
{
return this._path[this._path.length - 1];
},


displayName: function()
{
var displayName = this.name() || (this._project.displayName() + "/" + this._path.join("/"));
return displayName.trimEnd(100);
},


uri: function()
{
if (!this._project.id())
return this._path.join("/");
if (!this._path.length)
return this._project.id();
return this._project.id() + "/" + this._path.join("/");
},


originURL: function()
{
return this._originURL;
},


rename: function(newName)
{
if (!this._path.length)
return;
this._path[this._path.length - 1] = newName;
this._url = newName;
this._originURL = newName;
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.TitleChanged, null);
},


contentURL: function()
{
return this.originURL();
},


contentType: function()
{
return this._contentType;
},


scriptFile: function()
{
return this._scriptFile;
},


setScriptFile: function(scriptFile)
{
this._scriptFile = scriptFile;
},


styleFile: function()
{
return this._styleFile;
},


setStyleFile: function(styleFile)
{
this._styleFile = styleFile;
},


project: function()
{
return this._project;
},


requestContent: function(callback)
{
if (this._content || this._contentLoaded) {
callback(this._content, false, this._mimeType);
return;
}
this._requestContentCallbacks.push(callback);
if (this._requestContentCallbacks.length === 1)
this._project.requestFileContent(this, this._fireContentAvailable.bind(this));
},

checkContentUpdated: function()
{
if (!this._project.canSetFileContent())
return;
if (this._checkingContent)
return;
this._checkingContent = true;
this._project.requestFileContent(this, contentLoaded.bind(this));

function contentLoaded(updatedContent)
{
if (updatedContent === null) {
var workingCopy = this.workingCopy();
this._commitContent("", false);
this.setWorkingCopy(workingCopy);
delete this._checkingContent;
return;
}
if (typeof this._lastAcceptedContent === "string" && this._lastAcceptedContent === updatedContent) {
delete this._checkingContent;
return;
}
if (this._content === updatedContent) {
delete this._lastAcceptedContent;
delete this._checkingContent;
return;
}

if (!this.isDirty()) {
this._commitContent(updatedContent, false);
delete this._checkingContent;
return;
}

var shouldUpdate = window.confirm(WebInspector.UIString("This file was changed externally. Would you like to reload it?"));
if (shouldUpdate)
this._commitContent(updatedContent, false);
else
this._lastAcceptedContent = updatedContent;
delete this._checkingContent;
}
},


requestOriginalContent: function(callback)
{
this._project.requestFileContent(this, callback);
},


_commitContent: function(content, shouldSetContentInProject)
{
delete this._lastAcceptedContent;
this._content = content;
this._contentLoaded = true;

var lastRevision = this.history.length ? this.history[this.history.length - 1] : null;
if (!lastRevision || lastRevision._content !== this._content) {
var revision = new WebInspector.Revision(this, this._content, new Date());
this.history.push(revision);
revision._persist();
}

this._innerResetWorkingCopy();
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyCommitted);
if (this._url && WebInspector.fileManager.isURLSaved(this._url)) {
WebInspector.fileManager.save(this._url, this._content, false);
WebInspector.fileManager.close(this._url);
}
if (shouldSetContentInProject)
this._project.setFileContent(this, this._content, function() { });
},


addRevision: function(content)
{
this._commitContent(content, true);
},

_restoreRevisionHistory: function()
{
if (!window.localStorage)
return;

var registry = WebInspector.Revision._revisionHistoryRegistry();
var historyItems = registry[this.url];
if (!historyItems)
return;

function filterOutStale(historyItem)
{
return historyItem.loaderId === WebInspector.resourceTreeModel.mainFrame.loaderId;
}

historyItems = historyItems.filter(filterOutStale);
if (!historyItems.length)
return;

for (var i = 0; i < historyItems.length; ++i) {
var content = window.localStorage[historyItems[i].key];
var timestamp = new Date(historyItems[i].timestamp);
var revision = new WebInspector.Revision(this, content, timestamp);
this.history.push(revision);
}
this._content = this.history[this.history.length - 1].content;
this._contentLoaded = true;
this._mimeType = this.canonicalMimeType();
},

_clearRevisionHistory: function()
{
if (!window.localStorage)
return;

var registry = WebInspector.Revision._revisionHistoryRegistry();
var historyItems = registry[this.url];
for (var i = 0; historyItems && i < historyItems.length; ++i)
delete window.localStorage[historyItems[i].key];
delete registry[this.url];
window.localStorage["revision-history"] = JSON.stringify(registry);
},

revertToOriginal: function()
{

function callback(content, contentEncoded, mimeType)
{
if (typeof content !== "string")
return;

this.addRevision(content);
}

this.requestOriginalContent(callback.bind(this));

WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
action: WebInspector.UserMetrics.UserActionNames.ApplyOriginalContent,
url: this.url
});
},


revertAndClearHistory: function(callback)
{

function revert(content, contentEncoded, mimeType)
{
if (typeof content !== "string")
return;

this.addRevision(content);
this._clearRevisionHistory();
this.history = [];
callback(this);
}

this.requestOriginalContent(revert.bind(this));

WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
action: WebInspector.UserMetrics.UserActionNames.RevertRevision,
url: this.url
});
},


isEditable: function()
{
return this._isEditable;
},


workingCopy: function()
{
if (this._workingCopyGetter) {
this._workingCopy = this._workingCopyGetter();
delete this._workingCopyGetter;
}
if (this.isDirty())
return this._workingCopy;
return this._content;
},

resetWorkingCopy: function()
{
this._innerResetWorkingCopy();
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged);
},

_innerResetWorkingCopy: function()
{
delete this._workingCopy;
delete this._workingCopyGetter;
},


setWorkingCopy: function(newWorkingCopy)
{
this._mimeType = this.canonicalMimeType();
this._workingCopy = newWorkingCopy;
delete this._workingCopyGetter;
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged);
},

setWorkingCopyGetter: function(workingCopyGetter)
{
this._workingCopyGetter = workingCopyGetter;
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged);
},

removeWorkingCopyGetter: function()
{
if (!this._workingCopyGetter)
return;
this._workingCopy = this._workingCopyGetter();
delete this._workingCopyGetter;
},


commitWorkingCopy: function(callback)
{
if (!this.isDirty()) {
callback(null);
return;
}

this._commitContent(this.workingCopy(), true);
callback(null);

WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
action: WebInspector.UserMetrics.UserActionNames.FileSaved,
url: this.url
});
},


isDirty: function()
{
return typeof this._workingCopy !== "undefined" || typeof this._workingCopyGetter !== "undefined";
},


mimeType: function()
{
return this._mimeType;
},


canonicalMimeType: function()
{
return this.contentType().canonicalMimeType() || this._mimeType;
},


content: function()
{
return this._content;
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
var content = this.content();
if (content) {
var provider = new WebInspector.StaticContentProvider(this.contentType(), content);
provider.searchInContent(query, caseSensitive, isRegex, callback);
return;
}

this._project.searchInFileContent(this, query, caseSensitive, isRegex, callback);
},


_fireContentAvailable: function(content, contentEncoded, mimeType)
{
this._contentLoaded = true;
this._mimeType = mimeType;
this._content = content;

var callbacks = this._requestContentCallbacks.slice();
this._requestContentCallbacks = [];
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](content, contentEncoded, mimeType);

if (this._formatOnLoad) {
delete this._formatOnLoad;
this.setFormatted(true);
}
},


contentLoaded: function()
{
return this._contentLoaded;
},


uiLocationToRawLocation: function(lineNumber, columnNumber)
{
if (!this._sourceMapping)
return null;
var location = this._formatterMapping.formattedToOriginal(lineNumber, columnNumber);
return this._sourceMapping.uiLocationToRawLocation(this, location[0], location[1]);
},


addLiveLocation: function(liveLocation)
{
this._liveLocations.add(liveLocation);
},


removeLiveLocation: function(liveLocation)
{
this._liveLocations.remove(liveLocation);
},

updateLiveLocations: function()
{
var items = this._liveLocations.items();
for (var i = 0; i < items.length; ++i)
items[i].update();
},


overrideLocation: function(uiLocation)
{
var location = this._formatterMapping.originalToFormatted(uiLocation.lineNumber, uiLocation.columnNumber);
uiLocation.lineNumber = location[0];
uiLocation.columnNumber = location[1];
return uiLocation;
},


consoleMessages: function()
{
return this._consoleMessages;
},


consoleMessageAdded: function(message)
{
this._consoleMessages.push(message);
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessageAdded, message);
},


consoleMessageRemoved: function(message)
{
this._consoleMessages.remove(message);
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessageRemoved, message);
},

consoleMessagesCleared: function()
{
this._consoleMessages = [];
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessagesCleared);
},


formatted: function()
{
return !!this._formatted;
},


setFormatted: function(formatted)
{
if (!this.contentLoaded()) {
this._formatOnLoad = formatted;
return;
}

if (this._formatted === formatted)
return;

this._formatted = formatted;


this._contentLoaded = false;
this._content = false;
WebInspector.UISourceCode.prototype.requestContent.call(this, didGetContent.bind(this));


function didGetContent(content, contentEncoded, mimeType)
{
var formatter;
if (!formatted)
formatter = new WebInspector.IdentityFormatter();
else
formatter = WebInspector.Formatter.createFormatter(this.contentType());
formatter.formatContent(mimeType, content || "", formattedChanged.bind(this));


function formattedChanged(content, formatterMapping)
{
this._content = content;
this._innerResetWorkingCopy();
this._formatterMapping = formatterMapping;
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.FormattedChanged, {content: content});
this.updateLiveLocations();
}
}
},


createFormatter: function()
{

return null;
},


setSourceMapping: function(sourceMapping)
{
var wasIdentity = this._sourceMapping ? this._sourceMapping.isIdentity() : true;
this._sourceMapping = sourceMapping;
var data = {}
data.isIdentity = sourceMapping ? sourceMapping.isIdentity() : true;
data.identityHasChanged = data.isIdentity !== wasIdentity;
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.SourceMappingChanged, data);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.UISourceCodeProvider = function()
{
}

WebInspector.UISourceCodeProvider.Events = {
UISourceCodeAdded: "UISourceCodeAdded",
UISourceCodeRemoved: "UISourceCodeRemoved"
}

WebInspector.UISourceCodeProvider.prototype = {

uiSourceCodes: function() {},
}


WebInspector.UILocation = function(uiSourceCode, lineNumber, columnNumber)
{
this.uiSourceCode = uiSourceCode;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
}

WebInspector.UILocation.prototype = {

uiLocationToRawLocation: function()
{
return this.uiSourceCode.uiLocationToRawLocation(this.lineNumber, this.columnNumber);
},


url: function()
{
return this.uiSourceCode.contentURL();
},


linkText: function()
{
var linkText = this.uiSourceCode.name() || (this.uiSourceCode.project().displayName() + "/" + this.uiSourceCode.path().join("/"));
if (typeof this.lineNumber === "number")
linkText += ":" + (this.lineNumber + 1);
return linkText;
}
}


WebInspector.RawLocation = function()
{
}


WebInspector.LiveLocation = function(rawLocation, updateDelegate)
{
this._rawLocation = rawLocation;
this._updateDelegate = updateDelegate;
this._uiSourceCodes = [];
}

WebInspector.LiveLocation.prototype = {
update: function()
{
var uiLocation = this.uiLocation();
if (uiLocation) {
var uiSourceCode = uiLocation.uiSourceCode;
if (this._uiSourceCodes.indexOf(uiSourceCode) === -1) {
uiSourceCode.addLiveLocation(this);
this._uiSourceCodes.push(uiSourceCode);
}
var oneTime = this._updateDelegate(uiLocation);
if (oneTime)
this.dispose();
}
},


rawLocation: function()
{
return this._rawLocation;
},


uiLocation: function()
{

},

dispose: function()
{
for (var i = 0; i < this._uiSourceCodes.length; ++i)
this._uiSourceCodes[i].removeLiveLocation(this);
this._uiSourceCodes = [];
}
}


WebInspector.Revision = function(uiSourceCode, content, timestamp)
{
this._uiSourceCode = uiSourceCode;
this._content = content;
this._timestamp = timestamp;
}

WebInspector.Revision._revisionHistoryRegistry = function()
{
if (!WebInspector.Revision._revisionHistoryRegistryObject) {
if (window.localStorage) {
var revisionHistory = window.localStorage["revision-history"];
try {
WebInspector.Revision._revisionHistoryRegistryObject = revisionHistory ? JSON.parse(revisionHistory) : {};
} catch (e) {
WebInspector.Revision._revisionHistoryRegistryObject = {};
}
} else
WebInspector.Revision._revisionHistoryRegistryObject = {};
}
return WebInspector.Revision._revisionHistoryRegistryObject;
}

WebInspector.Revision.filterOutStaleRevisions = function()
{
if (!window.localStorage)
return;

var registry = WebInspector.Revision._revisionHistoryRegistry();
var filteredRegistry = {};
for (var url in registry) {
var historyItems = registry[url];
var filteredHistoryItems = [];
for (var i = 0; historyItems && i < historyItems.length; ++i) {
var historyItem = historyItems[i];
if (historyItem.loaderId === WebInspector.resourceTreeModel.mainFrame.loaderId) {
filteredHistoryItems.push(historyItem);
filteredRegistry[url] = filteredHistoryItems;
} else
delete window.localStorage[historyItem.key];
}
}
WebInspector.Revision._revisionHistoryRegistryObject = filteredRegistry;

function persist()
{
window.localStorage["revision-history"] = JSON.stringify(filteredRegistry);
}


setTimeout(persist, 0);
}

WebInspector.Revision.prototype = {

get uiSourceCode()
{
return this._uiSourceCode;
},


get timestamp()
{
return this._timestamp;
},


get content()
{
return this._content || null;
},

revertToThis: function()
{
function revert(content)
{
if (this._uiSourceCode._content !== content)
this._uiSourceCode.addRevision(content);
}
this.requestContent(revert.bind(this));
},


contentURL: function()
{
return this._uiSourceCode.originURL();
},


contentType: function()
{
return this._uiSourceCode.contentType();
},


requestContent: function(callback)
{
callback(this._content || "", false, this.uiSourceCode.canonicalMimeType());
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
callback([]);
},

_persist: function()
{
if (!window.localStorage)
return;

var url = this.contentURL();
if (!url || url.startsWith("inspector://"))
return;

var loaderId = WebInspector.resourceTreeModel.mainFrame.loaderId;
var timestamp = this.timestamp.getTime();
var key = "revision-history|" + url + "|" + loaderId + "|" + timestamp;

var registry = WebInspector.Revision._revisionHistoryRegistry();

var historyItems = registry[url];
if (!historyItems) {
historyItems = [];
registry[url] = historyItems;
}
historyItems.push({url: url, loaderId: loaderId, timestamp: timestamp, key: key});

function persist()
{
window.localStorage[key] = this._content;
window.localStorage["revision-history"] = JSON.stringify(registry);
}


setTimeout(persist.bind(this), 0);
}
}






WebInspector.CSSStyleModel = function(workspace)
{
this._workspace = workspace;
this._pendingCommandsMajorState = [];

this._locations = [];
this._sourceMappings = {};
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoRequested, this._undoRedoRequested, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoCompleted, this._undoRedoCompleted, this);
this._resourceBinding = new WebInspector.CSSStyleModelResourceBinding();
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameCreatedOrNavigated, this._mainFrameCreatedOrNavigated, this);
this._namedFlowCollections = {};
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._resetNamedFlowCollections, this);
InspectorBackend.registerCSSDispatcher(new WebInspector.CSSDispatcher(this));
CSSAgent.enable();
}


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.parseRuleMatchArrayPayload = function(matchArray)
{
var result = [];
for (var i = 0; i < matchArray.length; ++i)
result.push(WebInspector.CSSRule.parsePayload(matchArray[i].rule, matchArray[i].matchingSelectors));
return result;
}

WebInspector.CSSStyleModel.Events = {
StyleSheetAdded: "StyleSheetAdded",
StyleSheetChanged: "StyleSheetChanged",
StyleSheetRemoved: "StyleSheetRemoved",
MediaQueryResultChanged: "MediaQueryResultChanged",
NamedFlowCreated: "NamedFlowCreated",
NamedFlowRemoved: "NamedFlowRemoved",
RegionLayoutUpdated: "RegionLayoutUpdated"
}

WebInspector.CSSStyleModel.MediaTypes = ["all", "braille", "embossed", "handheld", "print", "projection", "screen", "speech", "tty", "tv"];

WebInspector.CSSStyleModel.prototype = {

getMatchedStylesAsync: function(nodeId, needPseudo, needInherited, userCallback)
{

function callback(userCallback, error, matchedPayload, pseudoPayload, inheritedPayload)
{
if (error) {
if (userCallback)
userCallback(null);
return;
}

var result = {};
if (matchedPayload)
result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(matchedPayload);

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

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

if (userCallback)
userCallback(result);
}

CSSAgent.getMatchedStylesForNode(nodeId, needPseudo, needInherited, callback.bind(null, userCallback));
},


getComputedStyleAsync: function(nodeId, userCallback)
{

function callback(userCallback, error, computedPayload)
{
if (error || !computedPayload)
userCallback(null);
else
userCallback(WebInspector.CSSStyleDeclaration.parseComputedStylePayload(computedPayload));
}

CSSAgent.getComputedStyleForNode(nodeId, callback.bind(null, userCallback));
},


getInlineStylesAsync: function(nodeId, userCallback)
{

function callback(userCallback, error, inlinePayload, attributesStylePayload)
{
if (error || !inlinePayload)
userCallback(null, null);
else
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(inlinePayload), attributesStylePayload ? WebInspector.CSSStyleDeclaration.parsePayload(attributesStylePayload) : null);
}

CSSAgent.getInlineStylesForNode(nodeId, callback.bind(null, userCallback));
},


forcePseudoState: function(nodeId, forcedPseudoClasses, userCallback)
{
CSSAgent.forcePseudoState(nodeId, forcedPseudoClasses || [], userCallback);
},


getNamedFlowCollectionAsync: function(documentNodeId, userCallback)
{
var namedFlowCollection = this._namedFlowCollections[documentNodeId];
if (namedFlowCollection) {
userCallback(namedFlowCollection);
return;
}


function callback(userCallback, error, namedFlowPayload)
{
if (error || !namedFlowPayload)
userCallback(null);
else {
var namedFlowCollection = new WebInspector.NamedFlowCollection(namedFlowPayload);
this._namedFlowCollections[documentNodeId] = namedFlowCollection;
userCallback(namedFlowCollection);
}
}

CSSAgent.getNamedFlowCollection(documentNodeId, callback.bind(this, userCallback));
},


getFlowByNameAsync: function(documentNodeId, flowName, userCallback)
{
var namedFlowCollection = this._namedFlowCollections[documentNodeId];
if (namedFlowCollection) {
userCallback(namedFlowCollection.flowByName(flowName));
return;
}


function callback(userCallback, namedFlowCollection)
{
if (!namedFlowCollection)
userCallback(null);
else
userCallback(namedFlowCollection.flowByName(flowName));
}

this.getNamedFlowCollectionAsync(documentNodeId, callback.bind(this, userCallback));
},


setRuleSelector: function(ruleId, nodeId, newSelector, successCallback, failureCallback)
{

function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
{
if (!selectedNodeIds)
return;
var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
var rule = WebInspector.CSSRule.parsePayload(rulePayload);
successCallback(rule, doesAffectSelectedNode);
}


function callback(nodeId, successCallback, failureCallback, newSelector, error, rulePayload)
{
this._pendingCommandsMajorState.pop();
if (error)
failureCallback();
else {
WebInspector.domAgent.markUndoableState();
var ownerDocumentId = this._ownerDocumentId(nodeId);
if (ownerDocumentId)
WebInspector.domAgent.querySelectorAll(ownerDocumentId, newSelector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
else
failureCallback();
}
}

this._pendingCommandsMajorState.push(true);
CSSAgent.setRuleSelector(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback, newSelector));
},


addRule: function(nodeId, selector, successCallback, failureCallback)
{

function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
{
if (!selectedNodeIds)
return;

var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
var rule = WebInspector.CSSRule.parsePayload(rulePayload);
successCallback(rule, doesAffectSelectedNode);
}


function callback(successCallback, failureCallback, selector, error, rulePayload)
{
this._pendingCommandsMajorState.pop();
if (error) {

failureCallback();
} else {
WebInspector.domAgent.markUndoableState();
var ownerDocumentId = this._ownerDocumentId(nodeId);
if (ownerDocumentId)
WebInspector.domAgent.querySelectorAll(ownerDocumentId, selector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
else
failureCallback();
}
}

this._pendingCommandsMajorState.push(true);
CSSAgent.addRule(nodeId, selector, callback.bind(this, successCallback, failureCallback, selector));
},

mediaQueryResultChanged: function()
{
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged);
},


styleSheetHeaders: function()
{
return Object.values(this._resourceBinding._styleSheetIdToHeader);
},


_ownerDocumentId: function(nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return null;
return node.ownerDocument ? node.ownerDocument.id : null;
},


_fireStyleSheetChanged: function(styleSheetId)
{
if (!this._pendingCommandsMajorState.length)
return;

var majorChange = this._pendingCommandsMajorState[this._pendingCommandsMajorState.length - 1];

if (!majorChange || !styleSheetId || !this.hasEventListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged))
return;

this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, majorChange: majorChange });
},


_styleSheetAdded: function(header)
{
this._resourceBinding._setHeaderForStyleSheetId(header.styleSheetId, header);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.StyleSheetAdded, header);
},


_styleSheetRemoved: function(id)
{
var header = this._resourceBinding._styleSheetIdToHeader[id];
console.assert(header);
this._resourceBinding._setHeaderForStyleSheetId(id, null);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, header);
},


_namedFlowCreated: function(namedFlowPayload)
{
var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];

if (!namedFlowCollection)
return;

namedFlowCollection._appendNamedFlow(namedFlow);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowCreated, namedFlow);
},


_namedFlowRemoved: function(documentNodeId, flowName)
{
var namedFlowCollection = this._namedFlowCollections[documentNodeId];

if (!namedFlowCollection)
return;

namedFlowCollection._removeNamedFlow(flowName);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, { documentNodeId: documentNodeId, flowName: flowName });
},


_regionLayoutUpdated: function(namedFlowPayload)
{
var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];

if (!namedFlowCollection)
return;

namedFlowCollection._appendNamedFlow(namedFlow);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, namedFlow);
},


setStyleSheetText: function(styleSheetId, newText, majorChange, userCallback)
{
function callback(error)
{
this._pendingCommandsMajorState.pop();
if (!error && majorChange)
WebInspector.domAgent.markUndoableState();

if (!error && userCallback)
userCallback(error);
}
this._pendingCommandsMajorState.push(majorChange);
CSSAgent.setStyleSheetText(styleSheetId, newText, callback.bind(this));
},

_undoRedoRequested: function()
{
this._pendingCommandsMajorState.push(true);
},

_undoRedoCompleted: function()
{
this._pendingCommandsMajorState.pop();
},


viaInspectorResourceForRule: function(rule)
{
if (!rule.id)
return null;
return this._resourceBinding._inspectorResource(rule.id.styleSheetId);
},


resourceBinding: function()
{
return this._resourceBinding;
},


_mainFrameCreatedOrNavigated: function(event)
{
this._resetSourceMappings();
this._resourceBinding._reset();
},


setSourceMapping: function(url, sourceMapping)
{
if (sourceMapping)
this._sourceMappings[url] = sourceMapping;
else
delete this._sourceMappings[url];
this._updateLocations();
},

_resetSourceMappings: function()
{
this._sourceMappings = {};
},

_resetNamedFlowCollections: function()
{
this._namedFlowCollections = {};
},

_updateLocations: function()
{
for (var i = 0; i < this._locations.length; ++i)
this._locations[i].update();
},


createLiveLocation: function(cssRule, updateDelegate)
{
if (!cssRule._rawLocation)
return null;
var location = new WebInspector.CSSStyleModel.LiveLocation(cssRule._rawLocation, updateDelegate);
this._locations.push(location);
location.update();
return location;
},


rawLocationToUILocation: function(rawLocation)
{
var sourceMapping = this._sourceMappings[rawLocation.url];
if (sourceMapping) {
var uiLocation = sourceMapping.rawLocationToUILocation(rawLocation);
if (uiLocation)
return uiLocation;
}
var uiSourceCode = this._workspace.uiSourceCodeForURL(rawLocation.url);
if (!uiSourceCode)
return null;
return new WebInspector.UILocation(uiSourceCode, rawLocation.lineNumber, rawLocation.columnNumber);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.CSSStyleModel.LiveLocation = function(rawLocation, updateDelegate)
{
WebInspector.LiveLocation.call(this, rawLocation, updateDelegate);
}

WebInspector.CSSStyleModel.LiveLocation.prototype = {

uiLocation: function()
{
var cssLocation =   (this.rawLocation());
return WebInspector.cssModel.rawLocationToUILocation(cssLocation);
},

dispose: function()
{
WebInspector.LiveLocation.prototype.dispose.call(this);
var locations = WebInspector.cssModel._locations;
if (locations)
locations.remove(this);
},

__proto__: WebInspector.LiveLocation.prototype
}


WebInspector.CSSLocation = function(url, lineNumber, columnNumber)
{
this.url = url;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber || 0;
}


WebInspector.CSSStyleDeclaration = function(payload)
{
this.id = payload.styleId;
this.width = payload.width;
this.height = payload.height;
this.range = payload.range;
this._shorthandValues = WebInspector.CSSStyleDeclaration.buildShorthandValueMap(payload.shorthandEntries);
this._livePropertyMap = {}; 
this._allProperties = []; 
this.__disabledProperties = {}; 
var payloadPropertyCount = payload.cssProperties.length;

var propertyIndex = 0;
for (var i = 0; i < payloadPropertyCount; ++i) {
var property = 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;
++propertyIndex;
}
this.length = propertyIndex;
if ("cssText" in payload)
this.cssText = payload.cssText;
}


WebInspector.CSSStyleDeclaration.buildShorthandValueMap = function(shorthandEntries)
{
var result = {};
for (var i = 0; i < shorthandEntries.length; ++i)
result[shorthandEntries[i].name] = shorthandEntries[i].value;
return result;
}


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


WebInspector.CSSStyleDeclaration.parseComputedStylePayload = function(payload)
{
var newPayload =   ({ cssProperties: [], shorthandEntries: [], width: "", height: "" });
if (payload)
newPayload.cssProperties = payload;

return new WebInspector.CSSStyleDeclaration(newPayload);
}

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 : "";
},


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


longhandProperties: function(name)
{
var longhands = WebInspector.CSSMetadata.cssPropertiesMetainfo.longhands(name);
var result = [];
for (var i = 0; longhands && i < longhands.length; ++i) {
var property = this._livePropertyMap[longhands[i]];
if (property)
result.push(property);
}
return result;
},


shorthandValue: function(shorthandProperty)
{
return this._shorthandValues[shorthandProperty];
},


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(index)
{
index = (typeof index === "undefined") ? this.pastLastSourcePropertyIndex() : index;
return new WebInspector.CSSProperty(this, index, "", "", "", "active", true, false, "");
},


insertPropertyAt: function(index, name, value, userCallback)
{

function callback(error, payload)
{
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (!userCallback)
return;

if (error) {
console.error(error);
userCallback(null);
} else
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload));
}

if (!this.id)
throw "No style id";

WebInspector.cssModel._pendingCommandsMajorState.push(true);
CSSAgent.setPropertyText(this.id, index, name + ": " + value + ";", false, callback.bind(this));
},


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


setText: function(text, userCallback)
{

function callback(error, payload)
{
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (!userCallback)
return;

if (error) {
console.error(error);
userCallback(null);
} else
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload));
}

if (!this.id)
throw "No style id";

if (typeof this.cssText === "undefined") {
userCallback(null);
return;
}

WebInspector.cssModel._pendingCommandsMajorState.push(true);
CSSAgent.setStyleText(this.id, text, callback);
}
}


WebInspector.CSSRule = function(payload, matchingSelectors)
{
this.id = payload.ruleId;
if (matchingSelectors)
this.matchingSelectors = matchingSelectors;
this.selectors = payload.selectorList.selectors;
this.selectorText = this.selectors.join(", ");
this.selectorRange = payload.selectorList.range;
this.sourceLine = payload.sourceLine;
this.sourceURL = payload.sourceURL;
this.origin = payload.origin;
this.style = WebInspector.CSSStyleDeclaration.parsePayload(payload.style);
this.style.parentRule = this;
if (payload.media)
this.media = WebInspector.CSSMedia.parseMediaArrayPayload(payload.media);
this._setRawLocation(payload);
}


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

WebInspector.CSSRule.prototype = {
_setRawLocation: function(payload)
{
if (!payload.sourceURL)
return;
if (this.selectorRange) {
var resource = WebInspector.resourceTreeModel.resourceForURL(payload.sourceURL);
if (resource && resource.type === WebInspector.resourceTypes.Stylesheet) {
this._rawLocation = new WebInspector.CSSLocation(payload.sourceURL, this.selectorRange.startLine, this.selectorRange.startColumn);
return;
}
}
this._rawLocation = new WebInspector.CSSLocation(payload.sourceURL, payload.sourceLine);
},

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

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

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

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


isSourceNavigable: function()
{
if (!this.sourceURL)
return false;
var resource = WebInspector.resourceTreeModel.resourceForURL(this.sourceURL);
return !!resource && resource.contentType() === WebInspector.resourceTypes.Stylesheet;
}
}


WebInspector.CSSProperty = function(ownerStyle, index, name, value, priority, status, parsedOk, implicit, text, range)
{
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.text = text;
this.range = range;
}


WebInspector.CSSProperty.parsePayload = function(ownerStyle, index, payload)
{





var result = new WebInspector.CSSProperty(
ownerStyle, index, payload.name, payload.value, payload.priority || "", payload.status || "style", ("parsedOk" in payload) ? !!payload.parsedOk : true, !!payload.implicit, payload.text, payload.range);
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, overwrite, userCallback)
{

function enabledCallback(style)
{
if (userCallback)
userCallback(style);
}


function callback(error, stylePayload)
{
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (!error) {
if (majorChange)
WebInspector.domAgent.markUndoableState();
this.text = propertyText;
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
var newProperty = style.allProperties[this.index];

if (newProperty && this.disabled && !propertyText.match(/^\s*$/)) {
newProperty.setDisabled(false, enabledCallback);
return;
}

if (userCallback)
userCallback(style);
} else {
if (userCallback)
userCallback(null);
}
}

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

if (!this.ownerStyle.id)
throw "No owner style id";


WebInspector.cssModel._pendingCommandsMajorState.push(majorChange);
CSSAgent.setPropertyText(this.ownerStyle.id, this.index, propertyText, overwrite, callback.bind(this));
},


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


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


function callback(error, stylePayload)
{
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (error) {
if (userCallback)
userCallback(null);
return;
}
WebInspector.domAgent.markUndoableState();
if (userCallback) {
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
userCallback(style);
}
}

if (!this.ownerStyle.id)
throw "No owner style id";

WebInspector.cssModel._pendingCommandsMajorState.push(false);
CSSAgent.toggleProperty(this.ownerStyle.id, this.index, disabled, callback.bind(this));
},


uiLocation: function(forName)
{
if (!this.range || !this.ownerStyle || !this.ownerStyle.parentRule || !this.ownerStyle.parentRule.sourceURL)
return null;

var range = this.range;
var line = forName ? range.startLine : range.endLine;

var column = forName ? range.startColumn : range.endColumn - 1;
var rawLocation = new WebInspector.CSSLocation(this.ownerStyle.parentRule.sourceURL, line, column);
return WebInspector.cssModel.rawLocationToUILocation(rawLocation);
}
}


WebInspector.CSSMedia = function(payload)
{
this.text = payload.text;
this.source = payload.source;
this.sourceURL = payload.sourceURL || "";
this.sourceLine = typeof payload.sourceLine === "undefined" || this.source === "linkedSheet" ? -1 : payload.sourceLine;
}

WebInspector.CSSMedia.Source = {
LINKED_SHEET: "linkedSheet",
INLINE_SHEET: "inlineSheet",
MEDIA_RULE: "mediaRule",
IMPORT_RULE: "importRule"
};


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


WebInspector.CSSMedia.parseMediaArrayPayload = function(payload)
{
var result = [];
for (var i = 0; i < payload.length; ++i)
result.push(WebInspector.CSSMedia.parsePayload(payload[i]));
return result;
}


WebInspector.CSSStyleSheetHeader = function(payload)
{
this.id = payload.styleSheetId;
this.frameId = payload.frameId;
this.sourceURL = payload.sourceURL;
this.origin = payload.origin;
this.title = payload.title;
this.disabled = payload.disabled;
}

WebInspector.CSSStyleSheetHeader.prototype = {

resourceURL: function()
{
return this.origin === "inspector" ? this._viaInspectorResourceURL() : this.sourceURL;
},


_key: function()
{
return this.frameId + ":" + this.resourceURL();
},


_viaInspectorResourceURL: function()
{
var parsedURL = new WebInspector.ParsedURL(this.sourceURL);
var fakeURL = "inspector://" + parsedURL.host + parsedURL.folderPathComponents;
if (!fakeURL.endsWith("/"))
fakeURL += "/";
fakeURL += "inspector-stylesheet";
return fakeURL;
}
}


WebInspector.CSSStyleSheet = function(payload)
{
this.id = payload.styleSheetId;
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(error, styleSheetPayload)
{
if (error)
userCallback(null);
else
userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload));
}
CSSAgent.getStyleSheet(styleSheetId, callback.bind(this));
}

WebInspector.CSSStyleSheet.prototype = {

getText: function()
{
return this._text;
},


setText: function(newText, majorChange, userCallback)
{

function callback(error)
{
if (!error)
WebInspector.domAgent.markUndoableState();

WebInspector.cssModel._pendingCommandsMajorState.pop();
if (userCallback)
userCallback(error);
}

WebInspector.cssModel._pendingCommandsMajorState.push(majorChange);
CSSAgent.setStyleSheetText(this.id, newText, callback.bind(this));
}
}


WebInspector.CSSStyleModelResourceBinding = function()
{
this._reset();
}

WebInspector.CSSStyleModelResourceBinding.prototype = {

_setHeaderForStyleSheetId: function(styleSheetId, header)
{
var oldHeader = this._styleSheetIdToHeader[styleSheetId];
if (oldHeader) {
delete this._styleSheetIdToHeader[styleSheetId];
delete this._frameAndURLToStyleSheetId[oldHeader._key()];
}
if (header) {
var styleSheetHeader = new WebInspector.CSSStyleSheetHeader(header);
this._styleSheetIdToHeader[styleSheetId] = styleSheetHeader;
if (styleSheetHeader.origin === "inspector")
this._createInspectorResource(styleSheetHeader);
else
this._frameAndURLToStyleSheetId[styleSheetHeader._key()] = styleSheetHeader.id;
}
},


resourceURLForStyleSheetId: function(styleSheetId)
{
var header = this._styleSheetIdToHeader[styleSheetId];
if (!header)
return null;

var frame = WebInspector.resourceTreeModel.frameForId(header.frameId);
if (!frame)
return null;

return header.resourceURL();
},


styleSheetIdForResource: function(resource)
{
return this._frameAndURLToStyleSheetId[resource.frameId + ":" + resource.url] || null;
},


_createInspectorResource: function(header)
{
var frame = WebInspector.resourceTreeModel.frameForId(header.frameId);
if (!frame)
return;

var viaInspectorURL = header._viaInspectorResourceURL();
console.assert(!frame.resourceForURL(viaInspectorURL));

var resource = frame.resourceForURL(header.sourceURL);
if (!resource)
return;

this._frameAndURLToStyleSheetId[header._key()] = header.id;
var inspectorResource = new WebInspector.Resource(null, viaInspectorURL, resource.documentURL, resource.frameId, resource.loaderId, WebInspector.resourceTypes.Stylesheet, "text/css", true);


function overrideRequestContent(callback)
{
function callbackWrapper(error, content)
{
callback(error ? "" : content, false, "text/css");
}
CSSAgent.getStyleSheetText(header.id, callbackWrapper);
}
inspectorResource.requestContent = overrideRequestContent;
frame.addResource(inspectorResource);
},


_inspectorResource: function(styleSheetId)
{
var header = this._styleSheetIdToHeader[styleSheetId];
if (!header)
return null;
var frame = WebInspector.resourceTreeModel.frameForId(header.frameId);
if (!frame)
return null;

var viaInspectorURL = header._viaInspectorResourceURL();
return frame.resourceForURL(viaInspectorURL);
},

_reset: function()
{


this._frameAndURLToStyleSheetId = {};

this._styleSheetIdToHeader = {};
}
}


WebInspector.CSSDispatcher = function(cssModel)
{
this._cssModel = cssModel;
}

WebInspector.CSSDispatcher.prototype = {
mediaQueryResultChanged: function()
{
this._cssModel.mediaQueryResultChanged();
},


styleSheetChanged: function(styleSheetId)
{
this._cssModel._fireStyleSheetChanged(styleSheetId);
},


styleSheetAdded: function(header)
{
this._cssModel._styleSheetAdded(header);
},


styleSheetRemoved: function(id)
{
this._cssModel._styleSheetRemoved(id);
},


namedFlowCreated: function(namedFlowPayload)
{
this._cssModel._namedFlowCreated(namedFlowPayload);
},


namedFlowRemoved: function(documentNodeId, flowName)
{
this._cssModel._namedFlowRemoved(documentNodeId, flowName);
},


regionLayoutUpdated: function(namedFlowPayload)
{
this._cssModel._regionLayoutUpdated(namedFlowPayload);
}
}


WebInspector.NamedFlow = function(payload)
{
this.documentNodeId = payload.documentNodeId;
this.name = payload.name;
this.overset = payload.overset;
this.content = payload.content;
this.regions = payload.regions;
}


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


WebInspector.NamedFlowCollection = function(payload)
{

this.namedFlowMap = {};

for (var i = 0; i < payload.length; ++i) {
var namedFlow = WebInspector.NamedFlow.parsePayload(payload[i]);
this.namedFlowMap[namedFlow.name] = namedFlow;
}
}

WebInspector.NamedFlowCollection.prototype = {

_appendNamedFlow: function(namedFlow)
{
this.namedFlowMap[namedFlow.name] = namedFlow;
},


_removeNamedFlow: function(flowName)
{
delete this.namedFlowMap[flowName];
},


flowByName: function(flowName)
{
var namedFlow = this.namedFlowMap[flowName];

if (!namedFlow)
return null;
return namedFlow;
}
}

WebInspector.cssModel = null;






WebInspector.NetworkManager = function()
{
WebInspector.Object.call(this);
this._dispatcher = new WebInspector.NetworkDispatcher(this);
if (WebInspector.settings.cacheDisabled.get())
NetworkAgent.setCacheDisabled(true);

NetworkAgent.enable();

WebInspector.settings.cacheDisabled.addChangeListener(this._cacheDisabledSettingChanged, this);
}

WebInspector.NetworkManager.EventTypes = {
RequestStarted: "RequestStarted",
RequestUpdated: "RequestUpdated",
RequestFinished: "RequestFinished",
RequestUpdateDropped: "RequestUpdateDropped"
}

WebInspector.NetworkManager._MIMETypes = {
"text/html":                   {"document": true},
"text/xml":                    {"document": true},
"text/plain":                  {"document": true},
"application/xhtml+xml":       {"document": true},
"text/css":                    {"stylesheet": true},
"text/xsl":                    {"stylesheet": true},
"image/jpg":                   {"image": true},
"image/jpeg":                  {"image": true},
"image/pjpeg":                 {"image": true},
"image/png":                   {"image": true},
"image/gif":                   {"image": true},
"image/bmp":                   {"image": true},
"image/svg+xml":               {"image": true, "font": true, "document": true},
"image/vnd.microsoft.icon":    {"image": true},
"image/webp":                  {"image": true},
"image/x-icon":                {"image": true},
"image/x-xbitmap":             {"image": true},
"font/ttf":                    {"font": true},
"font/opentype":               {"font": true},
"application/font-woff":       {"font": true},
"application/x-font-type1":    {"font": true},
"application/x-font-ttf":      {"font": true},
"application/x-truetype-font": {"font": true},
"text/javascript":             {"script": true},
"text/ecmascript":             {"script": true},
"application/javascript":      {"script": true},
"application/ecmascript":      {"script": true},
"application/x-javascript":    {"script": true},
"application/json":            {"script": true},
"text/javascript1.1":          {"script": true},
"text/javascript1.2":          {"script": true},
"text/javascript1.3":          {"script": true},
"text/jscript":                {"script": true},
"text/livescript":             {"script": true},
}

WebInspector.NetworkManager.prototype = {

inflightRequestForURL: function(url)
{
return this._dispatcher._inflightRequestsByURL[url];
},


_cacheDisabledSettingChanged: function(event)
{
var enabled =   (event.data);
NetworkAgent.setCacheDisabled(enabled);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.NetworkDispatcher = function(manager)
{
this._manager = manager;
this._inflightRequestsById = {};
this._inflightRequestsByURL = {};
InspectorBackend.registerNetworkDispatcher(this);
}

WebInspector.NetworkDispatcher.prototype = {

_headersMapToHeadersArray: function(headersMap)
{
var result = [];
for (var name in headersMap) {
var values = headersMap[name].split("\n");
for (var i = 0; i < values.length; ++i)
result.push({name: name, value: values[i]});
}
return result;
},


_updateNetworkRequestWithRequest: function(networkRequest, request)
{
networkRequest.requestMethod = request.method;
networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
networkRequest.requestFormData = request.postData;
},


_updateNetworkRequestWithResponse: function(networkRequest, response)
{
if (!response)
return;

if (response.url && networkRequest.url !== response.url)
networkRequest.url = response.url;
networkRequest.mimeType = response.mimeType;
networkRequest.statusCode = response.status;
networkRequest.statusText = response.statusText;
networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
if (response.headersText)
networkRequest.responseHeadersText = response.headersText;
if (response.requestHeaders)
networkRequest.requestHeaders = this._headersMapToHeadersArray(response.requestHeaders);
if (response.requestHeadersText)
networkRequest.requestHeadersText = response.requestHeadersText;

networkRequest.connectionReused = response.connectionReused;
networkRequest.connectionId = response.connectionId;

if (response.fromDiskCache)
networkRequest.cached = true;
else
networkRequest.timing = response.timing;

if (!this._mimeTypeIsConsistentWithType(networkRequest)) {
WebInspector.console.addMessage(WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.Network,
WebInspector.ConsoleMessage.MessageLevel.Log,
WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".", networkRequest.type.title(), networkRequest.mimeType, networkRequest.url),
WebInspector.ConsoleMessage.MessageType.Log,
"",
0,
1,
[],
null,
networkRequest.requestId));
}
},


_mimeTypeIsConsistentWithType: function(networkRequest)
{






if (networkRequest.hasErrorStatusCode() || networkRequest.statusCode === 304 || networkRequest.statusCode === 204)
return true;

if (typeof networkRequest.type === "undefined"
|| networkRequest.type === WebInspector.resourceTypes.Other
|| networkRequest.type === WebInspector.resourceTypes.XHR
|| networkRequest.type === WebInspector.resourceTypes.WebSocket)
return true;

if (!networkRequest.mimeType)
return true; 

if (networkRequest.mimeType in WebInspector.NetworkManager._MIMETypes)
return networkRequest.type.name() in WebInspector.NetworkManager._MIMETypes[networkRequest.mimeType];

return false;
},


_updateNetworkRequestWithCachedResource: function(networkRequest, cachedResource)
{
networkRequest.type = WebInspector.resourceTypes[cachedResource.type];
networkRequest.resourceSize = cachedResource.bodySize;
this._updateNetworkRequestWithResponse(networkRequest, cachedResource.response);
},


_isNull: function(response)
{
if (!response)
return true;
return !response.status && !response.mimeType && (!response.headers || !Object.keys(response.headers).length);
},


requestWillBeSent: function(requestId, frameId, loaderId, documentURL, request, time, initiator, redirectResponse)
{
var networkRequest = this._inflightRequestsById[requestId];
if (networkRequest) {

if (!redirectResponse)
return;
this.responseReceived(requestId, frameId, loaderId, time, PageAgent.ResourceType.Other, redirectResponse);
networkRequest = this._appendRedirect(requestId, time, request.url);
} else
networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, request.url, documentURL, initiator);
networkRequest.hasNetworkData = true;
this._updateNetworkRequestWithRequest(networkRequest, request);
networkRequest.startTime = time;

this._startNetworkRequest(networkRequest);
},


requestServedFromCache: function(requestId)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.cached = true;
},


responseReceived: function(requestId, frameId, loaderId, time, resourceType, response)
{

if (this._isNull(response))
return;

var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest) {

var eventData = {};
eventData.url = response.url;
eventData.frameId = frameId;
eventData.loaderId = loaderId;
eventData.resourceType = resourceType;
eventData.mimeType = response.mimeType;
this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, eventData);
return;
}

networkRequest.responseReceivedTime = time;
networkRequest.type = WebInspector.resourceTypes[resourceType];

this._updateNetworkRequestWithResponse(networkRequest, response);

this._updateNetworkRequest(networkRequest);
},


dataReceived: function(requestId, time, dataLength, encodedDataLength)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.resourceSize += dataLength;
if (encodedDataLength != -1)
networkRequest.increaseTransferSize(encodedDataLength);
networkRequest.endTime = time;

this._updateNetworkRequest(networkRequest);
},


loadingFinished: function(requestId, finishTime)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
this._finishNetworkRequest(networkRequest, finishTime);
},


loadingFailed: function(requestId, time, localizedDescription, canceled)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.failed = true;
networkRequest.canceled = canceled;
networkRequest.localizedFailDescription = localizedDescription;
this._finishNetworkRequest(networkRequest, time);
},


requestServedFromMemoryCache: function(requestId, frameId, loaderId, documentURL, time, initiator, cachedResource)
{
var networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, cachedResource.url, documentURL, initiator);
this._updateNetworkRequestWithCachedResource(networkRequest, cachedResource);
networkRequest.cached = true;
networkRequest.requestMethod = "GET";
this._startNetworkRequest(networkRequest);
networkRequest.startTime = networkRequest.responseReceivedTime = time;
this._finishNetworkRequest(networkRequest, time);
},


webSocketCreated: function(requestId, requestURL)
{
var networkRequest = new WebInspector.NetworkRequest(requestId, requestURL, "", "", "");
networkRequest.type = WebInspector.resourceTypes.WebSocket;
this._startNetworkRequest(networkRequest);
},


webSocketWillSendHandshakeRequest: function(requestId, time, request)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.requestMethod = "GET";
networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
networkRequest.startTime = time;

this._updateNetworkRequest(networkRequest);
},


webSocketHandshakeResponseReceived: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.statusCode = response.status;
networkRequest.statusText = response.statusText;
networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
networkRequest.responseReceivedTime = time;

this._updateNetworkRequest(networkRequest);
},


webSocketFrameReceived: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.addFrame(response, time);
networkRequest.responseReceivedTime = time;

this._updateNetworkRequest(networkRequest);
},


webSocketFrameSent: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.addFrame(response, time, true);
networkRequest.responseReceivedTime = time;

this._updateNetworkRequest(networkRequest);
},


webSocketFrameError: function(requestId, time, errorMessage)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.addFrameError(errorMessage, time);
networkRequest.responseReceivedTime = time;

this._updateNetworkRequest(networkRequest);
},


webSocketClosed: function(requestId, time)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
this._finishNetworkRequest(networkRequest, time);
},


_appendRedirect: function(requestId, time, redirectURL)
{
var originalNetworkRequest = this._inflightRequestsById[requestId];
var previousRedirects = originalNetworkRequest.redirects || [];
originalNetworkRequest.requestId = "redirected:" + requestId + "." + previousRedirects.length;
delete originalNetworkRequest.redirects;
if (previousRedirects.length > 0)
originalNetworkRequest.redirectSource = previousRedirects[previousRedirects.length - 1];
this._finishNetworkRequest(originalNetworkRequest, time);
var newNetworkRequest = this._createNetworkRequest(requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId,
redirectURL, originalNetworkRequest.documentURL, originalNetworkRequest.initiator);
newNetworkRequest.redirects = previousRedirects.concat(originalNetworkRequest);
return newNetworkRequest;
},


_startNetworkRequest: function(networkRequest)
{
this._inflightRequestsById[networkRequest.requestId] = networkRequest;
this._inflightRequestsByURL[networkRequest.url] = networkRequest;
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestStarted, networkRequest);
},


_updateNetworkRequest: function(networkRequest)
{
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdated, networkRequest);
},


_finishNetworkRequest: function(networkRequest, finishTime)
{
networkRequest.endTime = finishTime;
networkRequest.finished = true;
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestFinished, networkRequest);
delete this._inflightRequestsById[networkRequest.requestId];
delete this._inflightRequestsByURL[networkRequest.url];
},


_dispatchEventToListeners: function(eventType, networkRequest)
{
this._manager.dispatchEventToListeners(eventType, networkRequest);
},


_createNetworkRequest: function(requestId, frameId, loaderId, url, documentURL, initiator)
{
var networkRequest = new WebInspector.NetworkRequest(requestId, url, documentURL, frameId, loaderId);
networkRequest.initiator = initiator;
return networkRequest;
}
}


WebInspector.networkManager = null;






WebInspector.NetworkLog = function()
{
this._requests = [];
this._requestForId = {};
WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.OnLoad, this._onLoad, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._onDOMContentLoaded, this);
}

WebInspector.NetworkLog.prototype = {

get requests()
{
return this._requests;
},


requestForURL: function(url)
{
for (var i = 0; i < this._requests.length; ++i) {
if (this._requests[i].url === url)
return this._requests[i];
}
return null;
},


pageLoadForRequest: function(request)
{
return request.__page;
},


_onMainFrameNavigated: function(event)
{
var mainFrame =   event.data;

this._currentPageLoad = null;
var oldRequests = this._requests.splice(0, this._requests.length);
for (var i = 0; i < oldRequests.length; ++i) {
var request = oldRequests[i];
if (request.loaderId === mainFrame.loaderId) {
if (!this._currentPageLoad)
this._currentPageLoad = new WebInspector.PageLoad(request);
this._requests.push(request);
request.__page = this._currentPageLoad;
}
}
},


_onRequestStarted: function(event)
{
var request =   (event.data);
this._requests.push(request);
this._requestForId[request.requestId] = request;
request.__page = this._currentPageLoad;
},


_onDOMContentLoaded: function(event)
{
if (this._currentPageLoad)
this._currentPageLoad.contentLoadTime = event.data;
},


_onLoad: function(event)
{
if (this._currentPageLoad)
this._currentPageLoad.loadTime = event.data;
},


requestForId: function(requestId)
{
return this._requestForId[requestId];
}
}


WebInspector.networkLog = null;


WebInspector.PageLoad = function(mainRequest)
{
this.id = ++WebInspector.PageLoad._lastIdentifier;
this.url = mainRequest.url;
this.startTime = mainRequest.startTime;
}

WebInspector.PageLoad._lastIdentifier = 0;






WebInspector.ResourceTreeModel = function(networkManager)
{
networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, this._onRequestUpdateDropped, this);

WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);

PageAgent.enable();

NetworkAgent.enable();
this._fetchResourceTree();

InspectorBackend.registerPageDispatcher(new WebInspector.PageDispatcher(this));

this._pendingConsoleMessages = {};
this._securityOriginFrameCount = {};
}

WebInspector.ResourceTreeModel.EventTypes = {
FrameAdded: "FrameAdded",
FrameNavigated: "FrameNavigated",
FrameDetached: "FrameDetached",
MainFrameNavigated: "MainFrameNavigated",
MainFrameCreatedOrNavigated: "MainFrameCreatedOrNavigated",
ResourceAdded: "ResourceAdded",
WillLoadCachedResources: "WillLoadCachedResources",
CachedResourcesLoaded: "CachedResourcesLoaded",
DOMContentLoaded: "DOMContentLoaded",
OnLoad: "OnLoad",
InspectedURLChanged: "InspectedURLChanged",
SecurityOriginAdded: "SecurityOriginAdded",
SecurityOriginRemoved: "SecurityOriginRemoved"
}

WebInspector.ResourceTreeModel.prototype = {
_fetchResourceTree: function()
{
this._frames = {};
delete this._cachedResourcesProcessed;
PageAgent.getResourceTree(this._processCachedResources.bind(this));
},

_processCachedResources: function(error, mainFramePayload)
{
if (error) {
console.error(JSON.stringify(error));
return;
}

this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources);
WebInspector.inspectedPageURL = mainFramePayload.frame.url;
this._addFramesRecursively(null, mainFramePayload);
this._dispatchInspectedURLChanged();
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);
this._cachedResourcesProcessed = true;
},

cachedResourcesLoaded: function()
{
return this._cachedResourcesProcessed;
},

_dispatchInspectedURLChanged: function()
{
InspectorFrontendHost.inspectedURLChanged(WebInspector.inspectedPageURL);
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, WebInspector.inspectedPageURL);
},


_addFrame: function(frame, aboutToNavigate)
{
this._frames[frame.id] = frame;
if (frame.isMainFrame())
this.mainFrame = frame;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, frame);
if (!aboutToNavigate)
this._addSecurityOrigin(frame.securityOrigin);
if (frame.isMainFrame())
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameCreatedOrNavigated, frame);
},


_addSecurityOrigin: function(securityOrigin)
{
if (!this._securityOriginFrameCount[securityOrigin]) {
this._securityOriginFrameCount[securityOrigin] = 1;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, securityOrigin);
return;
}
this._securityOriginFrameCount[securityOrigin] += 1;
},


_removeSecurityOrigin: function(securityOrigin)
{
console.assert(this._securityOriginFrameCount[securityOrigin]);
if (this._securityOriginFrameCount[securityOrigin] === 1) {
delete this._securityOriginFrameCount[securityOrigin];
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, securityOrigin);
return;
}
this._securityOriginFrameCount[securityOrigin] -= 1;
},


securityOrigins: function()
{
return Object.keys(this._securityOriginFrameCount);
},


_handleMainFrameDetached: function(mainFrame)
{

function removeOriginForFrame(frame)
{
for (var i = 0; i < frame.childFrames.length; ++i)
removeOriginForFrame.call(this, frame.childFrames[i]);
if (!frame.isMainFrame())
this._removeSecurityOrigin(frame.securityOrigin);
}
removeOriginForFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
},


_frameNavigated: function(framePayload)
{

if (!this._cachedResourcesProcessed)
return;
var frame = this._frames[framePayload.id];
var addedOrigin;
if (frame) {

this._removeSecurityOrigin(frame.securityOrigin);
frame._navigate(framePayload);
addedOrigin = frame.securityOrigin;
} else {

var parentFrame = this._frames[framePayload.parentId];
frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload);
if (frame.isMainFrame() && this.mainFrame) {
this._handleMainFrameDetached(this.mainFrame);

this._frameDetached(this.mainFrame.id);
}
this._addFrame(frame, true);
addedOrigin = frame.securityOrigin;
}

if (frame.isMainFrame())
WebInspector.inspectedPageURL = frame.url;

this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, frame);
if (frame.isMainFrame()) {
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, frame);
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameCreatedOrNavigated, frame);
}
if (addedOrigin)
this._addSecurityOrigin(addedOrigin);


var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resources[i]);

if (frame.isMainFrame())
this._dispatchInspectedURLChanged();
},


_frameDetached: function(frameId)
{

if (!this._cachedResourcesProcessed)
return;

var frame = this._frames[frameId];
if (!frame)
return;

this._removeSecurityOrigin(frame.securityOrigin);
if (frame.parentFrame)
frame.parentFrame._removeChildFrame(frame);
else
frame._remove();
},


_onRequestFinished: function(event)
{
if (!this._cachedResourcesProcessed)
return;

var request =   (event.data);
if (request.failed || request.type === WebInspector.resourceTypes.XHR)
return;

var frame = this._frames[request.frameId];
if (frame) {
var resource = frame._addRequest(request);
this._addPendingConsoleMessagesToResource(resource);
}
},


_onRequestUpdateDropped: function(event)
{
if (!this._cachedResourcesProcessed)
return;

var frameId = event.data.frameId;
var frame = this._frames[frameId];
if (!frame)
return;

var url = event.data.url;
if (frame._resourcesMap[url])
return;

var resource = new WebInspector.Resource(null, url, frame.url, frameId, event.data.loaderId, WebInspector.resourceTypes[event.data.resourceType], event.data.mimeType);
frame.addResource(resource);
},


frameForId: function(frameId)
{
return this._frames[frameId];
},


forAllResources: function(callback)
{
if (this.mainFrame)
return this.mainFrame._callForFrameResources(callback);
return false;
},


frames: function() 
{
return Object.values(this._frames);
},


_consoleMessageAdded: function(event)
{
var msg =   (event.data);
var resource = msg.url ? this.resourceForURL(msg.url) : null;
if (resource)
this._addConsoleMessageToResource(msg, resource);
else
this._addPendingConsoleMessage(msg);
},


_addPendingConsoleMessage: function(msg)
{
if (!msg.url)
return;
if (!this._pendingConsoleMessages[msg.url])
this._pendingConsoleMessages[msg.url] = [];
this._pendingConsoleMessages[msg.url].push(msg);
},


_addPendingConsoleMessagesToResource: function(resource)
{
var messages = this._pendingConsoleMessages[resource.url];
if (messages) {
for (var i = 0; i < messages.length; i++)
this._addConsoleMessageToResource(messages[i], resource);
delete this._pendingConsoleMessages[resource.url];
}
},


_addConsoleMessageToResource: function(msg, resource)
{
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
resource.warnings += msg.repeatDelta;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
resource.errors += msg.repeatDelta;
break;
}
resource.addMessage(msg);
},

_consoleCleared: function()
{
function callback(resource)
{
resource.clearErrorsAndWarnings();
}

this._pendingConsoleMessages = {};
this.forAllResources(callback);
},


resourceForURL: function(url)
{

return this.mainFrame ? this.mainFrame.resourceForURL(url) : null;
},


_addFramesRecursively: function(parentFrame, frameTreePayload)
{
var framePayload = frameTreePayload.frame;
var frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload);
this._addFrame(frame);

var frameResource = this._createResourceFromFramePayload(framePayload, framePayload.url, WebInspector.resourceTypes.Document, framePayload.mimeType);
if (frame.isMainFrame())
WebInspector.inspectedPageURL = frameResource.url;
frame.addResource(frameResource);

for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
this._addFramesRecursively(frame, frameTreePayload.childFrames[i]);

for (var i = 0; i < frameTreePayload.resources.length; ++i) {
var subresource = frameTreePayload.resources[i];
var resource = this._createResourceFromFramePayload(framePayload, subresource.url, WebInspector.resourceTypes[subresource.type], subresource.mimeType);
frame.addResource(resource);
}
},


_createResourceFromFramePayload: function(frame, url, type, mimeType)
{
return new WebInspector.Resource(null, url, frame.url, frame.id, frame.loaderId, type, mimeType);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.ResourceTreeFrame = function(model, parentFrame, payload)
{
this._model = model;
this._parentFrame = parentFrame;

this._id = payload.id;
this._loaderId = payload.loaderId;
this._name = payload.name;
this._url = payload.url;
this._securityOrigin = payload.securityOrigin;
this._mimeType = payload.mimeType;


this._childFrames = [];


this._resourcesMap = {};

if (this._parentFrame)
this._parentFrame._childFrames.push(this);
}

WebInspector.ResourceTreeFrame.prototype = {

get id()
{
return this._id;
},


get name()
{
return this._name || "";
},


get url()
{
return this._url;
},


get securityOrigin()
{
return this._securityOrigin;
},


get loaderId()
{
return this._loaderId;
},


get parentFrame()
{
return this._parentFrame;
},


get childFrames()
{
return this._childFrames;
},


isMainFrame: function()
{
return !this._parentFrame;
},


_navigate: function(framePayload)
{
this._loaderId = framePayload.loaderId;
this._name = framePayload.name;
this._url = framePayload.url;
this._securityOrigin = framePayload.securityOrigin;
this._mimeType = framePayload.mimeType;

var mainResource = this._resourcesMap[this._url];
this._resourcesMap = {};
this._removeChildFrames();
if (mainResource && mainResource.loaderId === this._loaderId)
this.addResource(mainResource);
},


get mainResource()
{
return this._resourcesMap[this._url];
},


_removeChildFrame: function(frame)
{
this._childFrames.remove(frame);
frame._remove();
},

_removeChildFrames: function()
{
var copy = this._childFrames.slice();
for (var i = 0; i < copy.length; ++i)
this._removeChildFrame(copy[i]); 
},

_remove: function()
{
this._removeChildFrames();
delete this._model._frames[this.id];
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this);
},


addResource: function(resource)
{
if (this._resourcesMap[resource.url] === resource) {

return;
}
this._resourcesMap[resource.url] = resource;
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
},


_addRequest: function(request)
{
var resource = this._resourcesMap[request.url];
if (resource && resource.request === request) {

return resource;
}
resource = new WebInspector.Resource(request, request.url, request.documentURL, request.frameId, request.loaderId, request.type, request.mimeType);
this._resourcesMap[resource.url] = resource;
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
return resource;
},


resources: function()
{
var result = [];
for (var url in this._resourcesMap)
result.push(this._resourcesMap[url]);
return result;
},


resourceForURL: function(url)
{
var result;
function filter(resource)
{
if (resource.url === url) {
result = resource;
return true;
}
}
this._callForFrameResources(filter);
return result;
},


_callForFrameResources: function(callback)
{
for (var url in this._resourcesMap) {
if (callback(this._resourcesMap[url]))
return true;
}

for (var i = 0; i < this._childFrames.length; ++i) {
if (this._childFrames[i]._callForFrameResources(callback))
return true;
}
return false;
}
}


WebInspector.PageDispatcher = function(resourceTreeModel)
{
this._resourceTreeModel = resourceTreeModel;
}

WebInspector.PageDispatcher.prototype = {
domContentEventFired: function(time)
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, time);
},

loadEventFired: function(time)
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.OnLoad, time);
},

frameNavigated: function(frame)
{
this._resourceTreeModel._frameNavigated(frame);
},

frameDetached: function(frameId)
{
this._resourceTreeModel._frameDetached(frameId);
},

frameStartedLoading: function(frameId)
{
},

frameStoppedLoading: function(frameId)
{
},

frameScheduledNavigation: function(frameId, delay)
{
},

frameClearedScheduledNavigation: function(frameId)
{
},

javascriptDialogOpening: function(message)
{
},

javascriptDialogClosed: function()
{
},

scriptsEnabled: function(isEnabled)
{
WebInspector.settings.javaScriptDisabled.set(!isEnabled);
}
}


WebInspector.resourceTreeModel = null;






WebInspector.ParsedURL = function(url)
{
this.isValid = false;
this.url = url;
this.scheme = "";
this.host = "";
this.port = "";
this.path = "";
this.queryParams = "";
this.fragment = "";
this.folderPathComponents = "";
this.lastPathComponent = "";







var match = url.match(/^([A-Za-z][A-Za-z0-9+.-]*):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
if (match) {
this.isValid = true;
this.scheme = match[1].toLowerCase();
this.host = match[2];
this.port = match[3];
this.path = match[4] || "/";
this.fragment = match[5];
} else {
if (this.url.startsWith("data:")) {
this.scheme = "data";
return;
}
if (this.url === "about:blank") {
this.scheme = "about";
return;
}
this.path = this.url;
}


var path = this.path;
var indexOfQuery = path.indexOf("?");
if (indexOfQuery !== -1) {
this.queryParams = path.substring(indexOfQuery + 1)
path = path.substring(0, indexOfQuery);
}


var lastSlashIndex = path.lastIndexOf("/");
if (lastSlashIndex !== -1) {
this.folderPathComponents = path.substring(0, lastSlashIndex);
this.lastPathComponent = path.substring(lastSlashIndex + 1);
} else
this.lastPathComponent = path;
}


WebInspector.ParsedURL.splitURL = function(url)
{
var parsedURL = new WebInspector.ParsedURL(url);
var origin;
var folderPath;
var name;
if (parsedURL.isValid) {
origin = parsedURL.scheme + "://" + parsedURL.host;
if (parsedURL.port)
origin += ":" + parsedURL.port;
folderPath = parsedURL.folderPathComponents;
name = parsedURL.lastPathComponent;
if (parsedURL.queryParams)
name += "?" + parsedURL.queryParams;
} else {
origin = "";
folderPath = "";
name = url;
}
var result = [origin];
var splittedPath = folderPath.split("/");
for (var i = 1; i < splittedPath.length; ++i)
result.push(splittedPath[i]);
result.push(name);
return result;
}


WebInspector.ParsedURL.completeURL = function(baseURL, href)
{
if (href) {

var trimmedHref = href.trim();
if (trimmedHref.startsWith("data:") || trimmedHref.startsWith("blob:") || trimmedHref.startsWith("javascript:"))
return href;


var parsedHref = trimmedHref.asParsedURL();
if (parsedHref && parsedHref.scheme)
return trimmedHref;
} else
return baseURL;

var parsedURL = baseURL.asParsedURL();
if (parsedURL) {
if (parsedURL.isDataURL())
return href;
var path = href;
if (path.charAt(0) !== "/") {
var basePath = parsedURL.path;


var questionMarkIndex = basePath.indexOf("?");
if (questionMarkIndex > 0)
basePath = basePath.substring(0, questionMarkIndex);


var prefix;
if (path.charAt(0) === "?") {
var basePathCutIndex = basePath.indexOf("?");
if (basePathCutIndex !== -1)
prefix = basePath.substring(0, basePathCutIndex);
else
prefix = basePath;
} else
prefix = basePath.substring(0, basePath.lastIndexOf("/")) + "/";

path = prefix + path;
} else if (path.length > 1 && path.charAt(1) === "/") {

return parsedURL.scheme + ":" + path;
}
return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + path;
}
return null;
}

WebInspector.ParsedURL.prototype = {
get displayName()
{
if (this._displayName)
return this._displayName;

if (this.isDataURL())
return this.dataURLDisplayName();
if (this.isAboutBlank())
return this.url;

this._displayName = this.lastPathComponent;
if (!this._displayName && this.host)
this._displayName = this.host + "/";
if (!this._displayName && this.url)
this._displayName = this.url.trimURL(WebInspector.inspectedPageDomain ? WebInspector.inspectedPageDomain : "");
if (this._displayName === "/")
this._displayName = this.url;
return this._displayName;
},

dataURLDisplayName: function()
{
if (this._dataURLDisplayName)
return this._dataURLDisplayName;
if (!this.isDataURL())
return "";
this._dataURLDisplayName = this.url.trimEnd(20);
return this._dataURLDisplayName;
},

isAboutBlank: function()
{
return this.url === "about:blank";
},

isDataURL: function()
{
return this.scheme === "data";
}
}


String.prototype.asParsedURL = function()
{
var parsedURL = new WebInspector.ParsedURL(this.toString());
if (parsedURL.isValid)
return parsedURL;
return null;
}






WebInspector.resourceForURL = function(url)
{
return WebInspector.resourceTreeModel.resourceForURL(url);
}


WebInspector.forAllResources = function(callback)
{
WebInspector.resourceTreeModel.forAllResources(callback);
}


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

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

var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
if (uiSourceCode)
return uiSourceCode.displayName();

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

var parsedURL = WebInspector.inspectedPageURL.asParsedURL();
var lastPathComponent = parsedURL ? parsedURL.lastPathComponent : parsedURL;
var index = WebInspector.inspectedPageURL.indexOf(lastPathComponent);
if (index !== -1 && index + lastPathComponent.length === WebInspector.inspectedPageURL.length) {
var baseURL = WebInspector.inspectedPageURL.substring(0, index);
if (url.startsWith(baseURL))
return url.substring(index);
}

if (!parsedURL)
return url;

var displayName = url.trimURL(parsedURL.host);
return displayName === "/" ? parsedURL.host + "/" : displayName;
}


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

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

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

        var title = linkString;
        var realURL = (linkString.startsWith("www.") ? "http://" + linkString : linkString);
        var lineColumnMatch = lineColumnRegEx.exec(realURL);
        var lineNumber;
        if (lineColumnMatch) {
            realURL = realURL.substring(0, realURL.length - lineColumnMatch[0].length);
            lineNumber = parseInt(lineColumnMatch[1], 10);
            lineNumber = isNaN(lineNumber) ? undefined : lineNumber;
        }

        var linkNode = linkifier(title, realURL, lineNumber);
        container.appendChild(linkNode);
        string = string.substring(linkIndex + linkString.length, string.length);
    }

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

    return container;
}

/**
 * @param {string} string
 * @return {DocumentFragment}
 */
WebInspector.linkifyStringAsFragment = function(string)
{
    /**
     * @param {string} title
     * @param {string} url
     * @param {number=} lineNumber
     * @return {Node}
     */
    function linkifier(title, url, lineNumber)
    {
        var isExternal = !WebInspector.resourceForURL(url);
        var urlNode = WebInspector.linkifyURLAsNode(url, title, undefined, isExternal);
        if (typeof(lineNumber) !== "undefined") {
            urlNode.lineNumber = lineNumber;
            urlNode.preferredPanel = "scripts";
        }
        
        return urlNode; 
    }
    
    return WebInspector.linkifyStringAsFragmentWithCustomLinkifier(string, linkifier);
}

/**
 * @param {string} url
 * @param {string=} linkText
 * @param {string=} classes
 * @param {boolean=} isExternal
 * @param {string=} tooltipText
 * @return {!Element}
 */
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 = sanitizeHref(url);
    a.className = classes;
    if (typeof tooltipText === "undefined")
        a.title = url;
    else if (typeof tooltipText !== "string" || tooltipText.length)
        a.title = tooltipText;
    a.textContent = linkText.trimMiddle(WebInspector.Linkifier.MaxLengthForDisplayedURLs);
    if (isExternal)
        a.setAttribute("target", "_blank");

    return a;
}

/**
 * @param {string} url
 * @param {number=} lineNumber
 * @return {string}
 */
WebInspector.formatLinkText = function(url, lineNumber)
{
    var text = url ? WebInspector.displayNameForURL(url) : WebInspector.UIString("(program)");
    if (typeof lineNumber === "number")
        text += ":" + (lineNumber + 1);
    return text;
}

/**
 * @param {string} url
 * @param {number=} lineNumber
 * @param {string=} classes
 * @param {string=} tooltipText
 * @return {Element}
 */
WebInspector.linkifyResourceAsNode = function(url, lineNumber, classes, tooltipText)
{
    var linkText = WebInspector.formatLinkText(url, lineNumber);
    var anchor = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText);
    anchor.lineNumber = lineNumber;
    return anchor;
}

/**
 * @param {WebInspector.NetworkRequest} request
 * @param {string=} classes
 * @return {Element}
 */
WebInspector.linkifyRequestAsNode = function(request, classes)
{
    var anchor = WebInspector.linkifyURLAsNode(request.url);
    anchor.preferredPanel = "network";
    anchor.requestId  = request.requestId;
    return anchor;
}

/**
 * @param {string} content
 * @param {string} mimeType
 * @param {boolean} contentEncoded
 * @return {?string}
 */
WebInspector.contentAsDataURL = function(content, mimeType, contentEncoded)
{
    const maxDataUrlSize = 1024 * 1024;
    if (content == null || content.length > maxDataUrlSize)
        return null;

    return "data:" + mimeType + (contentEncoded ? ";base64," : ",") + content;
}

/* ResourceType.js */

/*
 * Copyright (C) 2012 Google Inc.  All rights reserved.
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @param {string} name
 * @param {string} title
 * @param {string} categoryTitle
 * @param {string} color
 * @param {boolean} isTextType
 */
WebInspector.ResourceType = function(name, title, categoryTitle, color, isTextType)
{
    this._name = name;
    this._title = title;
    this._categoryTitle = categoryTitle;
    this._color = color;
    this._isTextType = isTextType;
}

WebInspector.ResourceType.prototype = {
    /**
     * @return {string}
     */
    name: function()
    {
        return this._name;
    },

    /**
     * @return {string}
     */
    title: function()
    {
        return this._title;
    },

    /**
     * @return {string}
     */
    categoryTitle: function()
    {
        return this._categoryTitle;
    },

    /**
     * @return {string}
     */
    color: function()
    {
        return this._color;
    },

    /**
     * @return {boolean}
     */
    isTextType: function()
    {
        return this._isTextType;
    },

    /**
     * @return {string}
     */
    toString: function()
    {
        return this._name;
    },

    /**
     * @return {string}
     */
    canonicalMimeType: function()
    {
        if (this === WebInspector.resourceTypes.Document)
            return "text/html";
        if (this === WebInspector.resourceTypes.Script)
            return "text/javascript";
        if (this === WebInspector.resourceTypes.Stylesheet)
            return "text/css";
        return "";
    }
}

/**
 * Keep these in sync with WebCore::InspectorPageAgent::resourceTypeJson
 * @enum {!WebInspector.ResourceType}
 */
WebInspector.resourceTypes = {
    Document: new WebInspector.ResourceType("document", "Document", "Documents", "rgb(47,102,236)", true),
    Stylesheet: new WebInspector.ResourceType("stylesheet", "Stylesheet", "Stylesheets", "rgb(157,231,119)", true),
    Image: new WebInspector.ResourceType("image", "Image", "Images", "rgb(164,60,255)", false),
    Script: new WebInspector.ResourceType("script", "Script", "Scripts", "rgb(255,121,0)", true),
    XHR: new WebInspector.ResourceType("xhr", "XHR", "XHR", "rgb(231,231,10)", true),
    Font: new WebInspector.ResourceType("font", "Font", "Fonts", "rgb(255,82,62)", false),
    WebSocket: new WebInspector.ResourceType("websocket", "WebSocket", "WebSockets", "rgb(186,186,186)", false), // FIXME: Decide the color.
    Other: new WebInspector.ResourceType("other", "Other", "Other", "rgb(186,186,186)", false)
}

/* TimelineManager.js */

/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.Object}
 */
WebInspector.TimelineManager = function()
{
    WebInspector.Object.call(this);
    this._dispatcher = new WebInspector.TimelineDispatcher(this);
    this._enablementCount = 0;
}

WebInspector.TimelineManager.EventTypes = {
    TimelineStarted: "TimelineStarted",
    TimelineStopped: "TimelineStopped",
    TimelineEventRecorded: "TimelineEventRecorded"
}

WebInspector.TimelineManager.prototype = {
    /**
     * @param {number=} maxCallStackDepth
     * @param {boolean=} includeDomCounters
     * @param {boolean=} includeNativeMemoryStatistics
     */
    start: function(maxCallStackDepth, includeDomCounters, includeNativeMemoryStatistics)
    {
        this._enablementCount++;
        if (this._enablementCount === 1)
            TimelineAgent.start(maxCallStackDepth, includeDomCounters, includeNativeMemoryStatistics, this._started.bind(this));
    },

    stop: function()
    {
        if (!this._enablementCount) {
            console.error("WebInspector.TimelineManager start/stop calls are unbalanced");
            return;
        }
        this._enablementCount--;
        if (!this._enablementCount)
            TimelineAgent.stop(this._stopped.bind(this));
    },

    _started: function()
    {
        this.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStarted);
    },

    _stopped: function()
    {
        this.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStopped);
    },

    __proto__: WebInspector.Object.prototype
}

/**
 * @constructor
 * @implements {TimelineAgent.Dispatcher}
 */
WebInspector.TimelineDispatcher = function(manager)
{
    this._manager = manager;
    InspectorBackend.registerTimelineDispatcher(this);
}

WebInspector.TimelineDispatcher.prototype = {
    eventRecorded: function(record)
    {
        this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, record);
    }
}

/**
 * @type {WebInspector.TimelineManager}
 */
WebInspector.timelineManager;

/* UserAgentSupport.js */

/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 */
WebInspector.UserAgentSupport = function()
{
    this._userAgentOverrideEnabled = false;
    this._deviceMetricsOverrideEnabled = false;
    this._geolocationPositionOverrideEnabled = false;
    this._deviceOrientationOverrideEnabled = false;

    WebInspector.settings.userAgent.addChangeListener(this._userAgentChanged, this);
    WebInspector.settings.deviceMetrics.addChangeListener(this._deviceMetricsChanged, this);
    WebInspector.settings.deviceFitWindow.addChangeListener(this._deviceMetricsChanged, this);
    WebInspector.settings.geolocationOverride.addChangeListener(this._geolocationPositionChanged, this);
    WebInspector.settings.deviceOrientationOverride.addChangeListener(this._deviceOrientationChanged, this);
}

/**
 * @constructor
 * @param {number} width
 * @param {number} height
 * @param {number} fontScaleFactor
 */
WebInspector.UserAgentSupport.DeviceMetrics = function(width, height, fontScaleFactor)
{
    this.width = width;
    this.height = height;
    this.fontScaleFactor = fontScaleFactor;
}

/**
 * @return {WebInspector.UserAgentSupport.DeviceMetrics}
 */
WebInspector.UserAgentSupport.DeviceMetrics.parseSetting = function(value)
{
    if (value) {
        var splitMetrics = value.split("x");
        if (splitMetrics.length === 3)
            return new WebInspector.UserAgentSupport.DeviceMetrics(parseInt(splitMetrics[0], 10), parseInt(splitMetrics[1], 10), parseFloat(splitMetrics[2]));
    }
    return new WebInspector.UserAgentSupport.DeviceMetrics(0, 0, 1);
}

/**
 * @return {?WebInspector.UserAgentSupport.DeviceMetrics}
 */
WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput = function(widthString, heightString, fontScaleFactorString)
{
    function isUserInputValid(value, isInteger)
    {
        if (!value)
            return true;
        return isInteger ? /^[0]*[1-9][\d]*$/.test(value) : /^[0]*([1-9][\d]*(\.\d+)?|\.\d+)$/.test(value);
    }

    if (!widthString ^ !heightString)
        return null;

    var isWidthValid = isUserInputValid(widthString, true);
    var isHeightValid = isUserInputValid(heightString, true);
    var isFontScaleFactorValid = isUserInputValid(fontScaleFactorString, false);

    if (!isWidthValid && !isHeightValid && !isFontScaleFactorValid)
        return null;

    var width = isWidthValid ? parseInt(widthString || "0", 10) : -1;
    var height = isHeightValid ? parseInt(heightString || "0", 10) : -1;
    var fontScaleFactor = isFontScaleFactorValid ? parseFloat(fontScaleFactorString) : -1;

    return new WebInspector.UserAgentSupport.DeviceMetrics(width, height, fontScaleFactor);
}

WebInspector.UserAgentSupport.DeviceMetrics.prototype = {
    /**
     * @return {boolean}
     */
    isValid: function()
    {
        return this.isWidthValid() && this.isHeightValid() && this.isFontScaleFactorValid();
    },

    /**
     * @return {boolean}
     */
    isWidthValid: function()
    {
        return this.width >= 0;
    },

    /**
     * @return {boolean}
     */
    isHeightValid: function()
    {
        return this.height >= 0;
    },

    /**
     * @return {boolean}
     */
    isFontScaleFactorValid: function()
    {
        return this.fontScaleFactor > 0;
    },

    /**
     * @return {string}
     */
    toSetting: function()
    {
        if (!this.isValid())
            return "";

        return this.width && this.height ? this.width + "x" + this.height + "x" + this.fontScaleFactor : "";
    },

    /**
     * @return {string}
     */
    widthToInput: function()
    {
        return this.isWidthValid() && this.width ? String(this.width) : "";
    },

    /**
     * @return {string}
     */
    heightToInput: function()
    {
        return this.isHeightValid() && this.height ? String(this.height) : "";
    },

    /**
     * @return {string}
     */
    fontScaleFactorToInput: function()
    {
        return this.isFontScaleFactorValid() && this.fontScaleFactor ? String(this.fontScaleFactor) : "";
    }
}

/**
 * @constructor
 * @param {number} latitude
 * @param {number} longitude
 */
WebInspector.UserAgentSupport.GeolocationPosition = function(latitude, longitude, error)
{
    this.latitude = latitude;
    this.longitude = longitude;
    this.error = error;
}

WebInspector.UserAgentSupport.GeolocationPosition.prototype = {
    /**
     * @return {string}
     */
    toSetting: function()
    {
        return (typeof this.latitude === "number" && typeof this.longitude === "number" && typeof this.error === "string") ? this.latitude + "@" + this.longitude + ":" + this.error : "";
    }
}

/**
 * @return {WebInspector.UserAgentSupport.GeolocationPosition}
 */
WebInspector.UserAgentSupport.GeolocationPosition.parseSetting = function(value)
{
    if (value) {
        var splitError = value.split(":");
        if (splitError.length === 2) {
            var splitPosition = splitError[0].split("@")
            if (splitPosition.length === 2)
                return new WebInspector.UserAgentSupport.GeolocationPosition(parseFloat(splitPosition[0]), parseFloat(splitPosition[1]), splitError[1]);
        }
    }
    return new WebInspector.UserAgentSupport.GeolocationPosition(0, 0, "");
}

/**
 * @return {?WebInspector.UserAgentSupport.GeolocationPosition}
 */
WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput = function(latitudeString, longitudeString, errorStatus)
{
    function isUserInputValid(value)
    {
        if (!value)
            return true;
        return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
    }

    if (!latitudeString ^ !latitudeString)
        return null;

    var isLatitudeValid = isUserInputValid(latitudeString);
    var isLongitudeValid = isUserInputValid(longitudeString);

    if (!isLatitudeValid && !isLongitudeValid)
        return null;

    var latitude = isLatitudeValid ? parseFloat(latitudeString) : -1;
    var longitude = isLongitudeValid ? parseFloat(longitudeString) : -1;

    return new WebInspector.UserAgentSupport.GeolocationPosition(latitude, longitude, errorStatus ? "PositionUnavailable" : "");
}

WebInspector.UserAgentSupport.GeolocationPosition.clearGeolocationOverride = function()
{
    PageAgent.clearGeolocationOverride();
}

/**
 * @constructor
 * @param {number} alpha
 * @param {number} beta
 * @param {number} gamma
 */
WebInspector.UserAgentSupport.DeviceOrientation = function(alpha, beta, gamma)
{
    this.alpha = alpha;
    this.beta = beta;
    this.gamma = gamma;
}

WebInspector.UserAgentSupport.DeviceOrientation.prototype = {
    /**
     * @return {string}
     */
    toSetting: function()
    {
        return JSON.stringify(this);
    }
}

/**
 * @return {WebInspector.UserAgentSupport.DeviceOrientation}
 */
WebInspector.UserAgentSupport.DeviceOrientation.parseSetting = function(value)
{
    if (value) {
        var jsonObject = JSON.parse(value);
        return new WebInspector.UserAgentSupport.DeviceOrientation(jsonObject.alpha, jsonObject.beta, jsonObject.gamma);
    }
    return new WebInspector.UserAgentSupport.DeviceOrientation(0, 0, 0);
}

/**
 * @return {?WebInspector.UserAgentSupport.DeviceOrientation}
 */
WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput = function(alphaString, betaString, gammaString)
{
    function isUserInputValid(value)
    {
        if (!value)
            return true;
        return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
    }

    if (!alphaString ^ !betaString ^ !gammaString)
        return null;

    var isAlphaValid = isUserInputValid(alphaString);
    var isBetaValid = isUserInputValid(betaString);
    var isGammaValid = isUserInputValid(gammaString);

    if (!isAlphaValid && !isBetaValid && !isGammaValid)
        return null;

    var alpha = isAlphaValid ? parseFloat(alphaString) : -1;
    var beta = isBetaValid ? parseFloat(betaString) : -1;
    var gamma = isGammaValid ? parseFloat(gammaString) : -1;

    return new WebInspector.UserAgentSupport.DeviceOrientation(alpha, beta, gamma);
}

WebInspector.UserAgentSupport.DeviceOrientation.clearDeviceOrientationOverride = function()
{
    PageAgent.clearDeviceOrientationOverride();
}

WebInspector.UserAgentSupport.prototype = {
    toggleUserAgentOverride: function(enabled)
    {
        if (enabled === this._userAgentOverrideEnabled)
            return;
        this._userAgentOverrideEnabled = enabled;
        this._userAgentChanged();
    },

    toggleDeviceMetricsOverride: function(enabled)
    {
        if (enabled === this._deviceMetricsOverrideEnabled)
            return;
        this._deviceMetricsOverrideEnabled = enabled;
        this._deviceMetricsChanged();
    },

    toggleGeolocationPositionOverride: function(enabled)
    {
        if (enabled === this._geolocationPositionOverrideEnabled)
            return;
        this._geolocationPositionOverrideEnabled = enabled;
        this._geolocationPositionChanged();
    },

    toggleDeviceOrientationOverride: function(enabled)
    {
        if (enabled === this._deviceOrientationOverrideEnabled)
            return;
        this._deviceOrientationOverrideEnabled = enabled;
        this._deviceOrientationChanged();
    },

    _userAgentChanged: function()
    {
        NetworkAgent.setUserAgentOverride(this._userAgentOverrideEnabled ? WebInspector.settings.userAgent.get() : "");
    },

    _deviceMetricsChanged: function()
    {
        var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(this._deviceMetricsOverrideEnabled ? WebInspector.settings.deviceMetrics.get() : "");
        if (metrics.isValid())
            PageAgent.setDeviceMetricsOverride(metrics.width, metrics.height, metrics.fontScaleFactor, WebInspector.settings.deviceFitWindow.get());
    },

    _geolocationPositionChanged: function()
    {
        if (!this._geolocationPositionOverrideEnabled) {
            PageAgent.clearGeolocationOverride();
            return;
        }
        var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseSetting(WebInspector.settings.geolocationOverride.get());
        if (geolocation.error)
            PageAgent.setGeolocationOverride();
        else
            PageAgent.setGeolocationOverride(geolocation.latitude, geolocation.longitude, 150);
    },

    _deviceOrientationChanged: function()
    {
        if (!this._deviceOrientationOverrideEnabled) {
            PageAgent.clearDeviceOrientationOverride();
            return;
        }
        var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseSetting(WebInspector.settings.deviceOrientationOverride.get());
        PageAgent.setDeviceOrientationOverride(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
    }
}


/**
 * @type {WebInspector.UserAgentSupport} 
 */
WebInspector.userAgentSupport;

/* Database.js */

/*
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @param {WebInspector.DatabaseModel} model
 */
WebInspector.Database = function(model, id, domain, name, version)
{
    this._model = model;
    this._id = id;
    this._domain = domain;
    this._name = name;
    this._version = version;
}

WebInspector.Database.prototype = {
    /** @return {string} */
    get id()
    {
        return this._id;
    },

    /** @return {string} */
    get name()
    {
        return this._name;
    },

    set name(x)
    {
        this._name = x;
    },

    /** @return {string} */
    get version()
    {
        return this._version;
    },

    set version(x)
    {
        this._version = x;
    },

    /** @return {string} */
    get domain()
    {
        return this._domain;
    },

    set domain(x)
    {
        this._domain = x;
    },

    /**
     * @param {function(Array.<string>)} callback
     */
    getTableNames: function(callback)
    {
        function sortingCallback(error, names)
        {
            if (!error)
                callback(names.sort());
        }
        DatabaseAgent.getDatabaseTableNames(this._id, sortingCallback);
    },

    /**
     * @param {string} query
     * @param {function(Array.<string>=, Array.<*>=)} onSuccess
     * @param {function(string)} onError
     */
    executeSql: function(query, onSuccess, onError)
    {
        /**
         * @param {?Protocol.Error} error
         * @param {Array.<string>=} columnNames
         * @param {Array.<*>=} values
         * @param {DatabaseAgent.Error=} errorObj
         */
        function callback(error, columnNames, values, errorObj)
        {
            if (error) {
                onError(error);
                return;
            }
            if (errorObj) {
                var message;
                if (errorObj.message)
                    message = errorObj.message;
                else if (errorObj.code == 2)
                    message = WebInspector.UIString("Database no longer has expected version.");
                else
                    message = WebInspector.UIString("An unexpected error %s occurred.", errorObj.code);
                onError(message);
                return;
            }
            onSuccess(columnNames, values);
        }
        DatabaseAgent.executeSQL(this._id, query, callback.bind(this));
    }
}

/**
 * @constructor
 * @extends {WebInspector.Object}
 */
WebInspector.DatabaseModel = function()
{
    this._databases = [];
    InspectorBackend.registerDatabaseDispatcher(new WebInspector.DatabaseDispatcher(this));
    DatabaseAgent.enable();
}

WebInspector.DatabaseModel.Events = {
    DatabaseAdded: "DatabaseAdded"
}

WebInspector.DatabaseModel.prototype = {
    /**
     * @return {Array.<WebInspector.Database>}
     */
    databases: function()
    {
        var result = [];
        for (var databaseId in this._databases)
            result.push(this._databases[databaseId]);
        return result;
    },

    /**
     * @param {DatabaseAgent.DatabaseId} databaseId
     * @return {WebInspector.Database}
     */
    databaseForId: function(databaseId)
    {
        return this._databases[databaseId];
    },

    /**
     * @param {WebInspector.Database} database
     */
    _addDatabase: function(database)
    {
        this._databases.push(database);
        this.dispatchEventToListeners(WebInspector.DatabaseModel.Events.DatabaseAdded, database);
    },

    __proto__: WebInspector.Object.prototype
}

/**
 * @constructor
 * @implements {DatabaseAgent.Dispatcher}
 * @param {WebInspector.DatabaseModel} model
 */
WebInspector.DatabaseDispatcher = function(model)
{
    this._model = model;
}

WebInspector.DatabaseDispatcher.prototype = {
    /**
     * @param {DatabaseAgent.Database} payload
     */
    addDatabase: function(payload)
    {
        this._model._addDatabase(new WebInspector.Database(
            this._model,
            payload.id,
            payload.domain,
            payload.name,
            payload.version));
    }
}

/**
 * @type {WebInspector.DatabaseModel}
 */
WebInspector.databaseModel = null;

/* DOMStorage.js */

/*
 * Copyright (C) 2008 Nokia Inc.  All rights reserved.
 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @param {string} securityOrigin
 * @param {boolean} isLocalStorage
 */
WebInspector.DOMStorage = function(securityOrigin, isLocalStorage)
{
    this._securityOrigin = securityOrigin;
    this._isLocalStorage = isLocalStorage;
}

/**
 * @param {string} securityOrigin
 * @param {boolean} isLocalStorage
 * @return {DOMStorageAgent.StorageId}
 */
WebInspector.DOMStorage.storageId = function(securityOrigin, isLocalStorage)
{
    return { securityOrigin: securityOrigin, isLocalStorage: isLocalStorage };
}

WebInspector.DOMStorage.prototype = {

    /** @return {DOMStorageAgent.StorageId} */
    get id()
    {
        return WebInspector.DOMStorage.storageId(this._securityOrigin, this._isLocalStorage);
    },

    /** @return {string} */
    get securityOrigin()
    {
        return this._securityOrigin;
    },

    /** @return {boolean} */
    get isLocalStorage()
    {
        return this._isLocalStorage;
    },

    /**
     * @param {function(?Protocol.Error, Array.<DOMStorageAgent.Item>):void=} callback
     */
    getItems: function(callback)
    {
        DOMStorageAgent.getDOMStorageItems(this.id, callback);
    },

    /**
     * @param {string} key
     * @param {string} value
     * @param {function(?Protocol.Error):void=} callback
     */
    setItem: function(key, value, callback)
    {
        DOMStorageAgent.setDOMStorageItem(this.id, key, value, callback);
    },

    /**
     * @param {string} key
     * @param {function(?Protocol.Error):void=} callback
     */
    removeItem: function(key, callback)
    {
        DOMStorageAgent.removeDOMStorageItem(this.id, key, callback);
    }
}

/**
 * @constructor
 * @extends {WebInspector.Object}
 */
WebInspector.DOMStorageModel = function()
{
    this._storages = {};
    InspectorBackend.registerDOMStorageDispatcher(new WebInspector.DOMStorageDispatcher(this));
    DOMStorageAgent.enable();
    WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
    WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
}

WebInspector.DOMStorageModel.Events = {
    DOMStorageAdded: "DOMStorageAdded",
    DOMStorageRemoved: "DOMStorageRemoved",
    DOMStorageItemsCleared: "DOMStorageItemsCleared",
    DOMStorageItemRemoved: "DOMStorageItemRemoved",
    DOMStorageItemAdded: "DOMStorageItemAdded",
    DOMStorageItemUpdated: "DOMStorageItemUpdated"
}

WebInspector.DOMStorageModel.prototype = {

    /**
     * @param {WebInspector.Event} event
     */
    _securityOriginAdded: function(event)
    {
        var securityOrigin = /** @type {string} */ (event.data);
        var localStorageKey = this._storageKey(securityOrigin, true);
        console.assert(!this._storages[localStorageKey]);
        var localStorage = new WebInspector.DOMStorage(securityOrigin, true);
        this._storages[localStorageKey] = localStorage;
        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded, localStorage);

        var sessionStorageKey = this._storageKey(securityOrigin, false);
        console.assert(!this._storages[sessionStorageKey]);
        var sessionStorage = new WebInspector.DOMStorage(securityOrigin, false);
        this._storages[sessionStorageKey] = sessionStorage;
        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded, sessionStorage);
    },

    /**
     * @param {WebInspector.Event} event
     */
    _securityOriginRemoved: function(event)
    {
        var securityOrigin = /** @type {string} */ (event.data);
        var localStorageKey = this._storageKey(securityOrigin, true);
        var localStorage = this._storages[localStorageKey];
        console.assert(localStorage);
        delete this._storages[localStorageKey];
        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, localStorage);

        var sessionStorageKey = this._storageKey(securityOrigin, false);
        var sessionStorage = this._storages[sessionStorageKey];
        console.assert(sessionStorage);
        delete this._storages[sessionStorageKey];
        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, sessionStorage);
    },

    /**
     * @param {string} securityOrigin
     * @param {boolean} isLocalStorage
     * @return {string}
     */
    _storageKey: function(securityOrigin, isLocalStorage)
    {
        return JSON.stringify(WebInspector.DOMStorage.storageId(securityOrigin, isLocalStorage));
    },

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     */
    _domStorageItemsCleared: function(storageId)
    {
        var domStorage = this.storageForId(storageId);
        var storageData = {
            storage: domStorage
        };
        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageItemsCleared, storageData);
    },

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     * @param {string} key
     */
    _domStorageItemRemoved: function(storageId, key)
    {
        var domStorage = this.storageForId(storageId);
        var storageData = {
            storage: domStorage,
            key: key
        };
        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageItemRemoved, storageData);
    },

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     * @param {string} key
     * @param {string} newValue
     */
    _domStorageItemAdded: function(storageId, key, newValue)
    {
        var domStorage = this.storageForId(storageId);
        var storageData = {
            storage: domStorage,
            key: key,
            newValue: newValue
        };
        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageItemAdded, storageData);
    },

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     * @param {string} key
     * @param {string} oldValue
     * @param {string} newValue
     */
    _domStorageItemUpdated: function(storageId, key, oldValue, newValue)
    {
        var domStorage = this._storages[storageId];
        var storageData = {
            storage: domStorage,
            key: key,
            oldValue: oldValue,
            newValue: newValue
        };
        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageItemUpdated, storageData);
    },

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     * @return {WebInspector.DOMStorage}
     */
    storageForId: function(storageId)
    {
        return this._storages[JSON.stringify(storageId)];
    },

    /**
     * @return {Array.<WebInspector.DOMStorage>}
     */
    storages: function()
    {
        var result = [];
        for (var id in this._storages)
            result.push(this._storages[id]);
        return result;
    },

    __proto__: WebInspector.Object.prototype
}

/**
 * @constructor
 * @implements {DOMStorageAgent.Dispatcher}
 * @param {WebInspector.DOMStorageModel} model
 */
WebInspector.DOMStorageDispatcher = function(model)
{
    this._model = model;
}

WebInspector.DOMStorageDispatcher.prototype = {

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     */
    domStorageItemsCleared: function(storageId)
    {
        this._model._domStorageItemsCleared(storageId);
    },

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     * @param {string} key
     */
    domStorageItemRemoved: function(storageId, key)
    {
        this._model._domStorageItemRemoved(storageId, key);
    },

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     * @param {string} key
     * @param {string} newValue
     */
    domStorageItemAdded: function(storageId, key, newValue)
    {
        this._model._domStorageItemAdded(storageId, key, newValue);
    },

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     * @param {string} key
     * @param {string} oldValue
     * @param {string} newValue
     */
    domStorageItemUpdated: function(storageId, key, oldValue, newValue)
    {
        this._model._domStorageItemUpdated(storageId, key, oldValue, newValue);
    },
}

/**
 * @type {WebInspector.DOMStorageModel}
 */
WebInspector.domStorageModel = null;

/* DataGrid.js */

/*
 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.         IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.View}
 * @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} columnsArray
 * @param {function(WebInspector.DataGridNode, string, string, string)=} editCallback
 * @param {function(WebInspector.DataGridNode)=} deleteCallback
 * @param {function()=} refreshCallback
 * @param {function(!WebInspector.ContextMenu, WebInspector.DataGridNode)=} contextMenuCallback
 */
WebInspector.DataGrid = function(columnsArray, editCallback, deleteCallback, refreshCallback, contextMenuCallback)
{
    WebInspector.View.call(this);
    this.registerRequiredCSS("dataGrid.css");

    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);

    // FIXME: Add a createCallback which is different from editCallback and has different
    // behavior when creating a new node.
    if (editCallback)
        this._dataTable.addEventListener("dblclick", this._ondblclick.bind(this), false);
    this._editCallback = editCallback;
    this._deleteCallback = deleteCallback;
    this._refreshCallback = refreshCallback;
    this._contextMenuCallback = contextMenuCallback;

    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");
    columnGroup.span = columnsArray.length;

    var fillerRow = document.createElement("tr");
    fillerRow.className = "filler";

    this._columnsArray = columnsArray;
    this.columns = {};

    for (var i = 0; i < columnsArray.length; ++i) {
        var column = columnsArray[i];
        column.ordinal = i;
        var columnIdentifier = column.identifier = column.id || i;
        this.columns[columnIdentifier] = column;
        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");
        }

        headerRow.appendChild(cell);
        fillerRow.createChild("td", columnIdentifier + "-column");
    }

    headerRow.createChild("th", "corner");
    fillerRow.createChild("td", "corner");
    columnGroup.createChild("col", "corner");

    this._headerTableColumnGroup = columnGroup;
    this._headerTable.appendChild(this._headerTableColumnGroup);
    this.headerTableBody.appendChild(headerRow);

    this._dataTableColumnGroup = columnGroup.cloneNode(true);
    this._dataTable.appendChild(this._dataTableColumnGroup);
    this.dataTableBody.appendChild(fillerRow);

    this.selectedNode = null;
    this.expandNodesWhenArrowing = false;
    this.setRootNode(new WebInspector.DataGridNode());
    this.indentWidth = 15;
    this.resizers = [];
    this._columnWidthsInitialized = false;
}

/** @typedef {{id: ?string, editable: boolean, longText: ?boolean, sort: WebInspector.DataGrid.Order, sortable: boolean, align: WebInspector.DataGrid.Align}} */
WebInspector.DataGrid.ColumnDescriptor;

WebInspector.DataGrid.Events = {
    SelectedNode: "SelectedNode",
    DeselectedNode: "DeselectedNode",
    SortingChanged: "SortingChanged",
    ColumnsResized: "ColumnsResized"
}

/** @enum {string} */
WebInspector.DataGrid.Order = {
    Ascending: "ascending",
    Descending: "descending"
}

/** @enum {string} */
WebInspector.DataGrid.Align = {
    Center: "center",
    Right: "right"
}

/**
 * @param {Array.<string>} columnNames
 * @param {Array.<string>} values
 */
WebInspector.DataGrid.createSortableDataGrid = function(columnNames, values)
{
    var numColumns = columnNames.length;
    if (!numColumns)
        return null;

    var columns = [];
    for (var i = 0; i < columnNames.length; ++i)
        columns.push({title: columnNames[i], width: columnNames[i].length, sortable: true});

    var nodes = [];
    for (var i = 0; i < values.length / numColumns; ++i) {
        var data = {};
        for (var j = 0; j < columnNames.length; ++j)
            data[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.rootNode().appendChild(nodes[i]);

    dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, sortDataGrid, this);

    function sortDataGrid()
    {
        var nodes = dataGrid._rootNode.children.slice();
        var sortColumnIdentifier = dataGrid.sortColumnIdentifier();
        var sortDirection = dataGrid.isSortOrderAscending() ? 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];
            item1 = item1 instanceof Node ? item1.textContent : String(item1);
            item2 = item2 instanceof Node ? item2.textContent : String(item2);

            var comparison;
            if (columnIsNumeric) {
                // Sort numbers based on comparing their values rather than a lexicographical comparison.
                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.rootNode().removeChildren();
        for (var i = 0; i < nodes.length; i++)
            dataGrid._rootNode.appendChild(nodes[i]);
    }
    return dataGrid;
}

WebInspector.DataGrid.prototype = {
    /**
     * @param {!WebInspector.DataGridNode} rootNode
     */
    setRootNode: function(rootNode)
    {
        if (this._rootNode) {
            this._rootNode.removeChildren();
            this._rootNode.dataGrid = null;
            this._rootNode._isRoot = false;
        }
        /** @type {!WebInspector.DataGridNode} */
        this._rootNode = rootNode;
        rootNode._isRoot = true;
        rootNode.hasChildren = false;
        rootNode._expanded = true;
        rootNode._revealed = true;
        rootNode.dataGrid = this;
    },

    /**
     * @return {!WebInspector.DataGridNode}
     */
    rootNode: function()
    {
        return this._rootNode;
    },

    _ondblclick: function(event)
    {
        if (this._editing || this._editingNode)
            return;

        var columnIdentifier = this.columnIdentifierFromNode(event.target);
        if (!columnIdentifier || !this.columns[columnIdentifier].editable)
            return;
        this._startEditing(event.target);
    },

    /**
     * @param {!WebInspector.DataGridNode} node
     * @param {number} columnOrdinal
     */
    _startEditingColumnOfDataGridNode: function(node, columnOrdinal)
    {
        this._editing = true;
        /** @type {WebInspector.DataGridNode} */
        this._editingNode = node;
        this._editingNode.select();

        var element = this._editingNode._element.children[columnOrdinal];
        WebInspector.startEditing(element, this._startEditingConfig(element));
        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;
        }

        // Force editing the 1st column when editing the creation node
        if (this._editingNode.isCreationNode)
            return this._startEditingColumnOfDataGridNode(this._editingNode, this._nextEditableColumn(-1));

        this._editing = true;
        WebInspector.startEditing(element, this._startEditingConfig(element));

        window.getSelection().setBaseAndExtent(element, 0, element, 1);
    },

    renderInline: function()
    {
        this.element.addStyleClass("inline");
    },

    _startEditingConfig: function(element)
    {
        return new WebInspector.EditingConfig(this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
    },

    _editingCommitted: function(element, newText, oldText, context, moveDirection)
    {
        var columnIdentifier = this.columnIdentifierFromNode(element);
        if (!columnIdentifier) {
            this._editingCancelled(element);
            return;
        }
        var columnOrdinal = this.columns[columnIdentifier].ordinal;
        var textBeforeEditing = this._editingNode.data[columnIdentifier];
        var currentEditingNode = this._editingNode;

        function moveToNextIfNeeded(wasChange) {
            if (!moveDirection)
                return;

            if (moveDirection === "forward") {
            var firstEditableColumn = this._nextEditableColumn(-1);
                if (currentEditingNode.isCreationNode && columnOrdinal === firstEditableColumn && !wasChange)
                    return;

                var nextEditableColumn = this._nextEditableColumn(columnOrdinal);
                if (nextEditableColumn !== -1)
                    return this._startEditingColumnOfDataGridNode(currentEditingNode, nextEditableColumn);

                var nextDataGridNode = currentEditingNode.traverseNextNode(true, null, true);
                if (nextDataGridNode)
                    return this._startEditingColumnOfDataGridNode(nextDataGridNode, firstEditableColumn);
                if (currentEditingNode.isCreationNode && wasChange) {
                    this.addCreationNode(false);
                    return this._startEditingColumnOfDataGridNode(this.creationNode, firstEditableColumn);
                }
                return;
            }

            if (moveDirection === "backward") {
                var prevEditableColumn = this._nextEditableColumn(columnOrdinal, true);
                if (prevEditableColumn !== -1)
                    return this._startEditingColumnOfDataGridNode(currentEditingNode, prevEditableColumn);

                var lastEditableColumn = this._nextEditableColumn(this._columnsArray.length, true);
                var nextDataGridNode = currentEditingNode.traversePreviousNode(true, true);
                if (nextDataGridNode)
                    return this._startEditingColumnOfDataGridNode(nextDataGridNode, lastEditableColumn);
                return;
            }
        }

        if (textBeforeEditing == newText) {
            this._editingCancelled(element);
            moveToNextIfNeeded.call(this, false);
            return;
        }

        // Update the text in the datagrid that we typed
        this._editingNode.data[columnIdentifier] = newText;

        // Make the callback - expects an editing node (table row), the column number that is being edited,
        // the text that used to be there, and the new text.
        this._editCallback(this._editingNode, columnIdentifier, textBeforeEditing, newText);

        if (this._editingNode.isCreationNode)
            this.addCreationNode(false);

        this._editingCancelled(element);
        moveToNextIfNeeded.call(this, true);
    },

    _editingCancelled: function(element)
    {
        delete this._editing;
        this._editingNode = null;
    },

    /**
     * @param {number} columnOrdinal
     * @param {boolean=} moveBackward
     * @return {number}
     */
    _nextEditableColumn: function(columnOrdinal, moveBackward)
    {
        var increment = moveBackward ? -1 : 1;
        var columns = this._columnsArray;
        for (var i = columnOrdinal + increment; (i >= 0) && (i < columns.length); i += increment) {
            if (columns[i].editable)
                return i;
        }
        return -1;
    },

    /**
     * @return {?string}
     */
    sortColumnIdentifier: function()
    {
        if (!this._sortColumnCell)
            return null;
        return this._sortColumnCell.columnIdentifier;
    },

    /**
     * @return {?string}
     */
    sortOrder: function()
    {
        if (!this._sortColumnCell || this._sortColumnCell.hasStyleClass("sort-ascending"))
            return WebInspector.DataGrid.Order.Ascending;
        if (this._sortColumnCell.hasStyleClass("sort-descending"))
            return WebInspector.DataGrid.Order.Descending;
        return null;
    },

    /**
     * @return {boolean}
     */
    isSortOrderAscending: function()
    {
        return !this._sortColumnCell || this._sortColumnCell.hasStyleClass("sort-ascending");
    },

    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;
    },

    /**
     * @param {Array.<number>} widths
     * @param {number} minPercent
     * @param {number=} maxPercent
     */
    _autoSizeWidths: function(widths, minPercent, maxPercent)
    {
        if (minPercent)
            minPercent = Math.min(minPercent, Math.floor(100 / widths.length));
        var totalWidth = 0;
        for (var i = 0; i < widths.length; ++i)
            totalWidth += widths[i];
        var totalPercentWidth = 0;
        for (var i = 0; i < widths.length; ++i) {
            var width = Math.round(100 * widths[i] / totalWidth);
            if (minPercent && width < minPercent)
                width = minPercent;
            else if (maxPercent && width > maxPercent)
                width = maxPercent;
            totalPercentWidth += width;
            widths[i] = width;
        }
        var recoupPercent = totalPercentWidth - 100;

        while (minPercent && recoupPercent > 0) {
            for (var i = 0; i < widths.length; ++i) {
                if (widths[i] > minPercent) {
                    --widths[i];
                    --recoupPercent;
                    if (!recoupPercent)
                        break;
                }
            }
        }

        while (maxPercent && recoupPercent < 0) {
            for (var i = 0; i < widths.length; ++i) {
                if (widths[i] < maxPercent) {
                    ++widths[i];
                    ++recoupPercent;
                    if (!recoupPercent)
                        break;
                }
            }
        }

        return widths;
    },

    /**
     * @param {number} minPercent
     * @param {number=} maxPercent
     * @param {number=} maxDescentLevel
     */
    autoSizeColumns: function(minPercent, maxPercent, maxDescentLevel)
    {
        var widths = [];
        for (var i = 0; i < this._columnsArray.length; ++i)
            widths.push((this._columnsArray[i].title || "").length);

        maxDescentLevel = maxDescentLevel || 0;
        var children = this._enumerateChildren(this._rootNode, [], maxDescentLevel + 1);
        for (var i = 0; i < children.length; ++i) {
            var node = children[i];
            for (var j = 0; j < this._columnsArray.length; ++j) {
                var text = node.data[this._columnsArray[j].identifier] || "";
                if (text.length > widths[j])
                    widths[j] = text.length;
            }
        }

        widths = this._autoSizeWidths(widths, minPercent, maxPercent);

        for (var i = 0; i < this._columnsArray.length; ++i)
            this._columnsArray[i].element.style.width = widths[i] + "%";
        this._columnWidthsInitialized = false;
        this.updateWidths();
    },

    _enumerateChildren: function(rootNode, result, maxLevel)
    {
        if (!rootNode._isRoot)
            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;
    },

    onResize: function()
    {
        this.updateWidths();
    },

    // Updates the widths of the table, including the positions of the column
    // resizers.
    //
    // IMPORTANT: This function MUST be called once after the element of the
    // DataGrid is attached to its parent element and every subsequent time the
    // width of the parent element is changed in order to make it possible to
    // resize the columns.
    //
    // If this function is not called after the DataGrid is attached to its
    // parent element, then the DataGrid's columns will not be resizable.
updateWidths: function()
{
var headerTableColumns = this._headerTableColumnGroup.children;

var tableWidth = this._dataTable.offsetWidth;
var numColumns = headerTableColumns.length - 1; 


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(WebInspector.DataGrid.Events.ColumnsResized);
},


setName: function(name)
{
this._columnWeightsSetting = WebInspector.settings.createSetting("dataGrid-" + name + "-columnWeights", {});
this._loadColumnWeights();
},

_loadColumnWeights: function()
{
if (!this._columnWeightsSetting)
return;
var weights = this._columnWeightsSetting.get();
for (var i = 0; i < this._columnsArray.length; ++i) {
var column = this._columnsArray[i];
var weight = weights[column.identifier];
if (weight)
column.weight = weight;
}
this.applyColumnWeights();
},

_saveColumnWeights: function()
{
if (!this._columnWeightsSetting)
return;
var weights = {};
for (var i = 0; i < this._columnsArray.length; ++i) {
var column = this._columnsArray[i];
weights[column.identifier] = column.weight;
}
this._columnWeightsSetting.set(weights);
},

wasShown: function()
{
this._loadColumnWeights();
},

applyColumnWeights: function()
{
var sumOfWeights = 0.0;
for (var i = 0; i < this._columnsArray.length; ++i) {
var column = this._columnsArray[i];
if (this.isColumnVisible(column))
sumOfWeights += column.weight;
}
var factor = 100 / sumOfWeights;

for (var i = 0; i < this._columnsArray.length; ++i) {
var column = this._columnsArray[i];
var width = this.isColumnVisible(column) ? ((factor * column.weight) + "%"): "0%";
this._headerTableColumnGroup.children[i].style.width = width;
this._dataTableColumnGroup.children[i].style.width = width;
}

this._positionResizers();
this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);
},


isColumnVisible: function(column)
{
return !column.hidden;
},


setColumnVisible: function(columnIdentifier, visible)
{
if (visible === !this.columns[columnIdentifier].hidden)
return;

this.columns[columnIdentifier].hidden = !visible;
this.element.enableStyleClass("hide-" + columnIdentifier + "-column", !visible);
},

get scrollContainer()
{
return this._scrollContainer;
},

isScrolledToLastRow: function()
{
return this._scrollContainer.isScrolledToBottom();
},

scrollToLastRow: function()
{
this._scrollContainer.scrollTop = this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight;
},

_positionResizers: function()
{
var headerTableColumns = this._headerTableColumnGroup.children;
var numColumns = headerTableColumns.length - 1; 
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");

WebInspector.installDragHandle(resizer, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "col-resize");
this.element.appendChild(resizer);
this.resizers[i] = resizer;
}




left += this.headerTableBody.rows[0].cells[i].offsetWidth;

if (!this._columnsArray[i].hidden) {
resizer.style.removeProperty("display");
if (resizer._position !== left) {
resizer._position = left;
resizer.style.left = left + "px";
}
resizer.leftNeighboringColumnIndex = i;
if (previousResizer)
previousResizer.rightNeighboringColumnIndex = i;
previousResizer = resizer;
} else {
if (previousResizer && previousResizer._position !== left) {
previousResizer._position = left;
previousResizer.style.left = left + "px";
}
resizer.style.setProperty("display", "none");
resizer.leftNeighboringColumnIndex = 0;
resizer.rightNeighboringColumnIndex = 0;
}
}
if (previousResizer)
previousResizer.rightNeighboringColumnIndex = numColumns - 1;
},

addCreationNode: function(hasChildren)
{
if (this.creationNode)
this.creationNode.makeNormal();

var emptyData = {};
for (var column in this.columns)
emptyData[column] = null;
this.creationNode = new WebInspector.CreationDataGridNode(emptyData, hasChildren);
this.rootNode().appendChild(this.creationNode);
},

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(true);
handled = nextSelectedNode ? true : false;
} else if (event.keyIdentifier === "Down" && !event.altKey) {
nextSelectedNode = this.selectedNode.traverseNextNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traverseNextNode(true);
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._isRoot) {
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);
this.changeNodeAfterDeletion();
}
} else if (isEnterKey(event)) {
if (this._editCallback) {
handled = true;
this._startEditing(this.selectedNode._element.children[this._nextEditableColumn(-1)]);
}
}

if (nextSelectedNode) {
nextSelectedNode.reveal();
nextSelectedNode.select();
}

if (handled)
event.consume(true);
},

changeNodeAfterDeletion: function()
{
var nextSelectedNode = this.selectedNode.traverseNextNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traverseNextNode(true);

if (!nextSelectedNode || nextSelectedNode.isCreationNode) {
nextSelectedNode = this.selectedNode.traversePreviousNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traversePreviousNode(true);
}

if (nextSelectedNode) {
nextSelectedNode.reveal();
nextSelectedNode.select();
}
},


dataGridNodeFromNode: function(target)
{
var rowElement = target.enclosingNodeOrSelfWithNodeName("tr");
return rowElement && rowElement._dataGridNode;
},


columnIdentifierFromNode: function(target)
{
var cellElement = target.enclosingNodeOrSelfWithNodeName("td");
return cellElement && cellElement.columnIdentifier_;
},

_clickInHeaderCell: function(event)
{
var cell = event.target.enclosingNodeOrSelfWithNodeName("th");
if (!cell || !cell.columnIdentifier || !cell.hasStyleClass("sortable"))
return;

var sortOrder = WebInspector.DataGrid.Order.Ascending;
if ((cell === this._sortColumnCell) && this.isSortOrderAscending())
sortOrder = WebInspector.DataGrid.Order.Descending;

if (this._sortColumnCell)
this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+");
this._sortColumnCell = cell;

cell.addStyleClass("sort-" + sortOrder);

this.dispatchEventToListeners(WebInspector.DataGrid.Events.SortingChanged);
},


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 contextMenu = new WebInspector.ContextMenu(event);

var gridNode = this.dataGridNodeFromNode(event.target);
if (this._refreshCallback && (!gridNode || gridNode !== this.creationNode))
contextMenu.appendItem(WebInspector.UIString("Refresh"), this._refreshCallback.bind(this));

if (gridNode && gridNode.selectable && !gridNode.isEventWithinDisclosureTriangle(event)) {

if (this._editCallback) {
if (gridNode === this.creationNode)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add new" : "Add New"), this._startEditing.bind(this, event.target));
else {
var columnIdentifier = this.columnIdentifierFromNode(event.target);
if (columnIdentifier && this.columns[columnIdentifier].editable)
contextMenu.appendItem(WebInspector.UIString("Edit"), this._startEditing.bind(this, event.target));
}
}
if (this._deleteCallback && gridNode !== this.creationNode)
contextMenu.appendItem(WebInspector.UIString("Delete"), this._deleteCallback.bind(this, gridNode));
if (this._contextMenuCallback)
this._contextMenuCallback(contextMenu, gridNode);
}

contextMenu.show();
},

_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();
}
},

get resizeMethod()
{
if (typeof this._resizeMethod === "undefined")
return WebInspector.DataGrid.ResizeMethod.Nearest;
return this._resizeMethod;
},

set resizeMethod(method)
{
this._resizeMethod = method;
},


_startResizerDragging: function(event)
{
this._currentResizer = event.target;
return !!this._currentResizer.rightNeighboringColumnIndex
},

_resizerDragging: function(event)
{
var resizer = this._currentResizer;
if (!resizer)
return;

var tableWidth = this._dataTable.offsetWidth; 



var dragPoint = event.clientX - this.element.totalOffsetLeft();


var leftCellIndex = resizer.leftNeighboringColumnIndex;
var rightCellIndex = resizer.rightNeighboringColumnIndex;
var firstRowCells = this.headerTableBody.rows[0].cells;
var leftEdgeOfPreviousColumn = 0;
for (var i = 0; i < leftCellIndex; i++)
leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth;


if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.Last) {
rightCellIndex = this.resizers.length;
} else if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.First) {
leftEdgeOfPreviousColumn += firstRowCells[leftCellIndex].offsetWidth - firstRowCells[0].offsetWidth;
leftCellIndex = 0;
}

var rightEdgeOfNextColumn = leftEdgeOfPreviousColumn + firstRowCells[leftCellIndex].offsetWidth + firstRowCells[rightCellIndex].offsetWidth;


var leftMinimum = leftEdgeOfPreviousColumn + this.ColumnResizePadding;
var rightMaximum = rightEdgeOfNextColumn - this.ColumnResizePadding;
if (leftMinimum > rightMaximum)
return;

dragPoint = Number.constrain(dragPoint, leftMinimum, rightMaximum);

resizer.style.left = (dragPoint - this.CenterResizerOverBorderAdjustment) + "px";

var percentLeftColumn = (((dragPoint - leftEdgeOfPreviousColumn) / tableWidth) * 100) + "%";
this._headerTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn;
this._dataTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn;

var percentRightColumn = (((rightEdgeOfNextColumn - dragPoint) / tableWidth) * 100) + "%";
this._headerTableColumnGroup.children[rightCellIndex].style.width =  percentRightColumn;
this._dataTableColumnGroup.children[rightCellIndex].style.width = percentRightColumn;

var leftColumn = this._columnsArray[leftCellIndex];
var rightColumn = this._columnsArray[rightCellIndex];
if (leftColumn.weight || rightColumn.weight) {
var sumOfWeights = leftColumn.weight + rightColumn.weight;
var delta = rightEdgeOfNextColumn - leftEdgeOfPreviousColumn;
leftColumn.weight = (dragPoint - leftEdgeOfPreviousColumn) * sumOfWeights / delta;
rightColumn.weight = (rightEdgeOfNextColumn - dragPoint) * sumOfWeights / delta;
}

this._positionResizers();
event.preventDefault();
this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);
},

_endResizerDragging: function(event)
{
this._currentResizer = null;
this._saveColumnWeights();
this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);
},

ColumnResizePadding: 24,

CenterResizerOverBorderAdjustment: 3,

__proto__: WebInspector.View.prototype
}

WebInspector.DataGrid.ResizeMethod = {
Nearest: "nearest",
First: "first",
Last: "last"
}


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,


_isRoot: false,

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();
this._element.createChild("td", "corner");

return this._element;
},

createCells: function()
{
var columnsArray = this.dataGrid._columnsArray;
for (var i = 0; i < columnsArray.length; ++i) {
var cell = this.createCell(columnsArray[i].identifier);
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._isRoot) {
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;

this._element.enableStyleClass("parent", this._hasChildren);
this._element.enableStyleClass("expanded", this._hasChildren && this.expanded);
},

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

set revealed(x)
{
if (this._revealed === x)
return;

this._revealed = x;

if (this._element)
this._element.enableStyleClass("revealed", this._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._isRoot)
this._depth = this.parent.depth + 1;
else
this._depth = 0;
return this._depth;
},

get leftPadding()
{
if (typeof this._leftPadding === "number")
return this._leftPadding;

this._leftPadding = this.depth * this.dataGrid.indentWidth;
return this._leftPadding;
},

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();
this._element.createChild("td", "corner");
},


createTD: function(columnIdentifier)
{
var cell = document.createElement("td");
cell.className = columnIdentifier + "-column";
cell.columnIdentifier_ = columnIdentifier;

var alignment = this.dataGrid.columns[columnIdentifier].align;
if (alignment)
cell.addStyleClass(alignment);

return cell;
},


createCell: function(columnIdentifier)
{
var cell = this.createTD(columnIdentifier);

var data = this.data[columnIdentifier];
var div = document.createElement("div");
if (data instanceof Node)
div.appendChild(data);
else {
div.textContent = data;
if (this.dataGrid.columns[columnIdentifier].longText)
div.title = data;
}
cell.appendChild(div);

if (columnIdentifier === this.dataGrid.disclosureColumnIdentifier) {
cell.addStyleClass("disclosure");
if (this.leftPadding)
cell.style.setProperty("padding-left", this.leftPadding + "px");
}

return cell;
},


nodeHeight: function()
{
var rowHeight = 16;
if (!this.revealed)
return 0;
if (!this.expanded)
return rowHeight;
var result = rowHeight;
for (var i = 0; i < this.children.length; i++)
result += this.children[i].nodeHeight();
return result;
},


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();
if (!this.revealed)
child.revealed = false;
},


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;
},

_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._isRoot)
return;
if (this._element)
this._element.removeStyleClass("expanded");

this._expanded = false;

for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = false;
},

collapseRecursively: function()
{
var item = this;
while (item) {
if (item.expanded)
item.collapse();
item = item.traverseNextNode(false, this, true);
}
},

populate: function() { },

expand: function()
{
if (!this.hasChildren || this.expanded)
return;
if (this._isRoot)
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.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;
},

expandRecursively: function()
{
var item = this;
while (item) {
item.expand();
item = item.traverseNextNode(false, this);
}
},

reveal: function()
{
if (this._isRoot)
return;
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor._isRoot) {
if (!currentAncestor.expanded)
currentAncestor.expand();
currentAncestor = currentAncestor.parent;
}

this.element.scrollIntoViewIfNeeded(false);
},


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.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.SelectedNode);
},

revealAndSelect: function()
{
if (this._isRoot)
return;
this.reveal();
this.select();
},


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.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.DeselectedNode);
},


traverseNextNode: function(skipHidden, stayWithin, dontPopulate, info)
{
if (!dontPopulate && this.hasChildren)
this.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._isRoot && !((!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.populate();

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

if (node)
return node;

if (!this.parent || this.parent._isRoot)
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 left = cell.totalOffsetLeft() + this.leftPadding;
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)
nextNode = previousNode.element.nextSibling;
if (!nextNode)
nextNode = this.dataGrid.dataTableBody.firstChild;
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();

this.wasDetached();
},

wasDetached: function()
{
},

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;
},

__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;
},

__proto__: WebInspector.DataGridNode.prototype
}






WebInspector.ShowMoreDataGridNode = function(callback, startPosition, endPosition, chunkSize)
{
WebInspector.DataGridNode.call(this, {summaryRow:true}, false);
this._callback = callback;
this._startPosition = startPosition;
this._endPosition = endPosition;
this._chunkSize = chunkSize;

this.showNext = document.createElement("button");
this.showNext.setAttribute("type", "button");
this.showNext.addEventListener("click", this._showNextChunk.bind(this), false);
this.showNext.textContent = WebInspector.UIString("Show %d before", this._chunkSize);

this.showAll = document.createElement("button");
this.showAll.setAttribute("type", "button");
this.showAll.addEventListener("click", this._showAll.bind(this), false);

this.showLast = document.createElement("button");
this.showLast.setAttribute("type", "button");
this.showLast.addEventListener("click", this._showLastChunk.bind(this), false);
this.showLast.textContent = WebInspector.UIString("Show %d after", this._chunkSize);

this._updateLabels();
this.selectable = false;
}

WebInspector.ShowMoreDataGridNode.prototype = {
_showNextChunk: function()
{
this._callback(this._startPosition, this._startPosition + this._chunkSize);
},

_showAll: function()
{
this._callback(this._startPosition, this._endPosition);
},

_showLastChunk: function()
{
this._callback(this._endPosition - this._chunkSize, this._endPosition);
},

_updateLabels: function()
{
var totalSize = this._endPosition - this._startPosition;
if (totalSize > this._chunkSize) {
this.showNext.removeStyleClass("hidden");
this.showLast.removeStyleClass("hidden");
} else {
this.showNext.addStyleClass("hidden");
this.showLast.addStyleClass("hidden");
}
this.showAll.textContent = WebInspector.UIString("Show all %d", totalSize);
},

createCells: function()
{
var cell = document.createElement("td");
if (this.depth)
cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
cell.appendChild(this.showNext);
cell.appendChild(this.showAll);
cell.appendChild(this.showLast);
this._element.appendChild(cell);

var columns = this.dataGrid.columns;
var count = 0;
for (var c in columns)
++count;
while (--count > 0) {
cell = document.createElement("td");
this._element.appendChild(cell);
}
},


setStartPosition: function(from)
{
this._startPosition = from;
this._updateLabels();
},


setEndPosition: function(to)
{
this._endPosition = to;
this._updateLabels();
},


nodeHeight: function()
{
return 32;
},

dispose: function()
{
},

__proto__: WebInspector.DataGridNode.prototype
}







WebInspector.CookiesTable = function(expandable, refreshCallback, selectedCallback)
{
WebInspector.View.call(this);
this.element.className = "fill";

var readOnly = expandable;
this._refreshCallback = refreshCallback;

var columns = [
{id: "name", title: WebInspector.UIString("Name"), sortable: true, disclosure: expandable, sort: WebInspector.DataGrid.Order.Ascending, longText: true, weight: 24},
{id: "value", title: WebInspector.UIString("Value"), sortable: true, longText: true, weight: 34},
{id: "domain", title: WebInspector.UIString("Domain"), sortable: true, weight: 7},
{id: "path", title: WebInspector.UIString("Path"), sortable: true, weight: 7},
{id: "expires", title: WebInspector.UIString("Expires / Max-Age"), sortable: true, weight: 7},
{id: "size", title: WebInspector.UIString("Size"), sortable: true, align: WebInspector.DataGrid.Align.Right, weight: 7},
{id: "httpOnly", title: WebInspector.UIString("HTTP"), sortable: true, align: WebInspector.DataGrid.Align.Center, weight: 7},
{id: "secure", title: WebInspector.UIString("Secure"), sortable: true, align: WebInspector.DataGrid.Align.Center, weight: 7}
];

if (readOnly)
this._dataGrid = new WebInspector.DataGrid(columns);
else
this._dataGrid = new WebInspector.DataGrid(columns, undefined, this._onDeleteCookie.bind(this), refreshCallback, this._onContextMenu.bind(this));

this._dataGrid.setName("cookiesTable");
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._rebuildTable, this);

if (selectedCallback)
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, selectedCallback, this);

this._nextSelectedCookie =   (null);

this._dataGrid.show(this.element);
this._data = [];
}

WebInspector.CookiesTable.prototype = {

_clearAndRefresh: function(domain)
{
this.clear(domain);
this._refresh();
},


_onContextMenu: function(contextMenu, node)
{
if (node === this._dataGrid.creationNode)
return;
var cookie = node.cookie;
var domain = cookie.domain();
if (domain)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear all from \"%s\"" : "Clear All from \"%s\"", domain), this._clearAndRefresh.bind(this, domain));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear all" : "Clear All"), this._clearAndRefresh.bind(this, null));
},


setCookies: function(cookies)
{
this.setCookieFolders([{cookies: cookies}]);
},


setCookieFolders: function(cookieFolders)
{
this._data = cookieFolders;
this._rebuildTable();
},


selectedCookie: function()
{
var node = this._dataGrid.selectedNode;
return node ? node.cookie : null;
},


clear: function(domain)
{
for (var i = 0, length = this._data.length; i < length; ++i) {
var cookies = this._data[i].cookies;
for (var j = 0, cookieCount = cookies.length; j < cookieCount; ++j) {
if (!domain || cookies[j].domain() === domain)
cookies[j].remove();
}
}
},

_rebuildTable: function()
{
var selectedCookie = this._nextSelectedCookie || this.selectedCookie();
this._nextSelectedCookie = null;
this._dataGrid.rootNode().removeChildren();
for (var i = 0; i < this._data.length; ++i) {
var item = this._data[i];
if (item.folderName) {
var groupData = {name: item.folderName, value: "", domain: "", path: "", expires: "", size: this._totalSize(item.cookies), httpOnly: "", secure: ""};
var groupNode = new WebInspector.DataGridNode(groupData);
groupNode.selectable = true;
this._dataGrid.rootNode().appendChild(groupNode);
groupNode.element.addStyleClass("row-group");
this._populateNode(groupNode, item.cookies, selectedCookie);
groupNode.expand();
} else
this._populateNode(this._dataGrid.rootNode(), item.cookies, selectedCookie);
}
},


_populateNode: function(parentNode, cookies, selectedCookie)
{
parentNode.removeChildren();
if (!cookies)
return;

this._sortCookies(cookies);
for (var i = 0; i < cookies.length; ++i) {
var cookie = cookies[i];
var cookieNode = this._createGridNode(cookie);
parentNode.appendChild(cookieNode);
if (selectedCookie && selectedCookie.name() === cookie.name() && selectedCookie.domain() === cookie.domain() && selectedCookie.path() === cookie.path())
cookieNode.select();
}
},

_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.isSortOrderAscending() ? 1 : -1;

function compareTo(getter, cookie1, cookie2)
{
return sortDirection * (getter.apply(cookie1) + "").compareTo(getter.apply(cookie2) + "")
}

function numberCompare(getter, cookie1, cookie2)
{
return sortDirection * (getter.apply(cookie1) - getter.apply(cookie2));
}

function expiresCompare(cookie1, cookie2)
{
if (cookie1.session() !== cookie2.session())
return sortDirection * (cookie1.session() ? 1 : -1);

if (cookie1.session())
return 0;

if (cookie1.maxAge() && cookie2.maxAge())
return sortDirection * (cookie1.maxAge() - cookie2.maxAge());
if (cookie1.expires() && cookie2.expires())
return sortDirection * (cookie1.expires() - cookie2.expires());
return sortDirection * (cookie1.expires() ? 1 : -1);
}

var comparator;
switch (this._dataGrid.sortColumnIdentifier()) {
case "name": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.name); break;
case "value": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.value); break;
case "domain": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.domain); break;
case "path": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.path); break;
case "expires": comparator = expiresCompare; break;
case "size": comparator = numberCompare.bind(null, WebInspector.Cookie.prototype.size); break;
case "httpOnly": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.httpOnly); break;
case "secure": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.secure); break;
default: compareTo.bind(null, WebInspector.Cookie.prototype.name);
}

cookies.sort(comparator);
},


_createGridNode: function(cookie)
{
var data = {};
data.name = cookie.name();
data.value = cookie.value();
data.domain = cookie.domain() || "";
data.path = cookie.path() || "";
if (cookie.type() === WebInspector.Cookie.Type.Request)
data.expires = "";
else if (cookie.maxAge())
data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10));
else if (cookie.expires())
data.expires = new Date(cookie.expires()).toGMTString();
else
data.expires = WebInspector.UIString("Session");
data.size = cookie.size();
const checkmark = "\u2713";
data.httpOnly = (cookie.httpOnly() ? checkmark : "");
data.secure = (cookie.secure() ? checkmark : "");

var node = new WebInspector.DataGridNode(data);
node.cookie = cookie;
node.selectable = true;
return node;
},

_onDeleteCookie: function(node)
{
var cookie = node.cookie;
var neighbour = node.traverseNextNode() || node.traversePreviousNode();
if (neighbour)
this._nextSelectedCookie = neighbour.cookie;
cookie.remove();
this._refresh();
},

_refresh: function()
{
if (this._refreshCallback)
this._refreshCallback();
},

__proto__: WebInspector.View.prototype
}






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, this);

this._clearButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear"), "clear-storage-status-bar-item");
this._clearButton.visible = false;
this._clearButton.addEventListener("click", this._clearButtonClicked, this);

this._refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
this._refreshButton.addEventListener("click", this._refreshButtonClicked, this);

this._treeElement = treeElement;
this._cookieDomain = cookieDomain;

this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("This site has no cookies."));
this._emptyView.show(this.element);

this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
}

WebInspector.CookieItemsView.prototype = {
get statusBarItems()
{
return [this._refreshButton.element, this._clearButton.element, this._deleteButton.element];
},

wasShown: function()
{
this._update();
},

willHide: function()
{
this._deleteButton.visible = false;
},

_update: function()
{
WebInspector.Cookies.getCookiesAsync(this._updateWithCookies.bind(this));
},


_updateWithCookies: function(allCookies)
{
this._cookies = this._filterCookiesForDomain(allCookies);

if (!this._cookies.length) {

this._emptyView.show(this.element);
this._clearButton.visible = false;
this._deleteButton.visible = false;
if (this._cookiesTable)
this._cookiesTable.detach();
return;
}

if (!this._cookiesTable)
this._cookiesTable = new WebInspector.CookiesTable(false, this._update.bind(this), this._showDeleteButton.bind(this));

this._cookiesTable.setCookies(this._cookies);
this._emptyView.detach();
this._cookiesTable.show(this.element);
this._treeElement.subtitle = String.sprintf(WebInspector.UIString("%d cookies (%s)"), this._cookies.length,
Number.bytesToString(this._totalSize));
this._clearButton.visible = true;
this._deleteButton.visible = !!this._cookiesTable.selectedCookie();
},


_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;
},

clear: function()
{
this._cookiesTable.clear();
this._update();
},

_clearButtonClicked: function()
{
this.clear();
},

_showDeleteButton: function()
{
this._deleteButton.visible = true;
},

_deleteButtonClicked: function()
{
var selectedCookie = this._cookiesTable.selectedCookie();
if (selectedCookie) {
selectedCookie.remove();
this._update();
}
},

_refreshButtonClicked: function(event)
{
this._update();
},

_contextMenu: function(event)
{
if (!this._cookies.length) {
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Refresh"), this._update.bind(this));
contextMenu.show();
}
},

__proto__: WebInspector.View.prototype
}






WebInspector.ApplicationCacheModel = function()
{
ApplicationCacheAgent.enable();
InspectorBackend.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this));

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);

this._statuses = {};
this._manifestURLsByFrame = {};

this._mainFrameNavigated();

this._onLine = true;
}

WebInspector.ApplicationCacheModel.EventTypes = {
FrameManifestStatusUpdated: "FrameManifestStatusUpdated",
FrameManifestAdded: "FrameManifestAdded",
FrameManifestRemoved: "FrameManifestRemoved",
NetworkStateChanged: "NetworkStateChanged"
}

WebInspector.ApplicationCacheModel.prototype = {
_frameNavigated: function(event)
{
var frame =   (event.data);
if (frame.isMainFrame()) {
this._mainFrameNavigated();
return;
}

ApplicationCacheAgent.getManifestForFrame(frame.id, this._manifestForFrameLoaded.bind(this, frame.id));
},


_frameDetached: function(event)
{
var frame =   (event.data);
this._frameManifestRemoved(frame.id);
},

_mainFrameNavigated: function()
{
ApplicationCacheAgent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));
},


_manifestForFrameLoaded: function(frameId, error, manifestURL)
{
if (error) {
console.error(error);
return;
}

if (!manifestURL)
this._frameManifestRemoved(frameId);
},


_framesWithManifestsLoaded: function(error, framesWithManifests)
{
if (error) {
console.error(error);
return;
}

for (var i = 0; i < framesWithManifests.length; ++i)
this._frameManifestUpdated(framesWithManifests[i].frameId, framesWithManifests[i].manifestURL, framesWithManifests[i].status);
},


_frameManifestUpdated: function(frameId, manifestURL, status)
{
if (status === applicationCache.UNCACHED) {
this._frameManifestRemoved(frameId);
return;
}

if (!manifestURL)
return;

if (this._manifestURLsByFrame[frameId] && manifestURL !== this._manifestURLsByFrame[frameId])
this._frameManifestRemoved(frameId);

var statusChanged = this._statuses[frameId] !== status;
this._statuses[frameId] = status;

if (!this._manifestURLsByFrame[frameId]) {
this._manifestURLsByFrame[frameId] = manifestURL;
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, frameId);
}

if (statusChanged)
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, frameId);
},


_frameManifestRemoved: function(frameId)
{
if (!this._manifestURLsByFrame[frameId])
return;

var manifestURL = this._manifestURLsByFrame[frameId];
delete this._manifestURLsByFrame[frameId];
delete this._statuses[frameId];

this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, frameId);
},


frameManifestURL: function(frameId)
{
return this._manifestURLsByFrame[frameId] || "";
},


frameManifestStatus: function(frameId)
{
return this._statuses[frameId] || applicationCache.UNCACHED;
},


get onLine()
{
return this._onLine;
},


_statusUpdated: function(frameId, manifestURL, status)
{
this._frameManifestUpdated(frameId, manifestURL, status);
},


requestApplicationCache: function(frameId, callback)
{
function callbackWrapper(error, applicationCache)
{
if (error) {
console.error(error);
callback(null);
return;
}

callback(applicationCache);
}

ApplicationCacheAgent.getApplicationCacheForFrame(frameId, callbackWrapper.bind(this));
},


_networkStateUpdated: function(isNowOnline)
{
this._onLine = isNowOnline;
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, isNowOnline);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.ApplicationCacheDispatcher = function(applicationCacheModel)
{
this._applicationCacheModel = applicationCacheModel;
}

WebInspector.ApplicationCacheDispatcher.prototype = {

applicationCacheStatusUpdated: function(frameId, manifestURL, status)
{
this._applicationCacheModel._statusUpdated(frameId, manifestURL, status);
},


networkStateUpdated: function(isNowOnline)
{
this._applicationCacheModel._networkStateUpdated(isNowOnline);
}
}






WebInspector.IndexedDBModel = function()
{
IndexedDBAgent.enable();

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);

this._databases = new Map();
this._databaseNamesBySecurityOrigin = {};
this._reset();
}

WebInspector.IndexedDBModel.KeyTypes = {
NumberType:  "number",
StringType:  "string",
DateType:    "date",
ArrayType:   "array"
};

WebInspector.IndexedDBModel.KeyPathTypes = {
NullType:    "null",
StringType:  "string",
ArrayType:   "array"
};

WebInspector.IndexedDBModel.keyFromIDBKey = function(idbKey)
{
if (typeof(idbKey) === "undefined" || idbKey === null)
return null;

var key = {};
switch (typeof(idbKey)) {
case "number":
key.number = idbKey;
key.type = WebInspector.IndexedDBModel.KeyTypes.NumberType;
break;
case "string":
key.string = idbKey;
key.type = WebInspector.IndexedDBModel.KeyTypes.StringType;
break;
case "object":
if (idbKey instanceof Date) {
key.date = idbKey.getTime();
key.type = WebInspector.IndexedDBModel.KeyTypes.DateType;
} else if (idbKey instanceof Array) {
key.array = [];
for (var i = 0; i < idbKey.length; ++i)
key.array.push(WebInspector.IndexedDBModel.keyFromIDBKey(idbKey[i]));
key.type = WebInspector.IndexedDBModel.KeyTypes.ArrayType;
}
break;
default:
return null;
}
return key;
}

WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange = function(idbKeyRange)
{
var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
if (typeof(idbKeyRange) === "undefined" || idbKeyRange === null)
return null;

var keyRange = {};
keyRange.lower = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower);
keyRange.upper = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper);
keyRange.lowerOpen = idbKeyRange.lowerOpen;
keyRange.upperOpen = idbKeyRange.upperOpen;
return keyRange;
}


WebInspector.IndexedDBModel.idbKeyPathFromKeyPath = function(keyPath)
{
var idbKeyPath;
switch (keyPath.type) {
case WebInspector.IndexedDBModel.KeyPathTypes.NullType:
idbKeyPath = null;
break;
case WebInspector.IndexedDBModel.KeyPathTypes.StringType:
idbKeyPath = keyPath.string;
break;
case WebInspector.IndexedDBModel.KeyPathTypes.ArrayType:
idbKeyPath = keyPath.array;
break;
}
return idbKeyPath;
}

WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath = function(idbKeyPath)
{
if (typeof idbKeyPath === "string")
return "\"" + idbKeyPath + "\"";
if (idbKeyPath instanceof Array)
return "[\"" + idbKeyPath.join("\", \"") + "\"]";
return null;
}

WebInspector.IndexedDBModel.EventTypes = {
DatabaseAdded: "DatabaseAdded",
DatabaseRemoved: "DatabaseRemoved",
DatabaseLoaded: "DatabaseLoaded"
}

WebInspector.IndexedDBModel.prototype = {
_reset: function()
{
for (var securityOrigin in this._databaseNamesBySecurityOrigin)
this._removeOrigin(securityOrigin);
var securityOrigins = WebInspector.resourceTreeModel.securityOrigins();
for (var i = 0; i < securityOrigins.length; ++i)
this._addOrigin(securityOrigins[i]);
},

refreshDatabaseNames: function()
{
for (var securityOrigin in this._databaseNamesBySecurityOrigin)
this._loadDatabaseNames(securityOrigin);
},


refreshDatabase: function(databaseId)
{
this._loadDatabase(databaseId);
},


clearObjectStore: function(databaseId, objectStoreName, callback)
{
IndexedDBAgent.clearObjectStore(databaseId.securityOrigin, databaseId.name, objectStoreName, callback);
},


_securityOriginAdded: function(event)
{
var securityOrigin =   (event.data);
this._addOrigin(securityOrigin);
},


_securityOriginRemoved: function(event)
{
var securityOrigin =   (event.data);
this._removeOrigin(securityOrigin);
},


_addOrigin: function(securityOrigin)
{
console.assert(!this._databaseNamesBySecurityOrigin[securityOrigin]);
this._databaseNamesBySecurityOrigin[securityOrigin] = [];
this._loadDatabaseNames(securityOrigin);
},


_removeOrigin: function(securityOrigin)
{
console.assert(this._databaseNamesBySecurityOrigin[securityOrigin]);
for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
this._databaseRemoved(securityOrigin, this._databaseNamesBySecurityOrigin[securityOrigin][i]);
delete this._databaseNamesBySecurityOrigin[securityOrigin];
},


_updateOriginDatabaseNames: function(securityOrigin, databaseNames)
{
var newDatabaseNames = {};
for (var i = 0; i < databaseNames.length; ++i)
newDatabaseNames[databaseNames[i]] = true;
var oldDatabaseNames = {};
for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
oldDatabaseNames[this._databaseNamesBySecurityOrigin[securityOrigin][i]] = true;

this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames;

for (var databaseName in oldDatabaseNames) {
if (!newDatabaseNames[databaseName])
this._databaseRemoved(securityOrigin, databaseName);
}
for (var databaseName in newDatabaseNames) {
if (!oldDatabaseNames[databaseName])
this._databaseAdded(securityOrigin, databaseName);
}
},


_databaseAdded: function(securityOrigin, databaseName)
{
var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, databaseId);
},


_databaseRemoved: function(securityOrigin, databaseName)
{
var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, databaseId);
},


_loadDatabaseNames: function(securityOrigin)
{

function callback(error, databaseNames)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}

if (!this._databaseNamesBySecurityOrigin[securityOrigin])
return;
this._updateOriginDatabaseNames(securityOrigin, databaseNames);
}

IndexedDBAgent.requestDatabaseNames(securityOrigin, callback.bind(this));
},


_loadDatabase: function(databaseId)
{

function callback(error, databaseWithObjectStores)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}

if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin])
return;
var databaseModel = new WebInspector.IndexedDBModel.Database(databaseId, databaseWithObjectStores.version, databaseWithObjectStores.intVersion);
this._databases.put(databaseId, databaseModel);
for (var i = 0; i < databaseWithObjectStores.objectStores.length; ++i) {
var objectStore = databaseWithObjectStores.objectStores[i];
var objectStoreIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(objectStore.keyPath);
var objectStoreModel = new WebInspector.IndexedDBModel.ObjectStore(objectStore.name, objectStoreIDBKeyPath, objectStore.autoIncrement);
for (var j = 0; j < objectStore.indexes.length; ++j) {
var index = objectStore.indexes[j];
var indexIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(index.keyPath);
var indexModel = new WebInspector.IndexedDBModel.Index(index.name, indexIDBKeyPath, index.unique, index.multiEntry);
objectStoreModel.indexes[indexModel.name] = indexModel;
}
databaseModel.objectStores[objectStoreModel.name] = objectStoreModel;
}

this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, databaseModel);
}

IndexedDBAgent.requestDatabase(databaseId.securityOrigin, databaseId.name, callback.bind(this));
},


loadObjectStoreData: function(databaseId, objectStoreName, idbKeyRange, skipCount, pageSize, callback)
{
this._requestData(databaseId, databaseId.name, objectStoreName, "", idbKeyRange, skipCount, pageSize, callback);
},


loadIndexData: function(databaseId, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
{
this._requestData(databaseId, databaseId.name, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback);
},


_requestData: function(databaseId, databaseName, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
{

function innerCallback(error, dataEntries, hasMore)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}

if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin])
return;
var entries = [];
for (var i = 0; i < dataEntries.length; ++i) {
var key = WebInspector.RemoteObject.fromPayload(dataEntries[i].key);
var primaryKey = WebInspector.RemoteObject.fromPayload(dataEntries[i].primaryKey);
var value = WebInspector.RemoteObject.fromPayload(dataEntries[i].value);
entries.push(new WebInspector.IndexedDBModel.Entry(key, primaryKey, value));
}
callback(entries, hasMore);
}

var keyRange = WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRange);
IndexedDBAgent.requestData(databaseId.securityOrigin, databaseName, objectStoreName, indexName, skipCount, pageSize, keyRange ? keyRange : undefined, innerCallback.bind(this));
},

__proto__: WebInspector.Object.prototype
}


WebInspector.IndexedDBModel.Entry = function(key, primaryKey, value)
{
this.key = key;
this.primaryKey = primaryKey;
this.value = value;
}


WebInspector.IndexedDBModel.DatabaseId = function(securityOrigin, name)
{
this.securityOrigin = securityOrigin;
this.name = name;
}

WebInspector.IndexedDBModel.DatabaseId.prototype = {

equals: function(databaseId)
{
return this.name === databaseId.name && this.securityOrigin === databaseId.securityOrigin;
},
}

WebInspector.IndexedDBModel.Database = function(databaseId, version, intVersion)
{
this.databaseId = databaseId;
this.version = version;
this.intVersion = intVersion;
this.objectStores = {};
}


WebInspector.IndexedDBModel.ObjectStore = function(name, keyPath, autoIncrement)
{
this.name = name;
this.keyPath = keyPath;
this.autoIncrement = autoIncrement;
this.indexes = {};
}

WebInspector.IndexedDBModel.ObjectStore.prototype = {

get keyPathString()
{
return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
}
}


WebInspector.IndexedDBModel.Index = function(name, keyPath, unique, multiEntry)
{
this.name = name;
this.keyPath = keyPath;
this.unique = unique;
this.multiEntry = multiEntry;
}

WebInspector.IndexedDBModel.Index.prototype = {

get keyPathString()
{
return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
}
}






WebInspector.Spectrum = function()
{
WebInspector.View.call(this);
this.registerRequiredCSS("spectrum.css");

this.element.className = "spectrum-container";
this.element.tabIndex = 0;

var topElement = this.element.createChild("div", "spectrum-top");
topElement.createChild("div", "spectrum-fill");

var topInnerElement = topElement.createChild("div", "spectrum-top-inner fill");
this._draggerElement = topInnerElement.createChild("div", "spectrum-color");
this._dragHelperElement = this._draggerElement.createChild("div", "spectrum-sat fill").createChild("div", "spectrum-val fill").createChild("div", "spectrum-dragger");

this._sliderElement = topInnerElement.createChild("div", "spectrum-hue");
this.slideHelper = this._sliderElement.createChild("div", "spectrum-slider");

var rangeContainer = this.element.createChild("div", "spectrum-range-container");
var alphaLabel = rangeContainer.createChild("label");
alphaLabel.textContent = WebInspector.UIString("\u03B1:");

this._alphaElement = rangeContainer.createChild("input", "spectrum-range");
this._alphaElement.setAttribute("type", "range");
this._alphaElement.setAttribute("min", "0");
this._alphaElement.setAttribute("max", "100");
this._alphaElement.addEventListener("change", alphaDrag.bind(this), false);

var swatchElement = document.createElement("span");
swatchElement.className = "swatch";
this._swatchInnerElement = swatchElement.createChild("span", "swatch-inner");

var displayContainer = this.element.createChild("div");
displayContainer.appendChild(swatchElement);
this._displayElement = displayContainer.createChild("span", "source-code spectrum-display-value");

WebInspector.Spectrum.draggable(this._sliderElement, hueDrag.bind(this));
WebInspector.Spectrum.draggable(this._draggerElement, colorDrag.bind(this), colorDragStart.bind(this));

function hueDrag(element, dragX, dragY)
{
this._hsv[0] = dragY / this.slideHeight;

this._onchange();
}

var initialHelperOffset;

function colorDragStart(element, dragX, dragY)
{
initialHelperOffset = { x: this._dragHelperElement.offsetLeft, y: this._dragHelperElement.offsetTop };
}

function colorDrag(element, dragX, dragY, event)
{
if (event.shiftKey) {
if (Math.abs(dragX - initialHelperOffset.x) >= Math.abs(dragY - initialHelperOffset.y))
dragY = initialHelperOffset.y;
else
dragX = initialHelperOffset.x;
}

this._hsv[1] = dragX / this.dragWidth;
this._hsv[2] = (this.dragHeight - dragY) / this.dragHeight;

this._onchange();
}

function alphaDrag()
{
this._hsv[3] = this._alphaElement.value / 100;

this._onchange();
}
};

WebInspector.Spectrum.Events = {
ColorChanged: "ColorChanged"
};


WebInspector.Spectrum.draggable = function(element, onmove, onstart, onstop) {

var doc = document;
var dragging;
var offset;
var scrollOffset;
var maxHeight;
var maxWidth;

function consume(e)
{
e.consume(true);
}

function move(e)
{
if (dragging) {
var dragX = Math.max(0, Math.min(e.pageX - offset.left + scrollOffset.left, maxWidth));
var dragY = Math.max(0, Math.min(e.pageY - offset.top + scrollOffset.top, maxHeight));

if (onmove)
onmove(element, dragX, dragY, e);
}
}

function start(e)
{
var rightClick = e.which ? (e.which === 3) : (e.button === 2);

if (!rightClick && !dragging) {

if (onstart)
onstart(element, e)

dragging = true;
maxHeight = element.clientHeight;
maxWidth = element.clientWidth;

scrollOffset = element.scrollOffset();
offset = element.totalOffset();

doc.addEventListener("selectstart", consume, false);
doc.addEventListener("dragstart", consume, false);
doc.addEventListener("mousemove", move, false);
doc.addEventListener("mouseup", stop, false);

move(e);
consume(e);
}
}

function stop(e)
{
if (dragging) {
doc.removeEventListener("selectstart", consume, false);
doc.removeEventListener("dragstart", consume, false);
doc.removeEventListener("mousemove", move, false);
doc.removeEventListener("mouseup", stop, false);

if (onstop)
onstop(element, e);
}

dragging = false;
}

element.addEventListener("mousedown", start, false);
};

WebInspector.Spectrum.prototype = {

setColor: function(color)
{
this._hsv = color.hsva();
},


color: function()
{
return WebInspector.Color.fromHSVA(this._hsv);
},

_colorString: function()
{
var cf = WebInspector.Color.Format;
var format = this._originalFormat;
var color = this.color();
var originalFormatString = color.toString(this._originalFormat);
if (originalFormatString)
return originalFormatString;

if (color.hasAlpha()) {

if (format === cf.HSLA || format === cf.HSL)
return color.toString(cf.HSLA);
else
return color.toString(cf.RGBA);
}

if (format === cf.ShortHEX)
return color.toString(cf.HEX);
console.assert(format === cf.Nickname);
return color.toString(cf.RGB);
},


set displayText(text)
{
this._displayElement.textContent = text;
},

_onchange: function()
{
this._updateUI();
this.dispatchEventToListeners(WebInspector.Spectrum.Events.ColorChanged, this._colorString());
},

_updateHelperLocations: function()
{
var h = this._hsv[0];
var s = this._hsv[1];
var v = this._hsv[2];


var dragX = s * this.dragWidth;
var dragY = this.dragHeight - (v * this.dragHeight);

dragX = Math.max(-this._dragHelperElementHeight,
Math.min(this.dragWidth - this._dragHelperElementHeight, dragX - this._dragHelperElementHeight));
dragY = Math.max(-this._dragHelperElementHeight,
Math.min(this.dragHeight - this._dragHelperElementHeight, dragY - this._dragHelperElementHeight));

this._dragHelperElement.positionAt(dragX, dragY);


var slideY = (h * this.slideHeight) - this.slideHelperHeight;
this.slideHelper.style.top = slideY + "px";

this._alphaElement.value = this._hsv[3] * 100;
},

_updateUI: function()
{
this._updateHelperLocations();

this._draggerElement.style.backgroundColor = WebInspector.Color.fromHSVA([this._hsv[0], 1, 1, 1]).toString(WebInspector.Color.Format.RGB);
this._swatchInnerElement.style.backgroundColor = this.color().toString(WebInspector.Color.Format.RGB);

this._alphaElement.value = this._hsv[3] * 100;
},

wasShown: function()
{
this.slideHeight = this._sliderElement.offsetHeight;
this.dragWidth = this._draggerElement.offsetWidth;
this.dragHeight = this._draggerElement.offsetHeight;
this._dragHelperElementHeight = this._dragHelperElement.offsetHeight / 2;
this.slideHelperHeight = this.slideHelper.offsetHeight / 2;
this._updateUI();
},

__proto__: WebInspector.View.prototype
}


WebInspector.SpectrumPopupHelper = function()
{
this._spectrum = new WebInspector.Spectrum();
this._spectrum.element.addEventListener("keydown", this._onKeyDown.bind(this), false);

this._popover = new WebInspector.Popover();
this._popover.setCanShrink(false);
this._popover.element.addEventListener("mousedown", consumeEvent, false);

this._hideProxy = this.hide.bind(this, true);
}

WebInspector.SpectrumPopupHelper.Events = {
Hidden: "Hidden"
};

WebInspector.SpectrumPopupHelper.prototype = {

spectrum: function()
{
return this._spectrum;
},

toggle: function(element, color, format)
{
if (this._popover.isShowing())
this.hide(true);
else
this.show(element, color, format);

return this._popover.isShowing();
},

show: function(element, color, format)
{
if (this._popover.isShowing()) {
if (this._anchorElement === element)
return false;


this.hide(true);
}

this._anchorElement = element;

this._spectrum.setColor(color);
this._spectrum._originalFormat = format !== WebInspector.Color.Format.Original ? format : color.format();
this.reposition(element);

document.addEventListener("mousedown", this._hideProxy, false);
window.addEventListener("blur", this._hideProxy, false);
return true;
},

reposition: function(element)
{
if (!this._previousFocusElement)
this._previousFocusElement = WebInspector.currentFocusElement();
this._popover.showView(this._spectrum, element);
WebInspector.setCurrentFocusElement(this._spectrum.element);
},


hide: function(commitEdit)
{
if (!this._popover.isShowing())
return;
this._popover.hide();

document.removeEventListener("mousedown", this._hideProxy, false);
window.removeEventListener("blur", this._hideProxy, false);

this.dispatchEventToListeners(WebInspector.SpectrumPopupHelper.Events.Hidden, !!commitEdit);

WebInspector.setCurrentFocusElement(this._previousFocusElement);
delete this._previousFocusElement;

delete this._anchorElement;
},

_onKeyDown: function(event)
{
if (event.keyIdentifier === "Enter") {
this.hide(true);
event.consume(true);
return;
}
if (event.keyIdentifier === "U+001B") { 
this.hide(false);
event.consume(true);
}
},

__proto__: WebInspector.Object.prototype
}


WebInspector.ColorSwatch = function()
{
this.element = document.createElement("span");
this._swatchInnerElement = this.element.createChild("span", "swatch-inner");
this.element.title = WebInspector.UIString("Click to open a colorpicker. Shift-click to change color format");
this.element.className = "swatch";
this.element.addEventListener("mousedown", consumeEvent, false);
this.element.addEventListener("dblclick", consumeEvent, false);
}

WebInspector.ColorSwatch.prototype = {

setColorString: function(colorString)
{
this._swatchInnerElement.style.backgroundColor = colorString;
}
}






WebInspector.SidebarPane = function(title)
{
WebInspector.View.call(this);
this.element.className = "sidebar-pane";

this.titleElement = document.createElement("div");
this.titleElement.className = "sidebar-pane-toolbar";

this.bodyElement = this.element.createChild("div", "body");

this._title = title;

this._expandCallback = null;
}

WebInspector.SidebarPane.EventTypes = {
wasShown: "wasShown"
}

WebInspector.SidebarPane.prototype = {
title: function()
{
return this._title;
},


prepareContent: function(callback)
{
if (callback)
callback();
},

expand: function()
{
this.prepareContent(this.onContentReady.bind(this));
},

onContentReady: function()
{
if (this._expandCallback)
this._expandCallback();
else
this._expandPending = true;
},


setExpandCallback: function(callback)
{
this._expandCallback = callback;
if (this._expandPending) {
delete this._expandPending;
this._expandCallback();
}
},

wasShown: function()
{
WebInspector.View.prototype.wasShown.call(this);
this.dispatchEventToListeners(WebInspector.SidebarPane.EventTypes.wasShown);
},

__proto__: WebInspector.View.prototype
}


WebInspector.SidebarPaneTitle = function(container, pane)
{
this._pane = pane;

this.element = container.createChild("div", "sidebar-pane-title");
this.element.textContent = pane.title();
this.element.tabIndex = 0;
this.element.addEventListener("click", this._toggleExpanded.bind(this), false);
this.element.addEventListener("keydown", this._onTitleKeyDown.bind(this), false);
this.element.appendChild(this._pane.titleElement);

this._pane.setExpandCallback(this._expand.bind(this));
}

WebInspector.SidebarPaneTitle.prototype = {

_expand: function()
{
this.element.addStyleClass("expanded");
this._pane.show(this.element.parentNode, this.element.nextSibling);
},

_collapse: function()
{
this.element.removeStyleClass("expanded");
if (this._pane.element.parentNode == this.element.parentNode)
this._pane.detach();
},

_toggleExpanded: function()
{
if (this.element.hasStyleClass("expanded"))
this._collapse();
else
this._pane.expand();
},


_onTitleKeyDown: function(event)
{
if (isEnterKey(event) || event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
this._toggleExpanded();
}
}


WebInspector.SidebarPaneStack = function()
{
WebInspector.View.call(this);
this.element.className = "sidebar-pane-stack fill";
this.registerRequiredCSS("sidebarPane.css");
}

WebInspector.SidebarPaneStack.prototype = {

addPane: function(pane)
{
new WebInspector.SidebarPaneTitle(this.element, pane);
},

__proto__: WebInspector.View.prototype
}


WebInspector.SidebarTabbedPane = function()
{
WebInspector.TabbedPane.call(this);
this.element.addStyleClass("sidebar-tabbed-pane");
this.registerRequiredCSS("sidebarPane.css");
}

WebInspector.SidebarTabbedPane.prototype = {

addPane: function(pane)
{
var title = pane.title();
this.appendTab(title, title, pane);
pane.element.appendChild(pane.titleElement);
pane.setExpandCallback(this.selectTab.bind(this, title));

},

__proto__: WebInspector.TabbedPane.prototype
}






WebInspector.ElementsTreeOutline = function(omitRootDOMNode, selectEnabled, showInElementsPanelEnabled, contextMenuCallback, setPseudoClassCallback)
{
this.element = document.createElement("ol");
this.element.className = "elements-tree-outline";
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);
this.element.addEventListener("dragstart", this._ondragstart.bind(this), false);
this.element.addEventListener("dragover", this._ondragover.bind(this), false);
this.element.addEventListener("dragleave", this._ondragleave.bind(this), false);
this.element.addEventListener("drop", this._ondrop.bind(this), false);
this.element.addEventListener("dragend", this._ondragend.bind(this), false);
this.element.addEventListener("keydown", this._onkeydown.bind(this), false);

TreeOutline.call(this, this.element);

this._includeRootDOMNode = !omitRootDOMNode;
this._selectEnabled = selectEnabled;
this._showInElementsPanelEnabled = showInElementsPanelEnabled;
this._rootDOMNode = null;
this._selectDOMNode = null;
this._eventSupport = new WebInspector.Object();

this._visible = false;

this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
this._contextMenuCallback = contextMenuCallback;
this._setPseudoClassCallback = setPseudoClassCallback;
this._createNodeDecorators();
}

WebInspector.ElementsTreeOutline.Events = {
SelectedNodeChanged: "SelectedNodeChanged"
}

WebInspector.ElementsTreeOutline.MappedCharToEntity = {
"\u00a0": "nbsp",
"\u2002": "ensp",
"\u2003": "emsp",
"\u2009": "thinsp",
"\u200a": "#8202", 
"\u200b": "#8203", 
"\u200c": "zwnj",
"\u200d": "zwj",
"\u200e": "lrm",
"\u200f": "rlm",
"\u202a": "#8234", 
"\u202b": "#8235", 
"\u202c": "#8236", 
"\u202d": "#8237", 
"\u202e": "#8238" 
}

WebInspector.ElementsTreeOutline.prototype = {
_createNodeDecorators: function()
{
this._nodeDecorators = [];
this._nodeDecorators.push(new WebInspector.ElementsTreeOutline.PseudoStateDecorator());
},

wireToDomAgent: function()
{
this._elementsTreeUpdater = new WebInspector.ElementsTreeUpdater(this);
},

setVisible: function(visible)
{
this._visible = visible;
if (!this._visible)
return;

this._updateModifiedNodes();
if (this._selectedDOMNode)
this._revealAndSelectNode(this._selectedDOMNode, false);
},

addEventListener: function(eventType, listener, thisObject)
{
this._eventSupport.addEventListener(eventType, listener, thisObject);
},

removeEventListener: function(eventType, listener, thisObject)
{
this._eventSupport.removeEventListener(eventType, listener, thisObject);
},

get rootDOMNode()
{
return this._rootDOMNode;
},

set rootDOMNode(x)
{
if (this._rootDOMNode === x)
return;

this._rootDOMNode = x;

this._isXMLMimeType = x && x.isXMLNode();

this.update();
},

get isXMLMimeType()
{
return this._isXMLMimeType;
},

selectedDOMNode: function()
{
return this._selectedDOMNode;
},

selectDOMNode: function(node, focus)
{
if (this._selectedDOMNode === node) {
this._revealAndSelectNode(node, !focus);
return;
}

this._selectedDOMNode = node;
this._revealAndSelectNode(node, !focus);





if (this._selectedDOMNode === node)
this._selectedNodeChanged();
},


editing: function()
{
var node = this.selectedDOMNode();
if (!node)
return false;
var treeElement = this.findTreeElement(node);
if (!treeElement)
return false;
return treeElement._editing || false;
},

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, true);
},

updateSelection: function()
{
if (!this.selectedTreeElement)
return;
var element = this.treeOutline.selectedTreeElement;
element.updateSelection();
},


updateOpenCloseTags: function(node)
{
var treeElement = this.findTreeElement(node);
if (treeElement)
treeElement.updateTitle();
var children = treeElement.children;
var closingTagElement = children[children.length - 1];
if (closingTagElement && closingTagElement._elementCloseTag)
closingTagElement.updateTitle();
},

_selectedNodeChanged: function()
{
this._eventSupport.dispatchEventToListeners(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedDOMNode);
},


findTreeElement: function(node)
{
function isAncestorNode(ancestor, node)
{
return ancestor.isAncestor(node);
}

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

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;

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, omitFocus)
{
if (this._suppressRevealAndSelect)
return;

if (!this._includeRootDOMNode && node === this.rootDOMNode && this.rootDOMNode)
node = this.rootDOMNode.firstChild;
if (!node)
return;
var treeElement = this.createTreeElementFor(node);
if (!treeElement)
return;

treeElement.revealAndSelect(omitFocus);
},

_treeElementFromEvent: function(event)
{
var scrollContainer = this.element.parentElement;





var x = scrollContainer.totalOffsetLeft() + scrollContainer.offsetWidth - 36;

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;
}

WebInspector.domAgent.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.domAgent.hideDOMNodeHighlight();
},

_ondragstart: function(event)
{
if (!window.getSelection().isCollapsed)
return false;
if (event.target.nodeName === "A")
return false;

var treeElement = this._treeElementFromEvent(event);
if (!treeElement)
return false;

if (!this._isValidDragSourceOrTarget(treeElement))
return false;

if (treeElement.representedObject.nodeName() === "BODY" || treeElement.representedObject.nodeName() === "HEAD")
return false;

event.dataTransfer.setData("text/plain", treeElement.listItemElement.textContent);
event.dataTransfer.effectAllowed = "copyMove";
this._treeElementBeingDragged = treeElement;

WebInspector.domAgent.hideDOMNodeHighlight();

return true;
},

_ondragover: function(event)
{
if (!this._treeElementBeingDragged)
return false;

var treeElement = this._treeElementFromEvent(event);
if (!this._isValidDragSourceOrTarget(treeElement))
return false;

var node = treeElement.representedObject;
while (node) {
if (node === this._treeElementBeingDragged.representedObject)
return false;
node = node.parentNode;
}

treeElement.updateSelection();
treeElement.listItemElement.addStyleClass("elements-drag-over");
this._dragOverTreeElement = treeElement;
event.preventDefault();
event.dataTransfer.dropEffect = 'move';
return false;
},

_ondragleave: function(event)
{
this._clearDragOverTreeElementMarker();
event.preventDefault();
return false;
},

_isValidDragSourceOrTarget: function(treeElement)
{
if (!treeElement)
return false;

var node = treeElement.representedObject;
if (!(node instanceof WebInspector.DOMNode))
return false;

if (!node.parentNode || node.parentNode.nodeType() !== Node.ELEMENT_NODE)
return false;

return true;
},

_ondrop: function(event)
{
event.preventDefault();
var treeElement = this._treeElementFromEvent(event);
if (treeElement)
this._doMove(treeElement);
},

_doMove: function(treeElement)
{
if (!this._treeElementBeingDragged)
return;

var parentNode;
var anchorNode;

if (treeElement._elementCloseTag) {

parentNode = treeElement.representedObject;
} else {
var dragTargetNode = treeElement.representedObject;
parentNode = dragTargetNode.parentNode;
anchorNode = dragTargetNode;
}

var wasExpanded = this._treeElementBeingDragged.expanded;
this._treeElementBeingDragged.representedObject.moveTo(parentNode, anchorNode, this._selectNodeAfterEdit.bind(this, null, wasExpanded));

delete this._treeElementBeingDragged;
},

_ondragend: function(event)
{
event.preventDefault();
this._clearDragOverTreeElementMarker();
delete this._treeElementBeingDragged;
},

_clearDragOverTreeElementMarker: function()
{
if (this._dragOverTreeElement) {
this._dragOverTreeElement.updateSelection();
this._dragOverTreeElement.listItemElement.removeStyleClass("elements-drag-over");
delete this._dragOverTreeElement;
}
},


_onkeydown: function(event)
{
var keyboardEvent =   (event);
var node = this.selectedDOMNode();
var treeElement = this.getCachedTreeElement(node);
if (!treeElement)
return;

if (!treeElement._editing && WebInspector.KeyboardShortcut.hasNoModifiers(keyboardEvent) && keyboardEvent.keyCode === WebInspector.KeyboardShortcut.Keys.H.code) {
this._toggleHideShortcut(node);
event.consume(true);
return;
}
},

_contextMenuEventFired: function(event)
{
if (!this._showInElementsPanelEnabled)
return;

var treeElement = this._treeElementFromEvent(event);
if (!treeElement)
return;

function focusElement()
{

WebInspector.showPanel("elements");
WebInspector.domAgent.inspectElement(treeElement.representedObject.id);
}
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in Elements panel" : "Reveal in Elements Panel"), focusElement.bind(this));
contextMenu.show();
},

populateContextMenu: function(contextMenu, event)
{
var treeElement = this._treeElementFromEvent(event);
if (!treeElement)
return;

var isTag = treeElement.representedObject.nodeType() === Node.ELEMENT_NODE;
var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (textNode && textNode.hasStyleClass("bogus"))
textNode = null;
var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-comment");
contextMenu.appendApplicableItems(event.target);
if (textNode) {
contextMenu.appendSeparator();
treeElement._populateTextContextMenu(contextMenu, textNode);
} else if (isTag) {
contextMenu.appendSeparator();
treeElement._populateTagContextMenu(contextMenu, event);
} else if (commentNode) {
contextMenu.appendSeparator();
treeElement._populateNodeContextMenu(contextMenu, textNode);
}
},

adjustCollapsedRange: function()
{
},

_updateModifiedNodes: function()
{
if (this._elementsTreeUpdater)
this._elementsTreeUpdater._updateModifiedNodes();
},

_populateContextMenu: function(contextMenu, node)
{
if (this._contextMenuCallback)
this._contextMenuCallback(contextMenu, node);
},

handleShortcut: function(event)
{
var node = this.selectedDOMNode();
var treeElement = this.getCachedTreeElement(node);
if (!node || !treeElement)
return;

if (event.keyIdentifier === "F2") {
this._toggleEditAsHTML(node);
event.handled = true;
return;
}

if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && node.parentNode) {
if (event.keyIdentifier === "Up" && node.previousSibling) {
node.moveTo(node.parentNode, node.previousSibling, this._selectNodeAfterEdit.bind(this, null, treeElement.expanded));
event.handled = true;
return;
}
if (event.keyIdentifier === "Down" && node.nextSibling) {
node.moveTo(node.parentNode, node.nextSibling.nextSibling, this._selectNodeAfterEdit.bind(this, null, treeElement.expanded));
event.handled = true;
return;
}
}
},

_toggleEditAsHTML: function(node)
{
var treeElement = this.getCachedTreeElement(node);
if (!treeElement)
return;

if (treeElement._editing && treeElement._htmlEditElement && WebInspector.isBeingEdited(treeElement._htmlEditElement))
treeElement._editing.commit();
else
treeElement._editAsHTML();
},

_selectNodeAfterEdit: function(fallbackNode, wasExpanded, error, nodeId)
{
if (error)
return;


this._updateModifiedNodes();

var newNode = WebInspector.domAgent.nodeForId(nodeId) || fallbackNode;
if (!newNode)
return;

this.selectDOMNode(newNode, true);

var newTreeItem = this.findTreeElement(newNode);
if (wasExpanded) {
if (newTreeItem)
newTreeItem.expand();
}
return newTreeItem;
},


_toggleHideShortcut: function(node, userCallback)
{
function resolvedNode(object)
{
if (!object)
return;

function toggleClassAndInjectStyleRule()
{
const className = "__web-inspector-hide-shortcut__";
const styleTagId = "__web-inspector-hide-shortcut-style__";
const styleRule = ".__web-inspector-hide-shortcut__, .__web-inspector-hide-shortcut__ * { visibility: hidden !important; }";

this.classList.toggle(className);

var style = document.head.querySelector("style#" + styleTagId);
if (style)
return;

style = document.createElement("style");
style.id = styleTagId;
style.type = "text/css";
style.innerHTML = styleRule;
document.head.appendChild(style);
}

object.callFunction(toggleClassAndInjectStyleRule, undefined, userCallback);
object.release();
}

WebInspector.RemoteObject.resolveNode(node, "", resolvedNode);
},

__proto__: TreeOutline.prototype
}


WebInspector.ElementsTreeOutline.ElementDecorator = function()
{
}

WebInspector.ElementsTreeOutline.ElementDecorator.prototype = {

decorate: function(node)
{
},


decorateAncestor: function(node)
{
}
}


WebInspector.ElementsTreeOutline.PseudoStateDecorator = function()
{
WebInspector.ElementsTreeOutline.ElementDecorator.call(this);
}

WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName = "pseudoState";

WebInspector.ElementsTreeOutline.PseudoStateDecorator.prototype = {
decorate: function(node)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return null;
var propertyValue = node.getUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
if (!propertyValue)
return null;
return WebInspector.UIString("Element state: %s", ":" + propertyValue.join(", :"));
},

decorateAncestor: function(node)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return null;

var descendantCount = node.descendantUserPropertyCount(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
if (!descendantCount)
return null;
if (descendantCount === 1)
return WebInspector.UIString("%d descendant with forced state", descendantCount);
return WebInspector.UIString("%d descendants with forced state", descendantCount);
},

__proto__: WebInspector.ElementsTreeOutline.ElementDecorator.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) {
this._updateSearchHighlight(false);
delete this._highlightResult; 
}

this._searchQuery = searchQuery;
this._searchHighlightsVisible = true;
this.updateTitle(true);
},

hideSearchHighlights: function()
{
delete this._searchHighlightsVisible;
this._updateSearchHighlight(false);
},

_updateSearchHighlight: function(show)
{
if (!this._highlightResult)
return;

function updateEntryShow(entry)
{
switch (entry.type) {
case "added":
entry.parent.insertBefore(entry.node, entry.nextSibling);
break;
case "changed":
entry.node.textContent = entry.newText;
break;
}
}

function updateEntryHide(entry)
{
switch (entry.type) {
case "added":
if (entry.node.parentElement)
entry.node.parentElement.removeChild(entry.node);
break;
case "changed":
entry.node.textContent = entry.oldText;
break;
}
}


if (show) {
for (var i = 0, size = this._highlightResult.length; i < size; ++i)
updateEntryShow(this._highlightResult[i]);
} else {
for (var i = (this._highlightResult.length - 1); i >= 0; --i)
updateEntryHide(this._highlightResult[i]);
}
},

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;
},

updateSelection: function()
{
var listItemElement = this.listItemElement;
if (!listItemElement)
return;

if (!this._readyToUpdateSelection) {
if (document.body.offsetWidth > 0)
this._readyToUpdateSelection = true;
else {


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();
this.listItemElement.draggable = true;
},

_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;
this.representedObject.getChildNodes(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 || !this.treeOutline._visible)
return;

this._updateChildrenInProgress = true;
var selectedNode = this.treeOutline.selectedDOMNode();
var originalScrollTop = 0;
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 === selectedNode)
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();

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 button = document.createElement("button");
button.className = "show-all-nodes";
button.value = "";
var item = new TreeElement(button, null, false);
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);
},

expandRecursively: function()
{
function callback()
{
TreeElement.prototype.expandRecursively.call(this, Number.MAX_VALUE);
}

this.representedObject.getSubtree(-1, callback.bind(this));
},

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) {
var tagSpans = this.listItemElement.getElementsByClassName("webkit-html-tag-name");
if (tagSpans.length)
tagSpans[0].scrollIntoViewIfNeeded(false);
else
this.listItemElement.scrollIntoViewIfNeeded(false);
}
},

onselect: function(selectedByUser)
{
this.treeOutline.suppressRevealAndSelect = true;
this.treeOutline.selectDOMNode(this.representedObject, selectedByUser);
if (selectedByUser)
WebInspector.domAgent.highlightDOMNode(this.representedObject.id);
this.updateSelection();
this.treeOutline.suppressRevealAndSelect = false;
return true;
},

ondelete: function()
{
var startTagTreeElement = this.treeOutline.findTreeElement(this.representedObject);
startTagTreeElement ? startTagTreeElement.remove() : this.remove();
return true;
},

onenter: function()
{


if (this._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");
this.treeOutline.selectDOMNode(this.representedObject, true);
}


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.selectedDOMNode() != 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");


var treeElement = this._elementCloseTag ? this.treeOutline.findTreeElement(this.representedObject) : this;
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add attribute" : "Add Attribute"), this._addNewAttribute.bind(treeElement));
if (attribute && !newAttribute)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit attribute" : "Edit Attribute"), this._startEditingAttribute.bind(this, attribute, event.target));
contextMenu.appendSeparator();
if (this.treeOutline._setPseudoClassCallback) {
var pseudoSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Force element state" : "Force Element State"));
this._populateForcedPseudoStateItems(pseudoSubMenu);
contextMenu.appendSeparator();
}

this._populateNodeContextMenu(contextMenu);
this.treeOutline._populateContextMenu(contextMenu, this.representedObject);

contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Scroll into view" : "Scroll into View"), this._scrollIntoView.bind(this)); 
},

_populateForcedPseudoStateItems: function(subMenu)
{
const pseudoClasses = ["active", "hover", "focus", "visited"];
var node = this.representedObject;
var forcedPseudoState = (node ? node.getUserProperty("pseudoState") : null) || [];
for (var i = 0; i < pseudoClasses.length; ++i) {
var pseudoClassForced = forcedPseudoState.indexOf(pseudoClasses[i]) >= 0;
subMenu.appendCheckboxItem(":" + pseudoClasses[i], this.treeOutline._setPseudoClassCallback.bind(null, node.id, pseudoClasses[i], !pseudoClassForced), pseudoClassForced, false);
}
},

_populateTextContextMenu: function(contextMenu, textNode)
{
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit text" : "Edit Text"), this._startEditingTextNode.bind(this, textNode));
this._populateNodeContextMenu(contextMenu);
},

_populateNodeContextMenu: function(contextMenu)
{

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("Copy XPath"), this._copyXPath.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this));
},

_startEditing: function()
{
if (this.treeOutline.selectedDOMNode() !== 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");
this._buildAttributeDOM(container, " ", "");
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);
attr.scrollIntoViewIfNeeded(true);
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.textContent;

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);

var config = new WebInspector.EditingConfig(this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);

function handleKeyDownEvents(event)
{
var isMetaOrCtrl = WebInspector.isMac() ?
event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl))
return "commit";
else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
return "cancel";
else if (event.keyIdentifier === "U+0009") 
return "move-" + (event.shiftKey ? "backward" : "forward");
else {
WebInspector.handleElementValueModifications(event, attribute);
return "";
}
}

config.customFinishHandler = handleKeyDownEvents.bind(this);

this._editing = WebInspector.startEditing(attribute, config);

window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1);

return true;
},


_startEditingTextNode: function(textNodeElement)
{
if (WebInspector.isBeingEdited(textNodeElement))
return true;

var textNode = this.representedObject;


if (textNode.nodeType() === Node.ELEMENT_NODE && textNode.firstChild)
textNode = textNode.firstChild;

var container = textNodeElement.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (container)
container.textContent = textNode.nodeValue(); 
var config = new WebInspector.EditingConfig(this._textNodeEditingCommitted.bind(this, textNode), this._editingCancelled.bind(this));
this._editing = WebInspector.startEditing(textNodeElement, config);
window.getSelection().setBaseAndExtent(textNodeElement, 0, textNodeElement, 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);

var config = new WebInspector.EditingConfig(editingComitted.bind(this), editingCancelled.bind(this), tagName);
this._editing = WebInspector.startEditing(tagNameElement, config);
window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1);
return true;
},

_startEditingAsHTML: function(commitCallback, error, initialValue)
{
if (error)
return;
if (this._editing)
return;

function consume(event)
{
if (event.eventPhase === Event.AT_TARGET)
event.consume(true);
}

initialValue = this._convertWhitespaceToEntities(initialValue);

this._htmlEditElement = document.createElement("div");
this._htmlEditElement.className = "source-code elements-tree-editor";


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.treeOutline.childrenListElement.parentElement.addEventListener("mousedown", consume, false);

this.updateSelection();


function commit(element, newValue)
{
commitCallback(initialValue, newValue);
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.treeOutline.childrenListElement.parentElement.removeEventListener("mousedown", consume, false);
this.updateSelection();
}

var config = new WebInspector.EditingConfig(commit.bind(this), dispose.bind(this));
config.setMultilineOptions(initialValue, { name: "xml", htmlMode: true }, "web-inspector-html", true, true);
this._editing = WebInspector.startEditing(this._htmlEditElement, config);
},

_attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection)
{
delete this._editing;

var treeOutline = this.treeOutline;

function moveToNextAttributeIfNeeded(error)
{
if (error)
this._editingCancelled(element, attributeName);

if (!moveDirection)
return;

treeOutline._updateModifiedNodes();


var attributes = this.representedObject.attributes();
for (var i = 0; i < attributes.length; ++i) {
if (attributes[i].name !== attributeName)
continue;

if (moveDirection === "backward") {
if (i === 0)
this._startEditingTagName();
else
this._triggerEditAttribute(attributes[i - 1].name);
} else {
if (i === attributes.length - 1)
this._addNewAttribute();
else
this._triggerEditAttribute(attributes[i + 1].name);
}
return;
}


if (moveDirection === "backward") {
if (newText === " ") {

if (attributes.length > 0)
this._triggerEditAttribute(attributes[attributes.length - 1].name);
} else {

if (attributes.length > 1)
this._triggerEditAttribute(attributes[attributes.length - 2].name);
}
} else if (moveDirection === "forward") {
if (!/^\s*$/.test(newText))
this._addNewAttribute();
else
this._startEditingTagName();
}
}

if (!attributeName.trim() && !newText.trim()) {
element.removeSelf();
moveToNextAttributeIfNeeded.call(this);
return;
}

if (oldText !== newText) {
this.representedObject.setAttribute(attributeName, newText, moveToNextAttributeIfNeeded.bind(this));
return;
}

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") {
this._addNewAttribute();
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(error, nodeId)
{
if (error || !nodeId) {
cancel();
return;
}
var newTreeItem = treeOutline._selectNodeAfterEdit(null, wasExpanded, error, nodeId);
moveToNextAttributeIfNeeded.call(newTreeItem);
}

this.representedObject.setNodeName(newText, changeTagNameCallback);
},


_textNodeEditingCommitted: function(textNode, element, newText)
{
delete this._editing;

function callback()
{
this.updateTitle();
}
textNode.setNodeValue(newText, callback.bind(this));
},


_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(onlySearchQueryChanged)
{


if (this._editing)
return;

if (onlySearchQueryChanged) {
if (this._highlightResult)
this._updateSearchHighlight(false);
} else {
var highlightElement = document.createElement("span");
highlightElement.className = "highlight";
highlightElement.appendChild(this._nodeTitleInfo(WebInspector.linkifyURLAsNode).titleDOM);
this.title = highlightElement;
this._updateDecorations();
delete this._highlightResult;
}

delete this.selectionElement;
if (this.selected)
this.updateSelection();
this._preventFollowingLinksOnDoubleClick();
this._highlightSearchResults();
},

_createDecoratorElement: function()
{
var node = this.representedObject;
var decoratorMessages = [];
var parentDecoratorMessages = [];
for (var i = 0; i < this.treeOutline._nodeDecorators.length; ++i) {
var decorator = this.treeOutline._nodeDecorators[i];
var message = decorator.decorate(node);
if (message) {
decoratorMessages.push(message);
continue;
}

if (this.expanded || this._elementCloseTag)
continue;

message = decorator.decorateAncestor(node);
if (message)
parentDecoratorMessages.push(message)
}
if (!decoratorMessages.length && !parentDecoratorMessages.length)
return null;

var decoratorElement = document.createElement("div");
decoratorElement.addStyleClass("elements-gutter-decoration");
if (!decoratorMessages.length)
decoratorElement.addStyleClass("elements-has-decorated-children");
decoratorElement.title = decoratorMessages.concat(parentDecoratorMessages).join("\n");
return decoratorElement;
},

_updateDecorations: function()
{
if (this._decoratorElement && this._decoratorElement.parentElement)
this._decoratorElement.parentElement.removeChild(this._decoratorElement);
this._decoratorElement = this._createDecoratorElement();
if (this._decoratorElement && this.listItemElement)
this.listItemElement.insertBefore(this._decoratorElement, this.listItemElement.firstChild);
},


_buildAttributeDOM: function(parentElement, name, value, node, linkify)
{
var hasText = (value.length > 0);
var attrSpanElement = parentElement.createChild("span", "webkit-html-attribute");
var attrNameElement = attrSpanElement.createChild("span", "webkit-html-attribute-name");
attrNameElement.textContent = name;

if (hasText)
attrSpanElement.appendChild(document.createTextNode("=\u200B\""));

if (linkify && (name === "src" || name === "href")) {
var rewrittenHref = node.resolveURL(value);
value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
if (rewrittenHref === null) {
var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
attrValueElement.textContent = value;
} else {
if (value.startsWith("data:"))
value = value.trimMiddle(60);
attrSpanElement.appendChild(linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName().toLowerCase() === "a"));
}
} else {
value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
attrValueElement.textContent = value;
}

if (hasText)
attrSpanElement.appendChild(document.createTextNode("\""));
},


_buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeElement, linkify)
{
var node =   (this.representedObject);
var classes = [ "webkit-html-tag" ];
if (isClosingTag && isDistinctTreeElement)
classes.push("close");
if (node.isInShadowTree())
classes.push("shadow");
var tagElement = parentElement.createChild("span", classes.join(" "));
tagElement.appendChild(document.createTextNode("<"));
var tagNameElement = tagElement.createChild("span", isClosingTag ? "" : "webkit-html-tag-name");
tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName;
if (!isClosingTag && node.hasAttributes()) {
var attributes = node.attributes();
for (var i = 0; i < attributes.length; ++i) {
var attr = attributes[i];
tagElement.appendChild(document.createTextNode(" "));
this._buildAttributeDOM(tagElement, attr.name, attr.value, node, linkify);
}
}
tagElement.appendChild(document.createTextNode(">"));
parentElement.appendChild(document.createTextNode("\u200B"));
},

_convertWhitespaceToEntities: function(text)
{
var result = "";
var lastIndexAfterEntity = 0;
var charToEntity = WebInspector.ElementsTreeOutline.MappedCharToEntity;
for (var i = 0, size = text.length; i < size; ++i) {
var char = text.charAt(i);
if (charToEntity[char]) {
result += text.substring(lastIndexAfterEntity, i) + "&" + charToEntity[char] + ";";
lastIndexAfterEntity = i + 1;
}
}
if (result) {
result += text.substring(lastIndexAfterEntity);
return result;
}
return text;
},

_nodeTitleInfo: function(linkify)
{
var node = this.representedObject;
var info = {titleDOM: document.createDocumentFragment(), hasChildren: this.hasChildren};

switch (node.nodeType()) {
case Node.ATTRIBUTE_NODE:
var value = node.value || "\u200B"; 
this._buildAttributeDOM(info.titleDOM, node.name, value);
break;

case Node.ELEMENT_NODE:
var tagName = node.nodeNameInCorrectCase();
if (this._elementCloseTag) {
this._buildTagDOM(info.titleDOM, tagName, true, true);
info.hasChildren = false;
break;
}

this._buildTagDOM(info.titleDOM, tagName, false, false, linkify);

var textChild = this._singleTextChild(node);
var showInlineText = textChild && textChild.nodeValue().length < Preferences.maxInlineTextChildLength && !this.hasChildren;

if (!this.expanded && (!showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]))) {
if (this.hasChildren) {
var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node bogus");
textNodeElement.textContent = "\u2026";
info.titleDOM.appendChild(document.createTextNode("\u200B"));
}
this._buildTagDOM(info.titleDOM, tagName, true, false);
}




if (showInlineText) {
var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node");
textNodeElement.textContent = this._convertWhitespaceToEntities(textChild.nodeValue());
info.titleDOM.appendChild(document.createTextNode("\u200B"));
this._buildTagDOM(info.titleDOM, tagName, true, false);
info.hasChildren = false;
}
break;

case Node.TEXT_NODE:
if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") {
var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-js-node");
newNode.textContent = node.nodeValue();

var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript", true);
javascriptSyntaxHighlighter.syntaxHighlightNode(newNode);
} else if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "style") {
var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-css-node");
newNode.textContent = node.nodeValue();

var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/css", true);
cssSyntaxHighlighter.syntaxHighlightNode(newNode);
} else {
info.titleDOM.appendChild(document.createTextNode("\""));
var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node");
textNodeElement.textContent = this._convertWhitespaceToEntities(node.nodeValue());
info.titleDOM.appendChild(document.createTextNode("\""));
}
break;

case Node.COMMENT_NODE:
var commentElement = info.titleDOM.createChild("span", "webkit-html-comment");
commentElement.appendChild(document.createTextNode("<!--" + node.nodeValue() + "-->"));
break;

case Node.DOCUMENT_TYPE_NODE:
var docTypeElement = info.titleDOM.createChild("span", "webkit-html-doctype");
docTypeElement.appendChild(document.createTextNode("<!DOCTYPE " + node.nodeName()));
if (node.publicId) {
docTypeElement.appendChild(document.createTextNode(" PUBLIC \"" + node.publicId + "\""));
if (node.systemId)
docTypeElement.appendChild(document.createTextNode(" \"" + node.systemId + "\""));
} else if (node.systemId)
docTypeElement.appendChild(document.createTextNode(" SYSTEM \"" + node.systemId + "\""));

if (node.internalSubset)
docTypeElement.appendChild(document.createTextNode(" [" + node.internalSubset + "]"));

docTypeElement.appendChild(document.createTextNode(">"));
break;

case Node.CDATA_SECTION_NODE:
var cdataElement = info.titleDOM.createChild("span", "webkit-html-text-node");
cdataElement.appendChild(document.createTextNode("<![CDATA[" + node.nodeValue() + "]]>"));
break;
case Node.DOCUMENT_FRAGMENT_NODE:
var fragmentElement = info.titleDOM.createChild("span", "webkit-html-fragment");
fragmentElement.textContent = node.nodeNameInCorrectCase().collapseWhitespace();
if (node.isInShadowTree())
fragmentElement.addStyleClass("shadow");
break;
default:
info.titleDOM.appendChild(document.createTextNode(node.nodeNameInCorrectCase().collapseWhitespace()));
}
return info;
},

_singleTextChild: function(node)
{
if (!node)
return null;

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

if (node.hasShadowRoots())
return null;

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

_showInlineText: function(node)
{
if (node.nodeType() === Node.ELEMENT_NODE) {
var textChild = this._singleTextChild(node);
if (textChild && textChild.nodeValue().length < Preferences.maxInlineTextChildLength)
return true;
}
return false;
},

remove: function()
{
var parentElement = this.parent;
if (!parentElement)
return;

var self = this;
function removeNodeCallback(error, removedNodeId)
{
if (error)
return;

parentElement.removeChild(self);
parentElement.adjustCollapsedRange();
}

if (!this.representedObject.parentNode || this.representedObject.parentNode.nodeType() === Node.DOCUMENT_NODE)
return;
this.representedObject.removeNode(removeNodeCallback);
},

_editAsHTML: function()
{
var treeOutline = this.treeOutline;
var node = this.representedObject;
var parentNode = node.parentNode;
var index = node.index;
var wasExpanded = this.expanded;

function selectNode(error, nodeId)
{
if (error)
return;


treeOutline._updateModifiedNodes();

var newNode = parentNode ? parentNode.children[index] || parentNode : null;
if (!newNode)
return;

treeOutline.selectDOMNode(newNode, true);

if (wasExpanded) {
var newTreeItem = treeOutline.findTreeElement(newNode);
if (newTreeItem)
newTreeItem.expand();
}
}

function commitChange(initialValue, value)
{
if (initialValue !== value)
node.setOuterHTML(value, selectNode);
else
return;
}

node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange));
},

_copyHTML: function()
{
this.representedObject.copyNode();
},

_copyXPath: function()
{
this.representedObject.copyXPath(true);
},

_highlightSearchResults: function()
{
if (!this._searchQuery || !this._searchHighlightsVisible)
return;
if (this._highlightResult) {
this._updateSearchHighlight(true);
return;
}

var text = this.listItemElement.textContent;
var regexObject = createPlainTextSearchRegex(this._searchQuery, "gi");

var offset = 0;
var match = regexObject.exec(text);
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}


if (!matchRanges.length)
matchRanges.push({ offset: 0, length: text.length });

this._highlightResult = [];
WebInspector.highlightSearchResults(this.listItemElement, matchRanges, this._highlightResult);
},

_scrollIntoView: function()
{
function scrollIntoViewCallback(object)
{
function scrollIntoView()
{
this.scrollIntoViewIfNeeded(true);
}

if (object)
object.callFunction(scrollIntoView);
}

var node =   (this.representedObject);
WebInspector.RemoteObject.resolveNode(node, "", scrollIntoViewCallback);
},

__proto__: TreeElement.prototype
}


WebInspector.ElementsTreeUpdater = function(treeOutline)
{
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeInserted, this._nodeInserted, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributesUpdated, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._attributesUpdated, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.CharacterDataModified, this._characterDataModified, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);

this._treeOutline = treeOutline;
this._recentlyModifiedNodes = new Map();
}

WebInspector.ElementsTreeUpdater.prototype = {


_nodeModified: function(node, isUpdated, parentNode)
{
if (this._treeOutline._visible)
this._updateModifiedNodesSoon();

var entry =   (this._recentlyModifiedNodes.get(node));
if (!entry) {
entry = new WebInspector.ElementsTreeUpdater.UpdateEntry(isUpdated, parentNode);
this._recentlyModifiedNodes.put(node, entry);
return;
}

entry.isUpdated |= isUpdated;
if (parentNode)
entry.parent = parentNode;
},

_documentUpdated: function(event)
{
var inspectedRootDocument = event.data;

this._reset();

if (!inspectedRootDocument)
return;

this._treeOutline.rootDOMNode = inspectedRootDocument;
},

_attributesUpdated: function(event)
{
this._nodeModified(event.data.node, true);
},

_characterDataModified: function(event)
{
this._nodeModified(event.data, true);
},

_nodeInserted: function(event)
{
this._nodeModified(event.data, false, event.data.parentNode);
},

_nodeRemoved: function(event)
{
this._nodeModified(event.data.node, false, event.data.parent);
},

_childNodeCountUpdated: function(event)
{
var treeElement = this._treeOutline.findTreeElement(event.data);
if (treeElement)
treeElement.hasChildren = event.data.hasChildNodes();
},

_updateModifiedNodesSoon: function()
{
if (this._updateModifiedNodesTimeout)
return;
this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 50);
},

_updateModifiedNodes: function()
{
if (this._updateModifiedNodesTimeout) {
clearTimeout(this._updateModifiedNodesTimeout);
delete this._updateModifiedNodesTimeout;
}

var updatedParentTreeElements = [];

var hidePanelWhileUpdating = this._recentlyModifiedNodes.size() > 10;
if (hidePanelWhileUpdating) {
var treeOutlineContainerElement = this._treeOutline.element.parentNode;
this._treeOutline.element.addStyleClass("hidden");
var originalScrollTop = treeOutlineContainerElement ? treeOutlineContainerElement.scrollTop : 0;
}

var keys = this._recentlyModifiedNodes.keys();
for (var i = 0, size = keys.length; i < size; ++i) {
var node = keys[i];
var entry = this._recentlyModifiedNodes.get(node);
var parent = entry.parent;

if (parent === this._treeOutline._rootDOMNode) {

this._treeOutline.update();
this._treeOutline.element.removeStyleClass("hidden");
return;
}

if (entry.isUpdated) {
var nodeItem = this._treeOutline.findTreeElement(node);
if (nodeItem)
nodeItem.updateTitle();
}

if (!parent)
continue;

var parentNodeItem = this._treeOutline.findTreeElement(parent);
if (parentNodeItem && !parentNodeItem.alreadyUpdatedChildren) {
parentNodeItem.updateChildren();
parentNodeItem.alreadyUpdatedChildren = true;
updatedParentTreeElements.push(parentNodeItem);
}
}

for (var i = 0; i < updatedParentTreeElements.length; ++i)
delete updatedParentTreeElements[i].alreadyUpdatedChildren;

if (hidePanelWhileUpdating) {
this._treeOutline.element.removeStyleClass("hidden");
if (originalScrollTop)
treeOutlineContainerElement.scrollTop = originalScrollTop;
this._treeOutline.updateSelection();
}
this._recentlyModifiedNodes.clear();
},

_reset: function()
{
this._treeOutline.rootDOMNode = null;
this._treeOutline.selectDOMNode(null, false);
WebInspector.domAgent.hideDOMNodeHighlight();
this._recentlyModifiedNodes.clear();
}
}


WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent)
{
this.isUpdated = isUpdated;
if (parent)
this.parent = parent;
}





WebInspector.DOMPresentationUtils = {}

WebInspector.DOMPresentationUtils.decorateNodeLabel = function(node, parentElement)
{
var title = node.nodeNameInCorrectCase();

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;
}


WebInspector.DOMPresentationUtils.createSpansForNodeTitle = function(container, nodeTitle)
{
var match = nodeTitle.match(/([^#.]+)(#[^.]+)?(\..*)?/);
container.createChild("span", "webkit-html-tag-name").textContent = match[1];
if (match[2])
container.createChild("span", "webkit-html-attribute-value").textContent = match[2];
if (match[3])
container.createChild("span", "webkit-html-attribute-name").textContent = match[3];
}

WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node)
{
var link = document.createElement("span");
link.className = "node-link";
WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link);

link.addEventListener("click", WebInspector.domAgent.inspectElement.bind(WebInspector.domAgent, node.id), false);
link.addEventListener("mouseover", WebInspector.domAgent.highlightDOMNode.bind(WebInspector.domAgent, node.id, "", undefined), false);
link.addEventListener("mouseout", WebInspector.domAgent.hideDOMNodeHighlight.bind(WebInspector.domAgent), false);

return link;
}

WebInspector.DOMPresentationUtils.linkifyNodeById = function(nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return document.createTextNode(WebInspector.UIString("<node>"));
return WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
}


WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(imageURL, showDimensions, userCallback, precomputedDimensions)
{
var resource = WebInspector.resourceTreeModel.resourceForURL(imageURL);
if (!resource) {
userCallback();
return;
}

var imageElement = document.createElement("img");
imageElement.addEventListener("load", buildContent, false);
imageElement.addEventListener("error", errorCallback, false);
resource.populateImageSource(imageElement);

function errorCallback()
{

userCallback();
}

function buildContent()
{
var container = document.createElement("table");
container.className = "image-preview-container";
var naturalWidth = precomputedDimensions ? precomputedDimensions.naturalWidth : imageElement.naturalWidth;
var naturalHeight = precomputedDimensions ? precomputedDimensions.naturalHeight : imageElement.naturalHeight;
var offsetWidth = precomputedDimensions ? precomputedDimensions.offsetWidth : naturalWidth;
var offsetHeight = precomputedDimensions ? precomputedDimensions.offsetHeight : naturalHeight;
var description;
if (showDimensions) {
if (offsetHeight === naturalHeight && offsetWidth === naturalWidth)
description = WebInspector.UIString("%d \xd7 %d pixels", offsetWidth, offsetHeight);
else
description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight);
}

container.createChild("tr").createChild("td", "image-container").appendChild(imageElement);
if (description)
container.createChild("tr").createChild("td").createChild("span", "description").textContent = description;
userCallback(container);
}
}






WebInspector.SidebarSectionTreeElement = function(title, representedObject, hasChildren)
{
TreeElement.call(this, title.escapeHTML(), representedObject || {}, hasChildren);
this.expand();
}

WebInspector.SidebarSectionTreeElement.prototype = {
selectable: false,

collapse: function()
{

},

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);
},

__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;
},

set wait(x)
{
if (x)
this._listItemNode.addStyleClass("wait");
else
this._listItemNode.removeStyleClass("wait");
},

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.subtitleElement.textContent = "";
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);
},

__proto__: TreeElement.prototype
}






WebInspector.Section = function(title, subtitle)
{
this.element = document.createElement("div");
this.element.className = "section";
this.element._section = 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.handleClick.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._expanded) {
this.onpopulate();
this._populated = true;
}
},

onpopulate: function()
{

},

get firstSibling()
{
var parent = this.element.parentElement;
if (!parent)
return null;

var childElement = parent.firstChild;
while (childElement) {
if (childElement._section)
return childElement._section;
childElement = childElement.nextSibling;
}

return null;
},

get lastSibling()
{
var parent = this.element.parentElement;
if (!parent)
return null;

var childElement = parent.lastChild;
while (childElement) {
if (childElement._section)
return childElement._section;
childElement = childElement.previousSibling;
}

return null;
},

get nextSibling()
{
var curElement = this.element;
do {
curElement = curElement.nextSibling;
} while (curElement && !curElement._section);

return curElement ? curElement._section : null;
},

get previousSibling()
{
var curElement = this.element;
do {
curElement = curElement.previousSibling;
} while (curElement && !curElement._section);

return curElement ? curElement._section : null;
},

expand: function()
{
if (this._expanded)
return;
this._expanded = true;
this.element.addStyleClass("expanded");

if (!this._populated) {
this.onpopulate();
this._populated = true;
}
},

collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
this.element.removeStyleClass("expanded");
},

toggleExpanded: function()
{
this.expanded = !this.expanded;
},

handleClick: function(event)
{
this.toggleExpanded();
event.consume();
}
}






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.propertiesTreeOutline = new TreeOutline(this.propertiesElement, true);
this.propertiesTreeOutline.setFocusable(false);
this.propertiesTreeOutline.section = this;

this.element.appendChild(this.propertiesElement);
}

WebInspector.PropertiesSection.prototype = {
__proto__: WebInspector.Section.prototype
}






WebInspector.RemoteObject = function(objectId, type, subtype, value, description, preview)
{
this._type = type;
this._subtype = subtype;
if (objectId) {

this._objectId = objectId;
this._description = description;
this._hasChildren = true;
this._preview = preview;
} else {

console.assert(type !== "object" || value === null);
this._description = description || (value + "");
this._hasChildren = false;
this.value = value;
}
}


WebInspector.RemoteObject.fromPrimitiveValue = function(value)
{
return new WebInspector.RemoteObject(undefined, typeof value, undefined, value);
}


WebInspector.RemoteObject.fromLocalObject = function(value)
{
return new WebInspector.LocalJSONObject(value);
}


WebInspector.RemoteObject.resolveNode = function(node, objectGroup, callback)
{

function mycallback(error, object)
{
if (!callback)
return;

if (error || !object)
callback(null);
else
callback(WebInspector.RemoteObject.fromPayload(object));
}
DOMAgent.resolveNode(node.id, objectGroup, mycallback);
}


WebInspector.RemoteObject.fromPayload = function(payload)
{
console.assert(typeof payload === "object", "Remote object payload should only be an object");

return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
}


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 subtype()
{
return this._subtype;
},


get description()
{
return this._description;
},


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


get preview()
{
return this._preview;
},


getOwnProperties: function(callback)
{
this.doGetProperties(true, callback);
},


getAllProperties: function(callback)
{
this.doGetProperties(false, callback);
},


doGetProperties: function(ownProperties, callback)
{
if (!this._objectId) {
callback([]);
return;
}


function remoteObjectBinder(error, properties, internalProperties)
{
if (error) {
callback(null);
return;
}
var result = [];
for (var i = 0; properties && i < properties.length; ++i) {
var property = properties[i];
if (property.get || property.set) {
if (property.get)
result.push(new WebInspector.RemoteObjectProperty("get " + property.name, WebInspector.RemoteObject.fromPayload(property.get), property));
if (property.set)
result.push(new WebInspector.RemoteObjectProperty("set " + property.name, WebInspector.RemoteObject.fromPayload(property.set), property));
} else
result.push(new WebInspector.RemoteObjectProperty(property.name, WebInspector.RemoteObject.fromPayload(property.value), property));
}
var internalPropertiesResult;
if (internalProperties) {
internalPropertiesResult = [];
for (var i = 0; i < internalProperties.length; i++) {
var property = internalProperties[i];
internalPropertiesResult.push(new WebInspector.RemoteObjectProperty(property.name, WebInspector.RemoteObject.fromPayload(property.value)));
}
}
callback(result, internalPropertiesResult);
}
RuntimeAgent.getProperties(this._objectId, ownProperties, remoteObjectBinder);
},


setPropertyValue: function(name, value, callback)
{
if (!this._objectId) {
callback("Can't set a property of non-object.");
return;
}

RuntimeAgent.evaluate.invoke({expression:value, doNotPauseOnExceptionsAndMuteConsole:true}, evaluatedCallback.bind(this));


function evaluatedCallback(error, result, wasThrown)
{
if (error || wasThrown) {
callback(error || result.description);
return;
}

this.doSetObjectPropertyValue(result, name, callback);

if (result._objectId)
RuntimeAgent.releaseObject(result._objectId);
}
},


doSetObjectPropertyValue: function(result, name, callback)
{


var setPropertyValueFunction = "function(a, b) { this[a] = b; }";


if (result.type === "number" && typeof result.value !== "number")
setPropertyValueFunction = "function(a) { this[a] = " + result.description + "; }";

delete result.description; 
RuntimeAgent.callFunctionOn(this._objectId, setPropertyValueFunction, [{ value:name }, result], true, undefined, undefined, propertySetCallback.bind(this));


function propertySetCallback(error, result, wasThrown)
{
if (error || wasThrown) {
callback(error || result.description);
return;
}
callback();
}
},


pushNodeToFrontend: function(callback)
{
if (this._objectId)
WebInspector.domAgent.pushNodeToFrontend(this._objectId, callback);
else
callback(0);
},

highlightAsDOMNode: function()
{
WebInspector.domAgent.highlightDOMNode(undefined, undefined, this._objectId);
},

hideDOMNodeHighlight: function()
{
WebInspector.domAgent.hideDOMNodeHighlight();
},


callFunction: function(functionDeclaration, args, callback)
{

function mycallback(error, result, wasThrown)
{
if (!callback)
return;

callback((error || wasThrown) ? null : WebInspector.RemoteObject.fromPayload(result));
}

RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, undefined, undefined, mycallback);
},


callFunctionJSON: function(functionDeclaration, args, callback)
{

function mycallback(error, result, wasThrown)
{
callback((error || wasThrown) ? null : result.value);
}

RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, true, false, mycallback);
},

release: function()
{
if (!this._objectId)
return;
RuntimeAgent.releaseObject(this._objectId);
},


arrayLength: function()
{
if (this.subtype !== "array")
return 0;

var matches = this._description.match(/\[([0-9]+)\]/);
if (!matches)
return 0;
return parseInt(matches[1], 10);
}
}



WebInspector.ScopeRemoteObject = function(objectId, scopeRef, type, subtype, value, description, preview)
{
WebInspector.RemoteObject.call(this, objectId, type, subtype, value, description, preview);
this._scopeRef = scopeRef;
this._savedScopeProperties = undefined;
};


WebInspector.ScopeRemoteObject.fromPayload = function(payload, scopeRef)
{
if (scopeRef)
return new WebInspector.ScopeRemoteObject(payload.objectId, scopeRef, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
else
return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
}

WebInspector.ScopeRemoteObject.prototype = {

doGetProperties: function(ownProperties, callback)
{
if (this._savedScopeProperties) {



callback(this._savedScopeProperties.slice(), []);
return;
}


function wrappedCallback(properties, internalProperties)
{
if (this._scopeRef && properties instanceof Array)
this._savedScopeProperties = properties.slice();
callback(properties, internalProperties);
}

WebInspector.RemoteObject.prototype.doGetProperties.call(this, ownProperties, wrappedCallback.bind(this));
},


doSetObjectPropertyValue: function(result, name, callback)
{
var newValue;

switch (result.type) {
case "undefined":
newValue = {};
break;
case "object":
case "function":
newValue = { objectId: result.objectId };
break;
default:
newValue = { value: result.value };
}

DebuggerAgent.setVariableValue(this._scopeRef.number, name, newValue, this._scopeRef.callFrameId, this._scopeRef.functionId, setVariableValueCallback.bind(this));


function setVariableValueCallback(error)
{
if (error) {
callback(error);
return;
}
if (this._savedScopeProperties) {
for (var i = 0; i < this._savedScopeProperties.length; i++) {
if (this._savedScopeProperties[i].name === name)
this._savedScopeProperties[i].value = WebInspector.RemoteObject.fromPayload(result);
}
}
callback();
}
},

__proto__: WebInspector.RemoteObject.prototype
};


WebInspector.ScopeRef = function(number, callFrameId, functionId)
{
this.number = number;
this.callFrameId = callFrameId;
this.functionId = functionId;
}


WebInspector.RemoteObjectProperty = function(name, value, descriptor)
{
this.name = name;
this.value = value;
this.enumerable = descriptor ? !!descriptor.enumerable : true;
this.writable = descriptor ? !!descriptor.writable : true;
if (descriptor && descriptor.wasThrown)
this.wasThrown = true;
}


WebInspector.RemoteObjectProperty.fromPrimitiveValue = function(name, value)
{
return new WebInspector.RemoteObjectProperty(name, WebInspector.RemoteObject.fromPrimitiveValue(value));
}


WebInspector.RemoteObjectProperty.fromScopeValue = function(name, value)
{
var result = new WebInspector.RemoteObjectProperty(name, value);
result.writable = false;
return result;
}








WebInspector.LocalJSONObject = function(value)
{
this._value = value;
}

WebInspector.LocalJSONObject.prototype = {

get description()
{
if (this._cachedDescription)
return this._cachedDescription;

if (this.type === "object") {
switch (this.subtype) {
case "array":
function formatArrayItem(property)
{
return property.value.description;
}
this._cachedDescription = this._concatenate("[", "]", formatArrayItem);
break;
case "date":
this._cachedDescription = "" + this._value;
break;
case "null":
this._cachedDescription = "null";
break;
default:
function formatObjectItem(property)
{
return property.name + ":" + property.value.description;
}
this._cachedDescription = this._concatenate("{", "}", formatObjectItem);
}
} else
this._cachedDescription = String(this._value);

return this._cachedDescription;
},


_concatenate: function(prefix, suffix, formatProperty)
{
const previewChars = 100;

var buffer = prefix;
var children = this._children();
for (var i = 0; i < children.length; ++i) {
var itemDescription = formatProperty(children[i]);
if (buffer.length + itemDescription.length > previewChars) {
buffer += ",\u2026";
break;
}
if (i)
buffer += ", ";
buffer += itemDescription;
}
buffer += suffix;
return buffer;
},


get type()
{
return typeof this._value;
},


get subtype()
{
if (this._value === null)
return "null";

if (this._value instanceof Array)
return "array";

if (this._value instanceof Date)
return "date";

return undefined;
},


get hasChildren()
{
if ((typeof this._value !== "object") || (this._value === null))
return false;
return !!Object.keys(  (this._value)).length;
},


getOwnProperties: function(callback)
{
callback(this._children());
},


getAllProperties: function(callback)
{
callback(this._children());
},


_children: function()
{
if (!this.hasChildren)
return [];
var value =   (this._value);

function buildProperty(propName)
{
return new WebInspector.RemoteObjectProperty(propName, new WebInspector.LocalJSONObject(this._value[propName]));
}
if (!this._cachedChildren)
this._cachedChildren = Object.keys(value).map(buildProperty.bind(this));
return this._cachedChildren;
},


isError: function()
{
return false;
},


arrayLength: function()
{
return this._value instanceof Array ? this._value.length : 0;
}
}






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;
this.skipProto = false;

WebInspector.PropertiesSection.call(this, title || "", subtitle);
}

WebInspector.ObjectPropertiesSection._arrayLoadThreshold = 100;

WebInspector.ObjectPropertiesSection.prototype = {
enableContextMenu: function()
{
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), false);
},

_contextMenuEventFired: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendApplicableItems(this.object);
contextMenu.show();
},

onpopulate: function()
{
this.update();
},

update: function()
{
if (this.object.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
this.propertiesTreeOutline.removeChildren();
WebInspector.ArrayGroupingTreeElement._populateArray(this.propertiesTreeOutline, this.object, 0, this.object.arrayLength() - 1);
return;
}


function callback(properties, internalProperties)
{
if (!properties)
return;
this.updateProperties(properties, internalProperties);
}

if (this.ignoreHasOwnProperty)
this.object.getAllProperties(callback.bind(this));
else
this.object.getOwnProperties(callback.bind(this));
},

updateProperties: function(properties, internalProperties, 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]);
}

this.propertiesTreeOutline.removeChildren();

WebInspector.ObjectPropertyTreeElement.populateWithProperties(this.propertiesTreeOutline,
properties, internalProperties,
rootTreeElementConstructor, rootPropertyComparer,
this.skipProto, this.object);

this.propertiesForTest = properties;

if (!this.propertiesTreeOutline.children.length) {
var title = document.createElement("div");
title.className = "info";
title.textContent = this.emptyPlaceholder;
var infoElement = new TreeElement(title, null, false);
this.propertiesTreeOutline.appendChild(infoElement);
}
},

__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);
this.toggleOnClick = true;
this.selectable = false;
}

WebInspector.ObjectPropertyTreeElement.prototype = {
onpopulate: function()
{
return WebInspector.ObjectPropertyTreeElement.populate(this, this.property.value);
},

ondblclick: function(event)
{
if (this.property.writable)
this.startEditing(event);
},

onattach: function()
{
this.update();
},

update: function()
{
this.nameElement = document.createElement("span");
this.nameElement.className = "name";
this.nameElement.textContent = this.property.name;
if (!this.property.enumerable)
this.nameElement.addStyleClass("dimmed");

var separatorElement = document.createElement("span");
separatorElement.className = "separator";
separatorElement.textContent = ": ";

this.valueElement = document.createElement("span");
this.valueElement.className = "value";

var description = this.property.value.description;

if (this.property.wasThrown)
this.valueElement.textContent = "[Exception: " + description + "]";
else if (this.property.value.type === "string" && typeof description === "string") {
this.valueElement.textContent = "\"" + description.replace(/\n/g, "\u21B5") + "\"";
this.valueElement._originalTextContent = "\"" + description + "\"";
} else if (this.property.value.type === "function" && typeof description === "string") {
this.valueElement.textContent = /.*/.exec(description)[0].replace(/ +$/g, "");
this.valueElement._originalTextContent = description;
} else if (this.property.value.type !== "object" || this.property.value.subtype !== "node") 
this.valueElement.textContent = description;

if (this.property.wasThrown)
this.valueElement.addStyleClass("error");
if (this.property.value.subtype)
this.valueElement.addStyleClass("console-formatted-" + this.property.value.subtype);
else if (this.property.value.type)
this.valueElement.addStyleClass("console-formatted-" + this.property.value.type);

this.valueElement.addEventListener("contextmenu", this._contextMenuFired.bind(this, this.property.value), false);
if (this.property.value.type === "object" && this.property.value.subtype === "node" && this.property.value.description) {
WebInspector.DOMPresentationUtils.createSpansForNodeTitle(this.valueElement, this.property.value.description);
this.valueElement.addEventListener("mousemove", this._mouseMove.bind(this, this.property.value), false);
this.valueElement.addEventListener("mouseout", this._mouseOut.bind(this, this.property.value), false);
} else
this.valueElement.title = description || "";

this.listItemElement.removeChildren();

this.listItemElement.appendChild(this.nameElement);
this.listItemElement.appendChild(separatorElement);
this.listItemElement.appendChild(this.valueElement);
this.hasChildren = this.property.value.hasChildren && !this.property.wasThrown;
},

_contextMenuFired: function(value, event)
{
var contextMenu = new WebInspector.ContextMenu(event);
this.populateContextMenu(contextMenu);
contextMenu.appendApplicableItems(value);
contextMenu.show();
},


populateContextMenu: function(contextMenu)
{
},

_mouseMove: function(event)
{
this.property.value.highlightAsDOMNode();
},

_mouseOut: function(event)
{
this.property.value.hideDOMNodeHighlight();
},

updateSiblings: function()
{
if (this.parent.root)
this.treeOutline.section.update();
else
this.parent.shouldRefreshChildren = true;
},

renderPromptAsBlock: function()
{
return false;
},


elementAndValueToEdit: function(event)
{
return [this.valueElement, (typeof this.valueElement._originalTextContent === "string") ? this.valueElement._originalTextContent : undefined];
},

startEditing: function(event)
{
var elementAndValueToEdit = this.elementAndValueToEdit(event);
var elementToEdit = elementAndValueToEdit[0];
var valueToEdit = elementAndValueToEdit[1];

if (WebInspector.isBeingEdited(elementToEdit) || !this.treeOutline.section.editable || this._readOnly)
return;


if (typeof valueToEdit !== "undefined")
elementToEdit.textContent = valueToEdit;

var context = { expanded: this.expanded, elementToEdit: elementToEdit, previousContent: elementToEdit.textContent };


this.hasChildren = false;

this.listItemElement.addStyleClass("editing-sub-part");

this._prompt = new WebInspector.ObjectPropertyPrompt(this.editingCommitted.bind(this, null, elementToEdit.textContent, context.previousContent, context), this.editingCancelled.bind(this, null, context), this.renderPromptAsBlock());

function blurListener()
{
this.editingCommitted(null, elementToEdit.textContent, context.previousContent, context);
}

var proxyElement = this._prompt.attachAndStartEditing(elementToEdit, blurListener.bind(this));
window.getSelection().setBaseAndExtent(elementToEdit, 0, elementToEdit, 1);
proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this, context), false);
},


isEditing: function()
{
return !!this._prompt;
},

editingEnded: function(context)
{
this._prompt.detach();
delete this._prompt;

this.listItemElement.scrollLeft = 0;
this.listItemElement.removeStyleClass("editing-sub-part");
if (context.expanded)
this.expand();
},

editingCancelled: function(element, context)
{
this.editingEnded(context);
this.update();
},

editingCommitted: function(element, userInput, previousContent, context)
{
if (userInput === previousContent)
return this.editingCancelled(element, context); 

this.editingEnded(context);
this.applyExpression(userInput, true);
},

_promptKeyDown: function(context, event)
{
if (isEnterKey(event)) {
event.consume(true);
return this.editingCommitted(null, context.elementToEdit.textContent, context.previousContent, context);
}
if (event.keyIdentifier === "U+001B") { 
event.consume();
return this.editingCancelled(null, context);
}
},

applyExpression: function(expression, updateInterface)
{
expression = expression.trim();
var expressionLength = expression.length;
function callback(error)
{
if (!updateInterface)
return;

if (error)
this.update();

if (!expressionLength) {

this.parent.removeChild(this);
} else {

this.updateSiblings();
}
};
this.property.parentObject.setPropertyValue(this.property.name, expression.trim(), callback.bind(this));
},

propertyPath: function()
{
if ("_cachedPropertyPath" in this)
return this._cachedPropertyPath;

var current = this;
var result;

do {
if (current.property) {
if (result)
result = current.property.name + "." + result;
else
result = current.property.name;
}
current = current.parent;
} while (current && !current.root);

this._cachedPropertyPath = result;
return result;
},


__proto__: TreeElement.prototype
}


WebInspector.ObjectPropertyTreeElement.populate = function(treeElement, value) {
if (treeElement.children.length && !treeElement.shouldRefreshChildren)
return;

if (value.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
treeElement.removeChildren();
WebInspector.ArrayGroupingTreeElement._populateArray(treeElement, value, 0, value.arrayLength() - 1);
return;
}


function callback(properties, internalProperties)
{
treeElement.removeChildren();
if (!properties)
return;
if (!internalProperties)
internalProperties = [];

WebInspector.ObjectPropertyTreeElement.populateWithProperties(treeElement, properties, internalProperties,
treeElement.treeOutline.section.treeElementConstructor, WebInspector.ObjectPropertiesSection.CompareProperties,
treeElement.treeOutline.section.skipProto, value);
}

value.getOwnProperties(callback);
}


WebInspector.ObjectPropertyTreeElement.populateWithProperties = function(treeElement, properties, internalProperties, treeElementConstructor, comparator, skipProto, value) {
properties.sort(comparator);

for (var i = 0; i < properties.length; ++i) {
if (skipProto && properties[i].name === "__proto__")
continue;
properties[i].parentObject = value;
treeElement.appendChild(new treeElementConstructor(properties[i]));
}
if (value && value.type === "function") {



var hasTargetFunction = false;

if (internalProperties) {
for (var i = 0; i < internalProperties.length; i++) {
if (internalProperties[i].name == "[[TargetFunction]]") {
hasTargetFunction = true;
break;
}
}
}
if (!hasTargetFunction)
treeElement.appendChild(new WebInspector.FunctionScopeMainTreeElement(value));
}
if (internalProperties) {
for (var i = 0; i < internalProperties.length; i++) {
internalProperties[i].parentObject = value;
treeElement.appendChild(new treeElementConstructor(internalProperties[i]));
} 
}
}


WebInspector.FunctionScopeMainTreeElement = function(remoteObject)
{
TreeElement.call(this, "<function scope>", null, false);
this.toggleOnClick = true;
this.selectable = false;
this._remoteObject = remoteObject;
this.hasChildren = true;
}

WebInspector.FunctionScopeMainTreeElement.prototype = {
onpopulate: function()
{
if (this.children.length && !this.shouldRefreshChildren)
return;

function didGetDetails(error, response)
{
if (error) {
console.error(error);
return;
}
this.removeChildren();

var scopeChain = response.scopeChain;
if (!scopeChain)
return;
for (var i = 0; i < scopeChain.length; ++i) {
var scope = scopeChain[i];
var title = null;
var isTrueObject;

switch (scope.type) {
case "local":

title = WebInspector.UIString("Local");
isTrueObject = false;
break;
case "closure":
title = WebInspector.UIString("Closure");
isTrueObject = false;
break;
case "catch":
title = WebInspector.UIString("Catch");
isTrueObject = false;
break;
case "with":
title = WebInspector.UIString("With Block");
isTrueObject = true;
break;
case "global":
title = WebInspector.UIString("Global");
isTrueObject = true;
break;
default:
console.error("Unknown scope type: " + scope.type);
continue;
}

var scopeRef;
if (isTrueObject)
scopeRef = undefined;
else 
scopeRef = new WebInspector.ScopeRef(i, undefined, this._remoteObject.objectId);

var remoteObject = WebInspector.ScopeRemoteObject.fromPayload(scope.object, scopeRef);
if (isTrueObject) {
var property = WebInspector.RemoteObjectProperty.fromScopeValue(title, remoteObject);
property.parentObject = null;
this.appendChild(new this.treeOutline.section.treeElementConstructor(property));
} else {
var scopeTreeElement = new WebInspector.ScopeTreeElement(title, null, remoteObject);
this.appendChild(scopeTreeElement);
}
}

}
DebuggerAgent.getFunctionDetails(this._remoteObject.objectId, didGetDetails.bind(this));
},

__proto__: TreeElement.prototype
}


WebInspector.ScopeTreeElement = function(title, subtitle, remoteObject)
{

TreeElement.call(this, title, null, false);
this.toggleOnClick = true;
this.selectable = false;
this._remoteObject = remoteObject;
this.hasChildren = true;
}

WebInspector.ScopeTreeElement.prototype = {
onpopulate: function()
{
return WebInspector.ObjectPropertyTreeElement.populate(this, this._remoteObject);
},

__proto__: TreeElement.prototype
}


WebInspector.ArrayGroupingTreeElement = function(object, fromIndex, toIndex, propertyCount)
{
TreeElement.call(this, String.sprintf("[%d \u2026 %d]", fromIndex, toIndex), undefined, true);
this._fromIndex = fromIndex;
this._toIndex = toIndex;
this._object = object;
this._readOnly = true;
this._propertyCount = propertyCount;
this._populated = false;
}

WebInspector.ArrayGroupingTreeElement._bucketThreshold = 100;
WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold = 250000;


WebInspector.ArrayGroupingTreeElement._populateArray = function(treeElement, object, fromIndex, toIndex)
{
WebInspector.ArrayGroupingTreeElement._populateRanges(treeElement, object, fromIndex, toIndex, true);
}


WebInspector.ArrayGroupingTreeElement._populateRanges = function(treeElement, object, fromIndex, toIndex, topLevel)
{
object.callFunctionJSON(packRanges, [{value: fromIndex}, {value: toIndex}, {value: WebInspector.ArrayGroupingTreeElement._bucketThreshold}, {value: WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold}], callback.bind(this));


function packRanges(fromIndex, toIndex, bucketThreshold, sparseIterationThreshold)
{
var ownPropertyNames = null;
function doLoop(iterationCallback)
{
if (toIndex - fromIndex < sparseIterationThreshold) {
for (var i = fromIndex; i <= toIndex; ++i) {
if (i in this)
iterationCallback(i);
}
} else {
ownPropertyNames = ownPropertyNames || Object.getOwnPropertyNames(this);
for (var i = 0; i < ownPropertyNames.length; ++i) {
var name = ownPropertyNames[i];
var index = name >>> 0;
if (String(index) === name && fromIndex <= index && index <= toIndex)
iterationCallback(index);
}
}
}

var count = 0;
function countIterationCallback()
{
++count;
}
doLoop.call(this, countIterationCallback);

var bucketSize = count;
if (count <= bucketThreshold)
bucketSize = count;
else
bucketSize = Math.pow(bucketThreshold, Math.ceil(Math.log(count) / Math.log(bucketThreshold)) - 1);

var ranges = [];
count = 0;
var groupStart = -1;
var groupEnd = 0;
function loopIterationCallback(i)
{
if (groupStart === -1)
groupStart = i;

groupEnd = i;
if (++count === bucketSize) {
ranges.push([groupStart, groupEnd, count]);
count = 0;
groupStart = -1;
}
}
doLoop.call(this, loopIterationCallback);

if (count > 0)
ranges.push([groupStart, groupEnd, count]);
return ranges;
}

function callback(ranges)
{
if (ranges.length == 1)
WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeElement, object, ranges[0][0], ranges[0][1]);
else {
for (var i = 0; i < ranges.length; ++i) {
var fromIndex = ranges[i][0];
var toIndex = ranges[i][1];
var count = ranges[i][2];
if (fromIndex == toIndex)
WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeElement, object, fromIndex, toIndex);
else
treeElement.appendChild(new WebInspector.ArrayGroupingTreeElement(object, fromIndex, toIndex, count));
}
}
if (topLevel)
WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties(treeElement, object);
}
}


WebInspector.ArrayGroupingTreeElement._populateAsFragment = function(treeElement, object, fromIndex, toIndex)
{
object.callFunction(buildArrayFragment, [{value: fromIndex}, {value: toIndex}, {value: WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold}], processArrayFragment.bind(this));


function buildArrayFragment(fromIndex, toIndex, sparseIterationThreshold)
{
var result = Object.create(null);
if (toIndex - fromIndex < sparseIterationThreshold) {
for (var i = fromIndex; i <= toIndex; ++i) {
if (i in this)
result[i] = this[i];
}
} else {
var ownPropertyNames = Object.getOwnPropertyNames(this);
for (var i = 0; i < ownPropertyNames.length; ++i) {
var name = ownPropertyNames[i];
var index = name >>> 0;
if (String(index) === name && fromIndex <= index && index <= toIndex)
result[index] = this[index];
}
}
return result;
}


function processArrayFragment(arrayFragment)
{
arrayFragment.getAllProperties(processProperties.bind(this));
}


function processProperties(properties, internalProperties)
{
if (!properties)
return;

properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
properties[i].parentObject = this._object;
var childTreeElement = new treeElement.treeOutline.section.treeElementConstructor(properties[i]);
childTreeElement._readOnly = true;
treeElement.appendChild(childTreeElement);
}
}
}


WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties = function(treeElement, object)
{
object.callFunction(buildObjectFragment, undefined, processObjectFragment.bind(this));


function buildObjectFragment()
{
var result = Object.create(this.__proto__);
var names = Object.getOwnPropertyNames(this);
for (var i = 0; i < names.length; ++i) {
var name = names[i];

if (String(name >>> 0) === name && name >>> 0 !== 0xffffffff)
continue;
var descriptor = Object.getOwnPropertyDescriptor(this, name);
if (descriptor)
Object.defineProperty(result, name, descriptor);
}
return result;
}

function processObjectFragment(arrayFragment)
{
arrayFragment.getOwnProperties(processProperties.bind(this));
}


function processProperties(properties, internalProperties)
{
if (!properties)
return;

properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
properties[i].parentObject = this._object;
var childTreeElement = new treeElement.treeOutline.section.treeElementConstructor(properties[i]);
childTreeElement._readOnly = true;
treeElement.appendChild(childTreeElement);
}
}
}

WebInspector.ArrayGroupingTreeElement.prototype = {
onpopulate: function()
{
if (this._populated)
return;

this._populated = true;

if (this._propertyCount >= WebInspector.ArrayGroupingTreeElement._bucketThreshold) {
WebInspector.ArrayGroupingTreeElement._populateRanges(this, this._object, this._fromIndex, this._toIndex, false);
return;
}
WebInspector.ArrayGroupingTreeElement._populateAsFragment(this, this._object, this._fromIndex, this._toIndex);
},

onattach: function()
{
this.listItemElement.addStyleClass("name");
},

__proto__: TreeElement.prototype
}


WebInspector.ObjectPropertyPrompt = function(commitHandler, cancelHandler, renderAsBlock)
{
WebInspector.TextPrompt.call(this, WebInspector.runtimeModel.completionsForTextPrompt.bind(WebInspector.runtimeModel));
this.setSuggestBoxEnabled("generic-suggest");
if (renderAsBlock)
this.renderAsBlock();
}

WebInspector.ObjectPropertyPrompt.prototype = {
__proto__: WebInspector.TextPrompt.prototype
}






WebInspector.ObjectPopoverHelper = function(panelElement, getAnchor, queryObject, onHide, disableOnClick)
{
WebInspector.PopoverHelper.call(this, panelElement, getAnchor, this._showObjectPopover.bind(this), this._onHideObjectPopover.bind(this), disableOnClick);
this._queryObject = queryObject;
this._onHideCallback = onHide;
this._popoverObjectGroup = "popover";
panelElement.addEventListener("scroll", this.hidePopover.bind(this), true);
};

WebInspector.ObjectPopoverHelper.prototype = {

_showObjectPopover: function(element, popover)
{

function showObjectPopover(result, wasThrown, anchorOverride)
{
if (popover.disposed)
return;
if (wasThrown) {
this.hidePopover();
return;
}

var anchorElement = anchorOverride || element;

var popoverContentElement = null;
if (result.type !== "object") {
popoverContentElement = document.createElement("span");
popoverContentElement.className = "monospace console-formatted-" + result.type;
popoverContentElement.style.whiteSpace = "pre";
popoverContentElement.textContent = result.description;
if (result.type === "function") {
function didGetDetails(error, response)
{
if (error) {
console.error(error);
return;
}
var container = document.createElement("div");
container.className = "inline-block";

var title = container.createChild("div", "function-popover-title source-code");
var functionName = title.createChild("span", "function-name");
functionName.textContent = response.name || response.inferredName || response.displayName || WebInspector.UIString("(anonymous function)");

this._linkifier = new WebInspector.Linkifier();
var rawLocation =   (response.location);
var link = this._linkifier.linkifyRawLocation(rawLocation, "function-location-link");
if (link)
title.appendChild(link);

container.appendChild(popoverContentElement);

popover.show(container, anchorElement);
}
DebuggerAgent.getFunctionDetails(result.objectId, didGetDetails.bind(this));
return;
}
if (result.type === "string")
popoverContentElement.textContent = "\"" + popoverContentElement.textContent + "\"";
popover.show(popoverContentElement, anchorElement);
} else {
if (result.subtype === "node")
result.highlightAsDOMNode();
popoverContentElement = document.createElement("div");
this._titleElement = document.createElement("div");
this._titleElement.className = "source-frame-popover-title monospace";
this._titleElement.textContent = result.description;
popoverContentElement.appendChild(this._titleElement);

var section = new WebInspector.ObjectPropertiesSection(result);

if (result.description.substr(0, 4) === "HTML") {
this._sectionUpdateProperties = section.updateProperties.bind(section);
section.updateProperties = this._updateHTMLId.bind(this);
}
section.expanded = true;
section.element.addStyleClass("source-frame-popover-tree");
section.headerElement.addStyleClass("hidden");
popoverContentElement.appendChild(section.element);

const popoverWidth = 300;
const popoverHeight = 250;
popover.show(popoverContentElement, anchorElement, popoverWidth, popoverHeight);
}
}
this._queryObject(element, showObjectPopover.bind(this), this._popoverObjectGroup);
},

_onHideObjectPopover: function()
{
WebInspector.domAgent.hideDOMNodeHighlight();
if (this._linkifier) {
this._linkifier.reset();
delete this._linkifier;
}
if (this._onHideCallback)
this._onHideCallback();
RuntimeAgent.releaseObjectGroup(this._popoverObjectGroup);
},

_updateHTMLId: function(properties, rootTreeElementConstructor, rootPropertyComparer)
{
for (var i = 0; i < properties.length; ++i) {
if (properties[i].name === "id") {
if (properties[i].value.description)
this._titleElement.textContent += "#" + properties[i].value.description;
break;
}
}
this._sectionUpdateProperties(properties, rootTreeElementConstructor, rootPropertyComparer);
},

__proto__: WebInspector.PopoverHelper.prototype
}






WebInspector.NativeBreakpointsSidebarPane = function(title)
{
WebInspector.SidebarPane.call(this, title);
this.registerRequiredCSS("breakpointsList.css");

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.NativeBreakpointsSidebarPane.prototype = {
_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);
}
},

_reset: function()
{
this.listElement.removeChildren();
if (this.listElement.parentElement) {
this.bodyElement.removeChild(this.listElement);
this.bodyElement.appendChild(this.emptyElement);
}
},

__proto__: WebInspector.SidebarPane.prototype
}






WebInspector.DOMBreakpointsSidebarPane = function()
{
WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("DOM Breakpoints"));

this._breakpointElements = {};

this._breakpointTypes = {
SubtreeModified: "subtree-modified",
AttributeModified: "attribute-modified",
NodeRemoved: "node-removed"
};
this._breakpointTypeLabels = {};
this._breakpointTypeLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified");
this._breakpointTypeLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified");
this._breakpointTypeLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed");

this._contextMenuLabels = {};
this._contextMenuLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Subtree modifications" : "Subtree Modifications");
this._contextMenuLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Attributes modifications" : "Attributes Modifications");
this._contextMenuLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Node removal" : "Node Removal");

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
}

WebInspector.DOMBreakpointsSidebarPane.prototype = {
_inspectedURLChanged: function(event)
{
this._breakpointElements = {};
this._reset();
var url = event.data;
this._inspectedURL = url.removeURLFragment();
},

populateNodeContextMenu: function(node, contextMenu)
{
var nodeBreakpoints = {};
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
if (element._node === node)
nodeBreakpoints[element._type] = true;
}

function toggleBreakpoint(type)
{
if (!nodeBreakpoints[type])
this._setBreakpoint(node, type, true);
else
this._removeBreakpoint(node, type);
this._saveBreakpoints();
}

var breakPointSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Break on..."));
for (var key in this._breakpointTypes) {
var type = this._breakpointTypes[key];
var label = this._contextMenuLabels[type];
breakPointSubMenu.appendCheckboxItem(label, toggleBreakpoint.bind(this, type), nodeBreakpoints[type]);
}
},

createBreakpointHitStatusMessage: function(auxData, callback)
{
if (auxData.type === this._breakpointTypes.SubtreeModified) {
var targetNodeObject = WebInspector.RemoteObject.fromPayload(auxData["targetNode"]);
function didPushNodeToFrontend(targetNodeId)
{
if (targetNodeId)
targetNodeObject.release();
this._doCreateBreakpointHitStatusMessage(auxData, targetNodeId, callback);
}
targetNodeObject.pushNodeToFrontend(didPushNodeToFrontend.bind(this));
} else
this._doCreateBreakpointHitStatusMessage(auxData, null, callback);
},

_doCreateBreakpointHitStatusMessage: function (auxData, targetNodeId, callback)
{
var message;
var typeLabel = this._breakpointTypeLabels[auxData.type];
var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(auxData.nodeId);
var substitutions = [typeLabel, linkifiedNode];
var targetNode = "";
if (targetNodeId)
targetNode = WebInspector.DOMPresentationUtils.linkifyNodeById(targetNodeId);

if (auxData.type === this._breakpointTypes.SubtreeModified) {
if (auxData.insertion) {
if (targetNodeId !== auxData.nodeId) {
message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.";
substitutions.push(targetNode);
} else
message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.";
} else {
message = "Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.";
substitutions.push(targetNode);
}
} else
message = "Paused on a \"%s\" breakpoint set on %s.";

var element = document.createElement("span");
var formatters = {
s: function(substitution)
{
return substitution;
}
};
function append(a, b)
{
if (typeof b === "string")
b = document.createTextNode(b);
element.appendChild(b);
}
WebInspector.formatLocalized(message, substitutions, formatters, "", append);

callback(element);
},

_nodeRemoved: function(event)
{
var node = event.data.node;
this._removeBreakpointsForNode(event.data.node);
if (!node.children)
return;
for (var i = 0; i < node.children.length; ++i)
this._removeBreakpointsForNode(node.children[i]);
this._saveBreakpoints();
},

_removeBreakpointsForNode: function(node)
{
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
if (element._node === node)
this._removeBreakpoint(element._node, element._type);
}
},

_setBreakpoint: function(node, type, enabled)
{
var breakpointId = this._createBreakpointId(node.id, type);
if (breakpointId in this._breakpointElements)
return;

var element = document.createElement("li");
element._node = node;
element._type = type;
element.addEventListener("contextmenu", this._contextMenu.bind(this, node, type), true);

var checkboxElement = document.createElement("input");
checkboxElement.className = "checkbox-elem";
checkboxElement.type = "checkbox";
checkboxElement.checked = enabled;
checkboxElement.addEventListener("click", this._checkboxClicked.bind(this, node, type), false);
element._checkboxElement = checkboxElement;
element.appendChild(checkboxElement);

var labelElement = document.createElement("span");
element.appendChild(labelElement);

var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(node.id);
linkifiedNode.addStyleClass("monospace");
labelElement.appendChild(linkifiedNode);

var description = document.createElement("div");
description.className = "source-text";
description.textContent = this._breakpointTypeLabels[type];
labelElement.appendChild(description);

var currentElement = this.listElement.firstChild;
while (currentElement) {
if (currentElement._type && currentElement._type < element._type)
break;
currentElement = currentElement.nextSibling;
}
this._addListElement(element, currentElement);
this._breakpointElements[breakpointId] = element;
if (enabled)
DOMDebuggerAgent.setDOMBreakpoint(node.id, type);
},

_removeAllBreakpoints: function()
{
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
this._removeBreakpoint(element._node, element._type);
}
this._saveBreakpoints();
},

_removeBreakpoint: function(node, type)
{
var breakpointId = this._createBreakpointId(node.id, type);
var element = this._breakpointElements[breakpointId];
if (!element)
return;

this._removeListElement(element);
delete this._breakpointElements[breakpointId];
if (element._checkboxElement.checked)
DOMDebuggerAgent.removeDOMBreakpoint(node.id, type);
},

_contextMenu: function(node, type, event)
{
var contextMenu = new WebInspector.ContextMenu(event);
function removeBreakpoint()
{
this._removeBreakpoint(node, type);
this._saveBreakpoints();
}
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove breakpoint" : "Remove Breakpoint"), removeBreakpoint.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove all DOM breakpoints" : "Remove All DOM Breakpoints"), this._removeAllBreakpoints.bind(this));
contextMenu.show();
},

_checkboxClicked: function(node, type, event)
{
if (event.target.checked)
DOMDebuggerAgent.setDOMBreakpoint(node.id, type);
else
DOMDebuggerAgent.removeDOMBreakpoint(node.id, type);
this._saveBreakpoints();
},

highlightBreakpoint: function(auxData)
{
var breakpointId = this._createBreakpointId(auxData.nodeId, auxData.type);
var element = this._breakpointElements[breakpointId];
if (!element)
return;
this.expand();
element.addStyleClass("breakpoint-hit");
this._highlightedElement = element;
},

clearBreakpointHighlight: function()
{
if (this._highlightedElement) {
this._highlightedElement.removeStyleClass("breakpoint-hit");
delete this._highlightedElement;
}
},

_createBreakpointId: function(nodeId, type)
{
return nodeId + ":" + type;
},

_saveBreakpoints: function()
{
var breakpoints = [];
var storedBreakpoints = WebInspector.settings.domBreakpoints.get();
for (var i = 0; i < storedBreakpoints.length; ++i) {
var breakpoint = storedBreakpoints[i];
if (breakpoint.url !== this._inspectedURL)
breakpoints.push(breakpoint);
}
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
breakpoints.push({ url: this._inspectedURL, path: element._node.path(), type: element._type, enabled: element._checkboxElement.checked });
}
WebInspector.settings.domBreakpoints.set(breakpoints);
},

restoreBreakpoints: function()
{
var pathToBreakpoints = {};

function didPushNodeByPathToFrontend(path, nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return;

var breakpoints = pathToBreakpoints[path];
for (var i = 0; i < breakpoints.length; ++i)
this._setBreakpoint(node, breakpoints[i].type, breakpoints[i].enabled);
}

var breakpoints = WebInspector.settings.domBreakpoints.get();
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
if (breakpoint.url !== this._inspectedURL)
continue;
var path = breakpoint.path;
if (!pathToBreakpoints[path]) {
pathToBreakpoints[path] = [];
WebInspector.domAgent.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
}
pathToBreakpoints[path].push(breakpoint);
}
},


createProxy: function(panel)
{
var proxy = new WebInspector.DOMBreakpointsSidebarPane.Proxy(this, panel);
if (!this._proxies)
this._proxies = [];
this._proxies.push(proxy);
return proxy;
},

onContentReady: function()
{
for (var i = 0; i != this._proxies.length; i++)
this._proxies[i].onContentReady();
},

__proto__: WebInspector.NativeBreakpointsSidebarPane.prototype
}


WebInspector.DOMBreakpointsSidebarPane.Proxy = function(pane, panel)
{
WebInspector.View._assert(!pane.titleElement.firstChild, "Cannot create proxy for a sidebar pane with a toolbar");

WebInspector.SidebarPane.call(this, pane.title());
this.registerRequiredCSS("breakpointsList.css");

this._wrappedPane = pane;
this._panel = panel;

this.bodyElement.removeSelf();
this.bodyElement = this._wrappedPane.bodyElement;
}

WebInspector.DOMBreakpointsSidebarPane.Proxy.prototype = {
expand: function()
{
this._wrappedPane.expand();
},

onContentReady: function()
{
if (!this._panel.isShowing())
return;

this._reattachBody();
WebInspector.SidebarPane.prototype.onContentReady.call(this);
},

wasShown: function()
{
WebInspector.SidebarPane.prototype.wasShown.call(this);
this._reattachBody();
},

_reattachBody: function()
{
if (this.bodyElement.parentNode !== this.element)
this.element.appendChild(this.bodyElement);
},

__proto__: WebInspector.SidebarPane.prototype
}


WebInspector.domBreakpointsSidebarPane = null;






WebInspector.Color = function(rgba, format, originalText)
{
this._rgba = rgba;
this._originalText = originalText || null;
this._format = format || null;
if (typeof this._rgba[3] === "undefined")
this._rgba[3] = 1;
for (var i = 0; i < 4; ++i) {
if (this._rgba[i] < 0)
this._rgba[i] = 0;
if (this._rgba[i] > 1)
this._rgba[i] = 1;
}
}


WebInspector.Color.parse = function(text)
{

var value = text.toLowerCase().replace(/\s+/g, "");
var simple = /^(?:#([0-9a-f]{3,6})|rgb\(([^)]+)\)|(\w+)|hsl\(([^)]+)\))$/i;
var match = value.match(simple);
if (match) {
if (match[1]) { 
var hex = match[1].toUpperCase();
var format;
if (hex.length === 3) {
format = WebInspector.Color.Format.ShortHEX;
hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
} else
format = WebInspector.Color.Format.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 new WebInspector.Color([r / 255, g / 255, b / 255, 1], format, text);
}

if (match[2]) { 
var rgbString = match[2].split(/\s*,\s*/);
var rgba = [ WebInspector.Color._parseRgbNumeric(rgbString[0]),
WebInspector.Color._parseRgbNumeric(rgbString[1]),
WebInspector.Color._parseRgbNumeric(rgbString[2]), 1 ];
return new WebInspector.Color(rgba, WebInspector.Color.Format.RGB, text);
}

if (match[3]) { 
var nickname = match[3].toLowerCase();
if (nickname in WebInspector.Color.Nicknames) {
var rgba = WebInspector.Color.Nicknames[nickname];
var color = WebInspector.Color.fromRGBA(rgba);
color._format = WebInspector.Color.Format.Nickname;
color._originalText = nickname;
return color;
}
return null;
}

if (match[4]) { 
var hslString = match[4].replace(/%/g, "").split(/\s*,\s*/);
var hsla = [ WebInspector.Color._parseHueNumeric(hslString[0]),
WebInspector.Color._parseSatLightNumeric(hslString[1]),
WebInspector.Color._parseSatLightNumeric(hslString[2]), 1 ];
var rgba = WebInspector.Color._hsl2rgb(hsla);
return new WebInspector.Color(rgba, WebInspector.Color.Format.HSL, text);
}

return null;
}


var advanced = /^(?:rgba\(([^)]+)\)|hsla\(([^)]+)\))$/;
match = value.match(advanced);
if (match) {
if (match[1]) { 
var rgbaString = match[1].split(/\s*,\s*/);
var rgba = [ WebInspector.Color._parseRgbNumeric(rgbaString[0]),
WebInspector.Color._parseRgbNumeric(rgbaString[1]),
WebInspector.Color._parseRgbNumeric(rgbaString[2]),
WebInspector.Color._parseAlphaNumeric(rgbaString[3]) ];
return new WebInspector.Color(rgba, WebInspector.Color.Format.RGBA, text);
}

if (match[2]) { 
var hslaString = match[2].replace(/%/g, "").split(/\s*,\s*/);
var hsla = [ WebInspector.Color._parseHueNumeric(hslaString[0]),
WebInspector.Color._parseSatLightNumeric(hslaString[1]),
WebInspector.Color._parseSatLightNumeric(hslaString[2]),
WebInspector.Color._parseAlphaNumeric(hslaString[3]) ];
var rgba = WebInspector.Color._hsl2rgb(hsla);
return new WebInspector.Color(rgba, WebInspector.Color.Format.HSLA, text);
}
}

return null;
}


WebInspector.Color.fromRGBA = function(rgba)
{
return new WebInspector.Color([rgba[0] / 255, rgba[1] / 255, rgba[2] / 255, rgba[3]]);
}


WebInspector.Color.fromHSVA = function(hsva)
{
var h = hsva[0];
var s = hsva[1];
var v = hsva[2];

var t = (2 - s) * v;
if (v === 0 || s === 0)
s = 0;
else
s *= v / (t < 1 ? t : 2 - t);
var hsla = [h, s, t / 2, hsva[3]];

return new WebInspector.Color(WebInspector.Color._hsl2rgb(hsla), WebInspector.Color.Format.HSLA);
}

WebInspector.Color.prototype = {

format: function()
{
return this._format;
},


hsla: function()
{
if (this._hsla)
return this._hsla;
var r = this._rgba[0];
var g = this._rgba[1];
var b = this._rgba[2];
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 = ((1/6 * (g - b) / diff) + 1) % 1;
else if (g === max)
var h = (1/6 * (b - r) / diff) + 1/3;
else
var h = (1/6 * (r - g) / diff) + 2/3;

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);

this._hsla = [h, s, l, this._rgba[3]];
return this._hsla;
},


hsva: function()
{
var hsla = this.hsla();
var h = hsla[0];
var s = hsla[1];
var l = hsla[2];

s *= l < 0.5 ? l : 1 - l;
return [h, s !== 0 ? 2 * s / (l + s) : 0, (l + s), hsla[3]];
},


hasAlpha: function()
{
return this._rgba[3] !== 1;
},


canBeShortHex: function()
{
if (this.hasAlpha())
return false;
for (var i = 0; i < 3; ++i) {
var c = Math.round(this._rgba[i] * 255);
if (c % 17)
return false;
}
return true;
},


toString: function(format)
{
if (!format)
format = this._format;


function toRgbValue(value)
{
return Math.round(value * 255);
}


function toHexValue(value)
{
var hex = Math.round(value * 255).toString(16);
return hex.length === 1 ? "0" + hex : hex;
}


function toShortHexValue(value)
{
return (Math.round(value * 255) / 17).toString(16);
}

switch (format) {
case WebInspector.Color.Format.Original:
return this._originalText;
case WebInspector.Color.Format.RGB:
if (this.hasAlpha())
return null;
return String.sprintf("rgb(%d, %d, %d)", toRgbValue(this._rgba[0]), toRgbValue(this._rgba[1]), toRgbValue(this._rgba[2]));
case WebInspector.Color.Format.RGBA:
return String.sprintf("rgba(%d, %d, %d, %f)", toRgbValue(this._rgba[0]), toRgbValue(this._rgba[1]), toRgbValue(this._rgba[2]), this._rgba[3]);
case WebInspector.Color.Format.HSL:
if (this.hasAlpha())
return null;
var hsl = this.hsla();
return String.sprintf("hsl(%d, %d%, %d%)", Math.round(hsl[0] * 360), Math.round(hsl[1] * 100), Math.round(hsl[2] * 100));
case WebInspector.Color.Format.HSLA:
var hsla = this.hsla();
return String.sprintf("hsla(%d, %d%, %d%, %f)", Math.round(hsla[0] * 360), Math.round(hsla[1] * 100), Math.round(hsla[2] * 100), hsla[3]);
case WebInspector.Color.Format.HEX:
if (this.hasAlpha())
return null;
return String.sprintf("#%s%s%s", toHexValue(this._rgba[0]), toHexValue(this._rgba[1]), toHexValue(this._rgba[2])).toUpperCase();
case WebInspector.Color.Format.ShortHEX:
if (!this.canBeShortHex())
return null;
return String.sprintf("#%s%s%s", toShortHexValue(this._rgba[0]), toShortHexValue(this._rgba[1]), toShortHexValue(this._rgba[2])).toUpperCase();
case WebInspector.Color.Format.Nickname:
return this.nickname();
}

return this._originalText;
},


_canonicalRGBA: function()
{
var rgba = new Array(3);
for (var i = 0; i < 3; ++i)
rgba[i] = Math.round(this._rgba[i] * 255);
if (this._rgba[3] !== 1)
rgba.push(this._rgba[3]);
return rgba;
},


nickname: function()
{
if (!WebInspector.Color._rgbaToNickname) {
WebInspector.Color._rgbaToNickname = {};
for (var nickname in WebInspector.Color.Nicknames) {
var rgba = WebInspector.Color.Nicknames[nickname];
WebInspector.Color._rgbaToNickname[rgba] = nickname;
}
}

return WebInspector.Color._rgbaToNickname[this._canonicalRGBA()] || null;
},


toProtocolRGBA: function()
{
var rgba = this._canonicalRGBA();
var result = { r: rgba[0], g: rgba[1], b: rgba[2] };
if (rgba[3] !== 1)
result.a = rgba[3];
return result;
}
}


WebInspector.Color._parseRgbNumeric = function(value)
{
var parsed = parseInt(value, 10);
if (value.indexOf("%") !== -1)
parsed /= 100;
else
parsed /= 255;
return parsed;
}


WebInspector.Color._parseHueNumeric = function(value)
{
return isNaN(value) ? 0 : (parseFloat(value) / 360) % 1;
}


WebInspector.Color._parseSatLightNumeric = function(value)
{
return parseFloat(value) / 100;
}


WebInspector.Color._parseAlphaNumeric = function(value)
{
return isNaN(value) ? 0 : parseFloat(value);
}


WebInspector.Color._hsl2rgb = function(hsl)
{
var h = hsl[0];
var s = hsl[1];
var l = hsl[2];

function hue2rgb(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;
}

if (s < 0)
s = 0;

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 = hue2rgb(p, q, tr);
var g = hue2rgb(p, q, tg);
var b = hue2rgb(p, q, tb);
return [r, g, b, hsl[3]];
}

WebInspector.Color.Nicknames = {
"aliceBlue":          [240,248,255],
"antiqueWhite":       [250,235,215],
"aquamarine":         [127,255,212],
"azure":              [240,255,255],
"beige":              [245,245,220],
"bisque":             [255,228,196],
"black":              [0,0,0],
"blanchedAlmond":     [255,235,205],
"blue":               [0,0,255],
"blueViolet":         [138,43,226],
"brown":              [165,42,42],
"burlyWood":          [222,184,135],
"cadetBlue":          [95,158,160],
"chartreuse":         [127,255,0],
"chocolate":          [210,105,30],
"coral":              [255,127,80],
"cornflowerBlue":     [100,149,237],
"cornsilk":           [255,248,220],
"crimson":            [237,20,61],
"cyan":               [0,255,255],
"darkBlue":           [0,0,139],
"darkCyan":           [0,139,139],
"darkGoldenrod":      [184,134,11],
"darkGray":           [169,169,169],
"darkGreen":          [0,100,0],
"darkKhaki":          [189,183,107],
"darkMagenta":        [139,0,139],
"darkOliveGreen":     [85,107,47],
"darkOrange":         [255,140,0],
"darkOrchid":         [153,50,204],
"darkRed":            [139,0,0],
"darkSalmon":         [233,150,122],
"darkSeaGreen":       [143,188,143],
"darkSlateBlue":      [72,61,139],
"darkSlateGray":      [47,79,79],
"darkTurquoise":      [0,206,209],
"darkViolet":         [148,0,211],
"deepPink":           [255,20,147],
"deepSkyBlue":        [0,191,255],
"dimGray":            [105,105,105],
"dodgerBlue":         [30,144,255],
"fireBrick":          [178,34,34],
"floralWhite":        [255,250,240],
"forestGreen":        [34,139,34],
"gainsboro":          [220,220,220],
"ghostWhite":         [248,248,255],
"gold":               [255,215,0],
"goldenrod":          [218,165,32],
"gray":               [128,128,128],
"green":              [0,128,0],
"greenYellow":        [173,255,47],
"honeyDew":           [240,255,240],
"hotPink":            [255,105,180],
"indianRed":          [205,92,92],
"indigo":             [75,0,130],
"ivory":              [255,255,240],
"khaki":              [240,230,140],
"lavender":           [230,230,250],
"lavenderBlush":      [255,240,245],
"lawnGreen":          [124,252,0],
"lemonChiffon":       [255,250,205],
"lightBlue":          [173,216,230],
"lightCoral":         [240,128,128],
"lightCyan":          [224,255,255],
"lightGoldenrodYellow":[250,250,210],
"lightGreen":         [144,238,144],
"lightGrey":          [211,211,211],
"lightPink":          [255,182,193],
"lightSalmon":        [255,160,122],
"lightSeaGreen":      [32,178,170],
"lightSkyBlue":       [135,206,250],
"lightSlateGray":     [119,136,153],
"lightSteelBlue":     [176,196,222],
"lightYellow":        [255,255,224],
"lime":               [0,255,0],
"limeGreen":          [50,205,50],
"linen":              [250,240,230],
"magenta":            [255,0,255],
"maroon":             [128,0,0],
"mediumAquaMarine":   [102,205,170],
"mediumBlue":         [0,0,205],
"mediumOrchid":       [186,85,211],
"mediumPurple":       [147,112,219],
"mediumSeaGreen":     [60,179,113],
"mediumSlateBlue":    [123,104,238],
"mediumSpringGreen":  [0,250,154],
"mediumTurquoise":    [72,209,204],
"mediumVioletRed":    [199,21,133],
"midnightBlue":       [25,25,112],
"mintCream":          [245,255,250],
"mistyRose":          [255,228,225],
"moccasin":           [255,228,181],
"navajoWhite":        [255,222,173],
"navy":               [0,0,128],
"oldLace":            [253,245,230],
"olive":              [128,128,0],
"oliveDrab":          [107,142,35],
"orange":             [255,165,0],
"orangeRed":          [255,69,0],
"orchid":             [218,112,214],
"paleGoldenrod":      [238,232,170],
"paleGreen":          [152,251,152],
"paleTurquoise":      [175,238,238],
"paleVioletRed":      [219,112,147],
"papayaWhip":         [255,239,213],
"peachPuff":          [255,218,185],
"peru":               [205,133,63],
"pink":               [255,192,203],
"plum":               [221,160,221],
"powderBlue":         [176,224,230],
"purple":             [128,0,128],
"red":                [255,0,0],
"rosyBrown":          [188,143,143],
"royalBlue":          [65,105,225],
"saddleBrown":        [139,69,19],
"salmon":             [250,128,114],
"sandyBrown":         [244,164,96],
"seaGreen":           [46,139,87],
"seaShell":           [255,245,238],
"sienna":             [160,82,45],
"silver":             [192,192,192],
"skyBlue":            [135,206,235],
"slateBlue":          [106,90,205],
"slateGray":          [112,128,144],
"snow":               [255,250,250],
"springGreen":        [0,255,127],
"steelBlue":          [70,130,180],
"tan":                [210,180,140],
"teal":               [0,128,128],
"thistle":            [216,191,216],
"tomato":             [255,99,71],
"turquoise":          [64,224,208],
"violet":             [238,130,238],
"wheat":              [245,222,179],
"white":              [255,255,255],
"whiteSmoke":         [245,245,245],
"yellow":             [255,255,0],
"yellowGreen":        [154,205,50],
"transparent":        [0, 0, 0, 0],
};

WebInspector.Color.PageHighlight = {
Content: WebInspector.Color.fromRGBA([111, 168, 220, .66]),
ContentLight: WebInspector.Color.fromRGBA([111, 168, 220, .5]),
ContentOutline: WebInspector.Color.fromRGBA([9, 83, 148]),
Padding: WebInspector.Color.fromRGBA([147, 196, 125, .55]),
PaddingLight: WebInspector.Color.fromRGBA([147, 196, 125, .4]),
Border: WebInspector.Color.fromRGBA([255, 229, 153, .66]),
BorderLight: WebInspector.Color.fromRGBA([255, 229, 153, .5]),
Margin: WebInspector.Color.fromRGBA([246, 178, 107, .66]),
MarginLight: WebInspector.Color.fromRGBA([246, 178, 107, .5]),
EventTarget: WebInspector.Color.fromRGBA([255, 196, 196, .66])
}

WebInspector.Color.Format = {
Original: "original",
Nickname: "nickname",
HEX: "hex",
ShortHEX: "shorthex",
RGB: "rgb",
RGBA: "rgba",
HSL: "hsl",
HSLA: "hsla"
}






WebInspector.CSSMetadata = function(properties)
{
this._values =   ([]);
this._longhands = {};
this._shorthands = {};
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
if (typeof property === "string") {
this._values.push(property);
continue;
}

var propertyName = property.name;
this._values.push(propertyName);

var longhands = properties[i].longhands;
if (longhands) {
this._longhands[propertyName] = longhands;
for (var j = 0; j < longhands.length; ++j) {
var longhandName = longhands[j];
var shorthands = this._shorthands[longhandName];
if (!shorthands) {
shorthands = [];
this._shorthands[longhandName] = shorthands;
}
shorthands.push(propertyName);
}
}
}
this._values.sort();
}


WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata([]);

WebInspector.CSSMetadata.isColorAwareProperty = function(propertyName)
{
return WebInspector.CSSMetadata._colorAwareProperties[propertyName] === true;
}

WebInspector.CSSMetadata.colors = function()
{
if (!WebInspector.CSSMetadata._colorsKeySet)
WebInspector.CSSMetadata._colorsKeySet = WebInspector.CSSMetadata._colors.keySet();
return WebInspector.CSSMetadata._colorsKeySet;
}


WebInspector.CSSMetadata.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", "resize", "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", "zoom"
].keySet();

WebInspector.CSSMetadata._colors = [
"aqua", "black", "blue", "fuchsia", "gray", "green", "lime", "maroon", "navy", "olive", "orange", "purple", "red",
"silver", "teal", "white", "yellow", "transparent", "currentcolor", "grey", "aliceblue", "antiquewhite",
"aquamarine", "azure", "beige", "bisque", "blanchedalmond", "blueviolet", "brown", "burlywood", "cadetblue",
"chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
"darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange",
"darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey",
"darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "gainsboro", "ghostwhite", "gold", "goldenrod", "greenyellow", "honeydew", "hotpink",
"indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue",
"lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow",
"limegreen", "linen", "magenta", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
"mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream",
"mistyrose", "moccasin", "navajowhite", "oldlace", "olivedrab", "orangered", "orchid", "palegoldenrod", "palegreen",
"paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "rosybrown",
"royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "skyblue", "slateblue",
"slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "thistle", "tomato", "turquoise", "violet",
"wheat", "whitesmoke", "yellowgreen"
];

WebInspector.CSSMetadata._colorAwareProperties = [
"background", "background-color", "background-image", "border", "border-color", "border-top", "border-right", "border-bottom",
"border-left", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "box-shadow", "color",
"fill", "outline", "outline-color", "stroke", "text-line-through", "text-line-through-color", "text-overline", "text-overline-color",
"text-shadow", "text-underline", "text-underline-color", "-webkit-box-shadow", "-webkit-column-rule-color",
"-webkit-text-decoration-color", "-webkit-text-emphasis", "-webkit-text-emphasis-color"
].keySet();

WebInspector.CSSMetadata._propertyDataMap = {
"table-layout": { values: [
"auto", "fixed"
] },
"visibility": { values: [
"hidden", "visible", "collapse"
] },
"background-repeat": { values: [
"repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round"
] },
"text-underline": { values: [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
] },
"content": { values: [
"list-item", "close-quote", "no-close-quote", "no-open-quote", "open-quote"
] },
"list-style-image": { values: [
"none"
] },
"clear": { values: [
"none", "left", "right", "both"
] },
"text-underline-mode": { values: [
"continuous", "skip-white-space"
] },
"overflow-x": { values: [
"hidden", "auto", "visible", "overlay", "scroll"
] },
"stroke-linejoin": { values: [
"round", "miter", "bevel"
] },
"baseline-shift": { values: [
"baseline", "sub", "super"
] },
"border-bottom-width": { values: [
"medium", "thick", "thin"
] },
"marquee-speed": { values: [
"normal", "slow", "fast"
] },
"margin-top-collapse": { values: [
"collapse", "separate", "discard"
] },
"max-height": { values: [
"none"
] },
"box-orient": { values: [
"horizontal", "vertical", "inline-axis", "block-axis"
], },
"font-stretch": { values: [
"normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
"semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
] },
"-webkit-color-correction": { values: [
"default", "srgb"
] },
"text-underline-style": { values: [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
] },
"text-overline-mode": { values: [
"continuous", "skip-white-space"
] },
"-webkit-background-composite": { values: [
"highlight", "clear", "copy", "source-over", "source-in", "source-out", "source-atop", "destination-over",
"destination-in", "destination-out", "destination-atop", "xor", "plus-darker", "plus-lighter"
] },
"border-left-width": { values: [
"medium", "thick", "thin"
] },
"-webkit-writing-mode": { values: [
"lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr", "horizontal-bt"
] },
"text-line-through-mode": { values: [
"continuous", "skip-white-space"
] },
"border-collapse": { values: [
"collapse", "separate"
] },
"page-break-inside": { values: [
"auto", "avoid"
] },
"border-top-width": { values: [
"medium", "thick", "thin"
] },
"outline-color": { values: [
"invert"
] },
"text-line-through-style": { values: [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
] },
"outline-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"cursor": { values: [
"none", "copy", "auto", "crosshair", "default", "pointer", "move", "vertical-text", "cell", "context-menu",
"alias", "progress", "no-drop", "not-allowed", "-webkit-zoom-in", "-webkit-zoom-out", "e-resize", "ne-resize",
"nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "ew-resize", "ns-resize",
"nesw-resize", "nwse-resize", "col-resize", "row-resize", "text", "wait", "help", "all-scroll", "-webkit-grab",
"-webkit-grabbing"
] },
"border-width": { values: [
"medium", "thick", "thin"
] },
"size": { values: [
"a3", "a4", "a5", "b4", "b5", "landscape", "ledger", "legal", "letter", "portrait"
] },
"background-size": { values: [
"contain", "cover"
] },
"direction": { values: [
"ltr", "rtl"
] },
"marquee-direction": { values: [
"left", "right", "auto", "reverse", "forwards", "backwards", "ahead", "up", "down"
] },
"enable-background": { values: [
"accumulate", "new"
] },
"float": { values: [
"none", "left", "right"
] },
"overflow-y": { values: [
"hidden", "auto", "visible", "overlay", "scroll"
] },
"margin-bottom-collapse": { values: [
"collapse",  "separate", "discard"
] },
"box-reflect": { values: [
"left", "right", "above", "below"
] },
"overflow": { values: [
"hidden", "auto", "visible", "overlay", "scroll"
] },
"text-rendering": { values: [
"auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision"
] },
"text-align": { values: [
"-webkit-auto", "start", "end", "left", "right", "center", "justify", "-webkit-left", "-webkit-right", "-webkit-center"
] },
"list-style-position": { values: [
"outside", "inside", "hanging"
] },
"margin-bottom": { values: [
"auto"
] },
"color-interpolation": { values: [
"linearrgb"
] },
"background-origin": { values: [
"border-box", "content-box", "padding-box"
] },
"word-wrap": { values: [
"normal", "break-word"
] },
"font-weight": { values: [
"normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"
] },
"margin-before-collapse": { values: [
"collapse", "separate", "discard"
] },
"text-overline-width": { values: [
"normal", "medium", "auto", "thick", "thin"
] },
"text-transform": { values: [
"none", "capitalize", "uppercase", "lowercase"
] },
"border-right-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"border-left-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"-webkit-text-emphasis": { values: [
"circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
] },
"font-style": { values: [
"italic", "oblique", "normal"
] },
"speak": { values: [
"none", "normal", "spell-out", "digits", "literal-punctuation", "no-punctuation"
] },
"text-line-through": { values: [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave", "continuous",
"skip-white-space"
] },
"color-rendering": { values: [
"auto", "optimizeSpeed", "optimizeQuality"
] },
"list-style-type": { values: [
"none", "inline", "disc", "circle", "square", "decimal", "decimal-leading-zero", "arabic-indic", "binary", "bengali",
"cambodian", "khmer", "devanagari", "gujarati", "gurmukhi", "kannada", "lower-hexadecimal", "lao", "malayalam",
"mongolian", "myanmar", "octal", "oriya", "persian", "urdu", "telugu", "tibetan", "thai", "upper-hexadecimal",
"lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "afar",
"ethiopic-halehame-aa-et", "ethiopic-halehame-aa-er", "amharic", "ethiopic-halehame-am-et", "amharic-abegede",
"ethiopic-abegede-am-et", "cjk-earthly-branch", "cjk-heavenly-stem", "ethiopic", "ethiopic-halehame-gez",
"ethiopic-abegede", "ethiopic-abegede-gez", "hangul-consonant", "hangul", "lower-norwegian", "oromo",
"ethiopic-halehame-om-et", "sidama", "ethiopic-halehame-sid-et", "somali", "ethiopic-halehame-so-et", "tigre",
"ethiopic-halehame-tig", "tigrinya-er", "ethiopic-halehame-ti-er", "tigrinya-er-abegede",
"ethiopic-abegede-ti-er", "tigrinya-et", "ethiopic-halehame-ti-et", "tigrinya-et-abegede",
"ethiopic-abegede-ti-et", "upper-greek", "upper-norwegian", "asterisks", "footnotes", "hebrew", "armenian",
"lower-armenian", "upper-armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha",
"katakana-iroha"
] },
"-webkit-text-combine": { values: [
"none", "horizontal"
] },
"outline": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"font": { values: [
"caption", "icon", "menu", "message-box", "small-caption", "-webkit-mini-control", "-webkit-small-control",
"-webkit-control", "status-bar", "italic", "oblique", "small-caps", "normal", "bold", "bolder", "lighter",
"100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium",
"large", "x-large", "xx-large", "-webkit-xxx-large", "smaller", "larger", "serif", "sans-serif", "cursive",
"fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
] },
"dominant-baseline": { values: [
"middle", "auto", "central", "text-before-edge", "text-after-edge", "ideographic", "alphabetic", "hanging",
"mathematical", "use-script", "no-change", "reset-size"
] },
"display": { values: [
"none", "inline", "block", "list-item", "run-in", "compact", "inline-block", "table", "inline-table",
"table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group",
"table-column", "table-cell", "table-caption", "-webkit-box", "-webkit-inline-box", "-wap-marquee"
] },
"-webkit-text-emphasis-position": { values: [
"over", "under"
] },
"image-rendering": { values: [
"auto", "optimizeSpeed", "optimizeQuality"
] },
"alignment-baseline": { values: [
"baseline", "middle", "auto", "before-edge", "after-edge", "central", "text-before-edge", "text-after-edge",
"ideographic", "alphabetic", "hanging", "mathematical"
] },
"outline-width": { values: [
"medium", "thick", "thin"
] },
"text-line-through-width": { values: [
"normal", "medium", "auto", "thick", "thin"
] },
"box-align": { values: [
"baseline", "center", "stretch", "start", "end"
] },
"border-right-width": { values: [
"medium", "thick", "thin"
] },
"border-top-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"line-height": { values: [
"normal"
] },
"text-overflow": { values: [
"clip", "ellipsis"
] },
"overflow-wrap": { values: [
"normal", "break-word"
] },
"box-direction": { values: [
"normal", "reverse"
] },
"margin-after-collapse": { values: [
"collapse", "separate", "discard"
] },
"page-break-before": { values: [
"left", "right", "auto", "always", "avoid"
] },
"-webkit-hyphens": { values: [
"none", "auto", "manual"
] },
"border-image": { values: [
"repeat", "stretch"
] },
"text-decoration": { values: [
"blink", "line-through", "overline", "underline"
] },
"position": { values: [
"absolute", "fixed", "relative", "static"
] },
"font-family": { values: [
"serif", "sans-serif", "cursive", "fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
] },
"text-overflow-mode": { values: [
"clip", "ellipsis"
] },
"border-bottom-style": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"unicode-bidi": { values: [
"normal", "bidi-override", "embed"
] },
"clip-rule": { values: [
"nonzero", "evenodd"
] },
"margin-left": { values: [
"auto"
] },
"margin-top": { values: [
"auto"
] },
"zoom": { values: [
"normal", "document", "reset"
] },
"text-overline-style": { values: [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
] },
"max-width": { values: [
"none"
] },
"caption-side": { values: [
"top", "bottom"
] },
"empty-cells": { values: [
"hide", "show"
] },
"pointer-events": { values: [
"none", "all", "auto", "visible", "visiblepainted", "visiblefill", "visiblestroke", "painted", "fill", "stroke"
] },
"letter-spacing": { values: [
"normal"
] },
"background-clip": { values: [
"border-box", "content-box", "padding-box"
] },
"-webkit-font-smoothing": { values: [
"none", "auto", "antialiased", "subpixel-antialiased"
] },
"border": { values: [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"font-size": { values: [
"xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller",
"larger"
] },
"font-variant": { values: [
"small-caps", "normal"
] },
"vertical-align": { values: [
"baseline", "middle", "sub", "super", "text-top", "text-bottom", "top", "bottom", "-webkit-baseline-middle"
] },
"marquee-style": { values: [
"none", "scroll", "slide", "alternate"
] },
"white-space": { values: [
"normal", "nowrap", "pre", "pre-line", "pre-wrap"
] },
"text-underline-width": { values: [
"normal", "medium", "auto", "thick", "thin"
] },
"box-lines": { values: [
"single", "multiple"
] },
"page-break-after": { values: [
"left", "right", "auto", "always", "avoid"
] },
"clip-path": { values: [
"none"
] },
"margin": { values: [
"auto"
] },
"marquee-repetition": { values: [
"infinite"
] },
"margin-right": { values: [
"auto"
] },
"word-break": { values: [
"normal", "break-all", "break-word"
] },
"word-spacing": { values: [
"normal"
] },
"-webkit-text-emphasis-style": { values: [
"circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
] },
"-webkit-transform": { values: [
"scale", "scaleX", "scaleY", "scale3d", "rotate", "rotateX", "rotateY", "rotateZ", "rotate3d", "skew", "skewX", "skewY",
"translate", "translateX", "translateY", "translateZ", "translate3d", "matrix", "matrix3d", "perspective"
] },
"image-resolution": { values: [
"from-image", "snap"
] },
"box-sizing": { values: [
"content-box", "padding-box", "border-box"
] },
"clip": { values: [
"auto"
] },
"resize": { values: [
"none", "both", "horizontal", "vertical"
] },
"-webkit-align-content": { values: [
"flex-start", "flex-end", "center", "space-between", "space-around", "stretch"
] },
"-webkit-align-items": {  values: [
"flex-start", "flex-end", "center", "baseline", "stretch"
] },
"-webkit-align-self": {  values: [
"auto", "flex-start", "flex-end", "center", "baseline", "stretch"
] },
"-webkit-flex-direction": { values: [
"row", "row-reverse", "column", "column-reverse"
] },
"-webkit-justify-content": { values: [
"flex-start", "flex-end", "center", "space-between", "space-around"
] },
"-webkit-flex-wrap": { values: [
"nowrap", "wrap", "wrap-reverse"
] },
"-webkit-animation-timing-function": { values: [
"ease", "linear", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "steps", "cubic-bezier"
] },
"-webkit-animation-direction": { values: [
"normal", "reverse", "alternate", "alternate-reverse"
] },
"-webkit-animation-play-state": { values: [
"running", "paused"
] },
"-webkit-animation-fill-mode": { values: [
"none", "forwards", "backwards", "both"
] },
"-webkit-backface-visibility": { values: [
"visible", "hidden"
] },
"-webkit-box-decoration-break": { values: [
"slice", "clone"
] },
"-webkit-column-break-after": { values: [
"auto", "always", "avoid", "left", "right", "page", "column", "avoid-page", "avoid-column"
] },
"-webkit-column-break-before": { values: [
"auto", "always", "avoid", "left", "right", "page", "column", "avoid-page", "avoid-column"
] },
"-webkit-column-break-inside": { values: [
"auto", "avoid", "avoid-page", "avoid-column"
] },
"-webkit-column-span": { values: [
"none", "all"
] },
"-webkit-column-count": { values: [
"auto"
] },
"-webkit-column-gap": { values: [
"normal"
] },
"-webkit-line-break": { values: [
"auto", "loose", "normal", "strict"
] },
"-webkit-perspective": { values: [
"none"
] },
"-webkit-perspective-origin": { values: [
"left", "center", "right", "top", "bottom"
] },
"-webkit-text-align-last": { values: [
"auto", "start", "end", "left", "right", "center", "justify"
] },
"-webkit-text-decoration-line": { values: [
"none", "underline", "overline", "line-through", "blink"
] },
"-webkit-text-decoration-style": { values: [
"solid", "double", "dotted", "dashed", "wavy"
] },
"-webkit-text-decoration-skip": { values: [
"none", "objects", "spaces", "ink", "edges", "box-decoration"
] },
"-webkit-transform-origin": { values: [
"left", "center", "right", "top", "bottom"
] },
"-webkit-transform-style": { values: [
"flat", "preserve-3d"
] },
"-webkit-transition-timing-function": { values: [
"ease", "linear", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "steps", "cubic-bezier"
] },

"-webkit-flex": { m: "flexbox" },
"-webkit-flex-basis": { m: "flexbox" },
"-webkit-flex-flow": { m: "flexbox" },
"-webkit-flex-grow": { m: "flexbox" },
"-webkit-flex-shrink": { m: "flexbox" },
"-webkit-animation": { m: "animations" },
"-webkit-animation-delay": { m: "animations" },
"-webkit-animation-duration": { m: "animations" },
"-webkit-animation-iteration-count": { m: "animations" },
"-webkit-animation-name": { m: "animations" },
"-webkit-column-rule": { m: "multicol" },
"-webkit-column-rule-color": { m: "multicol", a: "crc" },
"-webkit-column-rule-style": { m: "multicol", a: "crs" },
"-webkit-column-rule-width": { m: "multicol", a: "crw" },
"-webkit-column-width": { m: "multicol", a: "cw" },
"-webkit-columns": { m: "multicol" },
"-webkit-grid-columns": { m: "grid" },
"-webkit-grid-rows": { m: "grid" },
"-webkit-order": { m: "flexbox" },
"-webkit-text-decoration-color": { m: "text-decor" },
"-webkit-text-emphasis-color": { m: "text-decor" },
"-webkit-transition": { m: "transitions" },
"-webkit-transition-delay": { m: "transitions" },
"-webkit-transition-duration": { m: "transitions" },
"-webkit-transition-property": { m: "transitions" },
"background": { m: "background" },
"background-attachment": { m: "background" },
"background-color": { m: "background" },
"background-image": { m: "background" },
"background-position": { m: "background" },
"background-position-x": { m: "background" },
"background-position-y": { m: "background" },
"background-repeat-x": { m: "background" },
"background-repeat-y": { m: "background" },
"border-top": { m: "background" },
"border-right": { m: "background" },
"border-bottom": { m: "background" },
"border-left": { m: "background" },
"border-radius": { m: "background" },
"bottom": { m: "visuren" },
"box-shadow": { m: "background" },
"color": { m: "color", a: "foreground" },
"counter-increment": { m: "generate" },
"counter-reset": { m: "generate" },
"height": { m: "box" },
"image-orientation": { m: "images" },
"left": { m: "visuren" },
"list-style": { m: "lists" },
"min-height": { m: "box" },
"min-width": { m: "box" },
"opacity": { m: "color", a: "transparency" },
"orphans": { m: "page" },
"outline-offset": { m: "ui" },
"padding": { m: "box", a: "padding1" },
"padding-bottom": { m: "box" },
"padding-left": { m: "box" },
"padding-right": { m: "box" },
"padding-top": { m: "box" },
"page": { m: "page" },
"quotes": { m: "generate" },
"right": { m: "visuren" },
"tab-size": { m: "text" },
"text-indent": { m: "text" },
"text-shadow": { m: "text-decor" },
"top": { m: "visuren" },
"unicode-range": { m: "fonts", a: "descdef-unicode-range" },
"widows": { m: "page" },
"width": { m: "box" },
"z-index": { m: "visuren" }
}


WebInspector.CSSMetadata.keywordsForProperty = function(propertyName)
{
var acceptedKeywords = ["inherit", "initial"];
var descriptor = WebInspector.CSSMetadata.descriptor(propertyName);
if (descriptor && descriptor.values)
acceptedKeywords.push.apply(acceptedKeywords, descriptor.values);
if (propertyName in WebInspector.CSSMetadata._colorAwareProperties)
acceptedKeywords.push.apply(acceptedKeywords, WebInspector.CSSMetadata._colors);
return new WebInspector.CSSMetadata(acceptedKeywords);
}


WebInspector.CSSMetadata.descriptor = function(propertyName)
{
if (!propertyName)
return null;
var unprefixedName = propertyName.replace(/^-webkit-/, "");
var entry = WebInspector.CSSMetadata._propertyDataMap[propertyName];
if (!entry && unprefixedName !== propertyName)
entry = WebInspector.CSSMetadata._propertyDataMap[unprefixedName];
return entry || null;
}

WebInspector.CSSMetadata.requestCSSShorthandData = function()
{
function propertyNamesCallback(error, properties)
{
if (!error)
WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata(properties);
}
CSSAgent.getSupportedCSSProperties(propertyNamesCallback);
}

WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet = function()
{
if (!WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet)
WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet = WebInspector.CSSMetadata.cssPropertiesMetainfo.keySet();
return WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet;
}


WebInspector.CSSMetadata.Weight = {
"-webkit-animation": 1,
"-webkit-animation-duration": 1,
"-webkit-animation-iteration-count": 1,
"-webkit-animation-name": 1,
"-webkit-animation-timing-function": 1,
"-webkit-appearance": 1,
"-webkit-background-clip": 2,
"-webkit-border-horizontal-spacing": 1,
"-webkit-border-vertical-spacing": 1,
"-webkit-box-shadow": 24,
"-webkit-font-smoothing": 2,
"-webkit-transform": 1,
"-webkit-transition": 8,
"-webkit-transition-delay": 7,
"-webkit-transition-duration": 7,
"-webkit-transition-property": 7,
"-webkit-transition-timing-function": 6,
"-webkit-user-select": 1,
"background": 222,
"background-attachment": 144,
"background-clip": 143,
"background-color": 222,
"background-image": 201,
"background-origin": 142,
"background-size": 25,
"border": 121,
"border-bottom": 121,
"border-bottom-color": 121,
"border-bottom-left-radius": 50,
"border-bottom-right-radius": 50,
"border-bottom-style": 114,
"border-bottom-width": 120,
"border-collapse": 3,
"border-left": 95,
"border-left-color": 95,
"border-left-style": 89,
"border-left-width": 94,
"border-radius": 50,
"border-right": 93,
"border-right-color": 93,
"border-right-style": 88,
"border-right-width": 93,
"border-top": 111,
"border-top-color": 111,
"border-top-left-radius": 49,
"border-top-right-radius": 49,
"border-top-style": 104,
"border-top-width": 109,
"bottom": 16,
"box-shadow": 25,
"box-sizing": 2,
"clear": 23,
"color": 237,
"cursor": 34,
"direction": 4,
"display": 210,
"fill": 2,
"filter": 1,
"float": 105,
"font": 174,
"font-family": 25,
"font-size": 174,
"font-style": 9,
"font-weight": 89,
"height": 161,
"left": 54,
"letter-spacing": 3,
"line-height": 75,
"list-style": 17,
"list-style-image": 8,
"list-style-position": 8,
"list-style-type": 17,
"margin": 241,
"margin-bottom": 226,
"margin-left": 225,
"margin-right": 213,
"margin-top": 241,
"max-height": 5,
"max-width": 11,
"min-height": 9,
"min-width": 6,
"opacity": 24,
"outline": 10,
"outline-color": 10,
"outline-style": 10,
"outline-width": 10,
"overflow": 57,
"overflow-x": 56,
"overflow-y": 57,
"padding": 216,
"padding-bottom": 208,
"padding-left": 216,
"padding-right": 206,
"padding-top": 216,
"position": 136,
"resize": 1,
"right": 29,
"stroke": 1,
"stroke-width": 1,
"table-layout": 1,
"text-align": 66,
"text-decoration": 53,
"text-indent": 9,
"text-overflow": 8,
"text-shadow": 19,
"text-transform": 5,
"top": 71,
"unicode-bidi": 1,
"vertical-align": 37,
"visibility": 11,
"white-space": 24,
"width": 255,
"word-wrap": 6,
"z-index": 32,
"zoom": 10
};


WebInspector.CSSMetadata.prototype = {

startsWith: function(prefix)
{
var firstIndex = this._firstIndexOfPrefix(prefix);
if (firstIndex === -1)
return [];

var results = [];
while (firstIndex < this._values.length && this._values[firstIndex].startsWith(prefix))
results.push(this._values[firstIndex++]);
return results;
},


mostUsedOf: function(properties)
{
var maxWeight = 0;
var index = 0;
for (var i = 0; i < properties.length; i++) {
var weight = WebInspector.CSSMetadata.Weight[properties[i]];
if (weight > maxWeight) {
maxWeight = weight;
index = i;
}
}
return index;
},

_firstIndexOfPrefix: function(prefix)
{
if (!this._values.length)
return -1;
if (!prefix)
return 0;

var maxIndex = this._values.length - 1;
var minIndex = 0;
var foundIndex;

do {
var middleIndex = (maxIndex + minIndex) >> 1;
if (this._values[middleIndex].startsWith(prefix)) {
foundIndex = middleIndex;
break;
}
if (this._values[middleIndex] < prefix)
minIndex = middleIndex + 1;
else
maxIndex = middleIndex - 1;
} while (minIndex <= maxIndex);

if (foundIndex === undefined)
return -1;

while (foundIndex && this._values[foundIndex - 1].startsWith(prefix))
foundIndex--;

return foundIndex;
},

keySet: function()
{
if (!this._keySet)
this._keySet = this._values.keySet();
return this._keySet;
},

next: function(str, prefix)
{
return this._closest(str, prefix, 1);
},

previous: function(str, prefix)
{
return this._closest(str, prefix, -1);
},

_closest: function(str, prefix, shift)
{
if (!str)
return "";

var index = this._values.indexOf(str);
if (index === -1)
return "";

if (!prefix) {
index = (index + this._values.length + shift) % this._values.length;
return this._values[index];
}

var propertiesWithPrefix = this.startsWith(prefix);
var j = propertiesWithPrefix.indexOf(str);
j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length;
return propertiesWithPrefix[j];
},


longhands: function(shorthand)
{
return this._longhands[shorthand];
},


shorthands: function(longhand)
{
return this._shorthands[longhand];
}
}






WebInspector.StatusBarItem = function(element)
{
this.element = element;
this._enabled = true;
}

WebInspector.StatusBarItem.prototype = {

setEnabled: function(value)
{
if (this._enabled === value)
return;
this._enabled = value;
this._applyEnabledState();
},


_applyEnabledState: function()
{
this.element.disabled = !this._enabled;
},

__proto__: WebInspector.Object.prototype
}


WebInspector.StatusBarText = function(text, className)
{
WebInspector.StatusBarItem.call(this, document.createElement("span"));
this.element.className = "status-bar-item status-bar-text";
if (className)
this.element.addStyleClass(className);
this.element.textContent = text;
}

WebInspector.StatusBarText.prototype = {

setText: function(text)
{
this.element.textContent = text;
},

__proto__: WebInspector.StatusBarItem.prototype
}



WebInspector.StatusBarButton = function(title, className, states)
{
WebInspector.StatusBarItem.call(this, 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.className = className;
this._visible = true;
}

WebInspector.StatusBarButton.prototype = {
_clicked: function()
{
this.dispatchEventToListeners("click");
if (this._longClickInterval)
clearInterval(this._longClickInterval);
},


enabled: function()
{
return this._enabled;
},

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)
this.element.enableStyleClass("toggled-on", x);
else {
this.element.removeStyleClass("toggled-" + this._state);
if (x !== 0)
this.element.addStyleClass("toggled-" + x);
}
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;

this.element.enableStyleClass("hidden", !x);
this._visible = x;
},

makeLongClickEnabled: function()
{
this.element.addEventListener("mousedown", mouseDown.bind(this), false);
this.element.addEventListener("mouseout", mouseUp.bind(this), false);
this.element.addEventListener("mouseup", mouseUp.bind(this), false);

var longClicks = 0;

function mouseDown(e)
{
if (e.which !== 1)
return;
longClicks = 0;
this._longClickInterval = setInterval(longClicked.bind(this), 200);
}

function mouseUp(e)
{
if (e.which !== 1)
return;
if (this._longClickInterval)
clearInterval(this._longClickInterval);
}

function longClicked()
{
++longClicks;
this.dispatchEventToListeners(longClicks === 1 ? "longClickDown" : "longClickPress");
}
},


makeLongClickOptionsEnabled: function(buttonsProvider)
{
this.makeLongClickEnabled();

this.longClickGlyph = document.createElement("div");
this.longClickGlyph.className = "fill long-click-glyph";
this.element.appendChild(this.longClickGlyph);

this.longClickGlyphShadow = document.createElement("div");
this.longClickGlyphShadow.className = "fill long-click-glyph shadow";
this.element.appendChild(this.longClickGlyphShadow);

this.addEventListener("longClickDown", this._showOptions.bind(this, buttonsProvider), this);
},


_showOptions: function(buttonsProvider)
{
var buttons = buttonsProvider();
var mainButtonClone = new WebInspector.StatusBarButton(this.title, this.className, this.states);
mainButtonClone.addEventListener("click", this._clicked, this);
mainButtonClone.state = this.state;
buttons.push(mainButtonClone);

var mouseUpListener = mouseUp.bind(this);
document.documentElement.addEventListener("mouseup", mouseUpListener, false);

var optionsGlassPane = new WebInspector.GlassPane();
var optionsBarElement = optionsGlassPane.element.createChild("div", "alternate-status-bar-buttons-bar");
const buttonHeight = 24;
optionsBarElement.style.height = (buttonHeight * buttons.length) + "px";
optionsBarElement.style.left = (this.element.offsetLeft + 1) + "px";

var boundMouseOver = mouseOver.bind(this);
var boundMouseOut = mouseOut.bind(this);
for (var i = 0; i < buttons.length; ++i) {
buttons[i].element.addEventListener("mousemove", boundMouseOver, false);
buttons[i].element.addEventListener("mouseout", boundMouseOut, false);
optionsBarElement.appendChild(buttons[i].element);
}
buttons[buttons.length - 1].element.addStyleClass("emulate-active");

function mouseOver(e)
{
if (e.which !== 1)
return;
var buttonElement = e.target.enclosingNodeOrSelfWithClass("status-bar-item");
buttonElement.addStyleClass("emulate-active");
}

function mouseOut(e)
{
if (e.which !== 1)
return;
var buttonElement = e.target.enclosingNodeOrSelfWithClass("status-bar-item");
buttonElement.removeStyleClass("emulate-active");
}

function mouseUp(e)
{
if (e.which !== 1)
return;
optionsGlassPane.dispose();
document.documentElement.removeEventListener("mouseup", mouseUpListener, false);

for (var i = 0; i < buttons.length; ++i) {
if (buttons[i].element.hasStyleClass("emulate-active")) {
buttons[i].element.removeStyleClass("emulate-active");
buttons[i]._clicked();
break;
}
}
}
},

__proto__: WebInspector.StatusBarItem.prototype
}


WebInspector.StatusBarComboBox = function(changeHandler, className)
{
WebInspector.StatusBarItem.call(this, document.createElement("span"));
this.element.className = "status-bar-select-container";

this._selectElement = this.element.createChild("select", "status-bar-item");
this.element.createChild("div", "status-bar-select-arrow");
if (changeHandler)
this._selectElement.addEventListener("change", changeHandler, false);
if (className)
this._selectElement.addStyleClass(className);
}

WebInspector.StatusBarComboBox.prototype = {

size: function()
{
return this._selectElement.childElementCount;
},


addOption: function(option)
{
this._selectElement.appendChild(option);
},


createOption: function(label, title, value)
{
var option = this._selectElement.createChild("option");
option.text = label;
if (title)
option.title = title;
if (typeof value !== "undefined")
option.value = value;
return option;
},


_applyEnabledState: function()
{
this._selectElement.disabled = !this._enabled;
},


removeOption: function(option)
{
this._selectElement.removeChild(option);
},

removeOptions: function()
{
this._selectElement.removeChildren();
},


selectedOption: function()
{
if (this._selectElement.selectedIndex >= 0)
return this._selectElement[this._selectElement.selectedIndex];
return null;
},


select: function(option)
{
this._selectElement.selectedIndex = Array.prototype.indexOf.call(this._selectElement, option);
},


setSelectedIndex: function(index)
{
this._selectElement.selectedIndex = index;
},


selectedIndex: function()
{
return this._selectElement.selectedIndex;
},

__proto__: WebInspector.StatusBarItem.prototype
}






WebInspector.TextEditor = function() { };

WebInspector.TextEditor.Events = {
GutterClick: "gutterClick"
};


WebInspector.TextEditor.GutterClickEventData;

WebInspector.TextEditor.prototype = {

undo: function() { },

redo: function() { },


isClean: function() { },

markClean: function() { },


cursorPositionToCoordinates: function(lineNumber, column) { return null; },


coordinatesToCursorPosition: function(x, y) { return null; },


tokenAtTextPosition: function(lineNumber, column) { return null; },


set mimeType(mimeType) { },


setReadOnly: function(readOnly) { },


readOnly: function() { },


defaultFocusedElement: function() { },


highlightRegex: function(regex, cssClass) { },


highlightRange: function(range, cssClass) { },


removeHighlight: function(highlightDescriptor) { },


revealLine: function(lineNumber) { },


addBreakpoint: function(lineNumber, disabled, conditional) { },


removeBreakpoint: function(lineNumber) { },


setExecutionLine: function(lineNumber) { },

clearExecutionLine: function() { },


addDecoration: function(lineNumber, element) { },


removeDecoration: function(lineNumber, element) { },


markAndRevealRange: function(range) { },


highlightLine: function(lineNumber) { },

clearLineHighlight: function() { },


elementsToRestoreScrollPositionsFor: function() { },


inheritScrollPositions: function(textEditor) { },

beginUpdates: function() { },

endUpdates: function() { },

onResize: function() { },


editRange: function(range, text) { },


scrollToLine: function(lineNumber) { },


selection: function() { },


lastSelection: function() { },


setSelection: function(textRange) { },


copyRange: function(range) { },


setText: function(text) { },


text: function() { },


range: function() { },


line: function(lineNumber) { },


get linesCount() { },


setAttribute: function(line, name, value) { },


getAttribute: function(line, name) { },


removeAttribute: function(line, name) { },

wasShown: function() { },

willHide: function() { }
}


WebInspector.TextEditorDelegate = function()
{
}

WebInspector.TextEditorDelegate.prototype = {

onTextChanged: function(oldRange, newRange) { },


selectionChanged: function(textRange) { },


scrollChanged: function(lineNumber) { },


populateLineGutterContextMenu: function(contextMenu, lineNumber) { },


populateTextAreaContextMenu: function(contextMenu, lineNumber) { },


createLink: function(hrefValue, isExternal) { }
}






WebInspector.DefaultTextEditor = function(url, delegate)
{
WebInspector.View.call(this);
this._delegate = delegate;
this._url = url;

this.registerRequiredCSS("textEditor.css");

this.element.className = "text-editor monospace";


this.element.addEventListener("mouseup", preventDefaultOnMouseUp.bind(this), false);
function preventDefaultOnMouseUp(event)
{
if (event.button === 1)
event.consume(true);
}

this._textModel = new WebInspector.TextEditorModel();
this._textModel.addEventListener(WebInspector.TextEditorModel.Events.TextChanged, this._textChanged, this);

var syncScrollListener = this._syncScroll.bind(this);
var syncDecorationsForLineListener = this._syncDecorationsForLine.bind(this);
var syncLineHeightListener = this._syncLineHeight.bind(this);
this._mainPanel = new WebInspector.TextEditorMainPanel(this._delegate, this._textModel, url, syncScrollListener, syncDecorationsForLineListener);
this._gutterPanel = new WebInspector.TextEditorGutterPanel(this._textModel, syncDecorationsForLineListener, syncLineHeightListener);

this._mainPanel.element.addEventListener("scroll", this._handleScrollChanged.bind(this), false);

this._gutterPanel.element.addEventListener("mousedown", this._onMouseDown.bind(this), true);


this._mainPanel.element.addEventListener("mouseup", consumeMouseUp.bind(this), false);
function consumeMouseUp(event)
{
if (event.button === 1)
event.consume(false);
}

this.element.appendChild(this._mainPanel.element);
this.element.appendChild(this._gutterPanel.element);


function forwardWheelEvent(event)
{
var clone = document.createEvent("WheelEvent");
clone.initWebKitWheelEvent(event.wheelDeltaX, event.wheelDeltaY,
event.view,
event.screenX, event.screenY,
event.clientX, event.clientY,
event.ctrlKey, event.altKey, event.shiftKey, event.metaKey);
this._mainPanel.element.dispatchEvent(clone);
}
this._gutterPanel.element.addEventListener("mousewheel", forwardWheelEvent.bind(this), false);

this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);

this._wordMovementController = new WebInspector.DefaultTextEditor.WordMovementController(this, this._textModel);
this._registerShortcuts();
}


WebInspector.DefaultTextEditor.EditInfo = function(range, text)
{
this.range = range;
this.text = text;
}

WebInspector.DefaultTextEditor.prototype = {

undo: function()
{
this._mainPanel.undo();
},

redo: function()
{
this._mainPanel.redo();
},


isClean: function()
{
return this._textModel.isClean();
},

markClean: function()
{
this._textModel.markClean();
},

tokenAtTextPosition: function(lineNumber, column)
{
return this._mainPanel.tokenAtTextPosition(lineNumber, column);
},


cursorPositionToCoordinates: function(lineNumber, column)
{
return this._mainPanel.cursorPositionToCoordinates(lineNumber, column);
},


coordinatesToCursorPosition: function(x, y)
{
return this._mainPanel.coordinatesToCursorPosition(x, y);
},


copyRange: function(range)
{
return this._textModel.copyRange(range);
},


highlightRegex: function(regex, cssClass)
{
return this._mainPanel.highlightRegex(regex, cssClass);
},


removeHighlight: function(highlightDescriptor)
{
this._mainPanel.removeHighlight(highlightDescriptor);
},


highlightRange: function(range, cssClass)
{
return this._mainPanel.highlightRange(range, cssClass);
},


set mimeType(mimeType)
{
this._mainPanel.mimeType = mimeType;
},


setReadOnly: function(readOnly)
{
if (this._mainPanel.readOnly() === readOnly)
return;
this._mainPanel.setReadOnly(readOnly, this.isShowing());
WebInspector.markBeingEdited(this.element, !readOnly);
},


readOnly: function()
{
return this._mainPanel.readOnly();
},


defaultFocusedElement: function()
{
return this._mainPanel.defaultFocusedElement();
},


revealLine: function(lineNumber)
{
this._mainPanel.revealLine(lineNumber);
},

_onMouseDown: function(event)
{
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (!target)
return;
this.dispatchEventToListeners(WebInspector.TextEditor.Events.GutterClick, { lineNumber: target.lineNumber, event: event });
},


addBreakpoint: function(lineNumber, disabled, conditional)
{
this.beginUpdates();
this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint");
if (disabled)
this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint-disabled");
else
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
if (conditional)
this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint-conditional");
else
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
this.endUpdates();
},


removeBreakpoint: function(lineNumber)
{
this.beginUpdates();
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint");
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
this.endUpdates();
},


setExecutionLine: function(lineNumber)
{
this._executionLineNumber = lineNumber;
this._mainPanel.addDecoration(lineNumber, "webkit-execution-line");
this._gutterPanel.addDecoration(lineNumber, "webkit-execution-line");
},

clearExecutionLine: function()
{
if (typeof this._executionLineNumber === "number") {
this._mainPanel.removeDecoration(this._executionLineNumber, "webkit-execution-line");
this._gutterPanel.removeDecoration(this._executionLineNumber, "webkit-execution-line");
}
delete this._executionLineNumber;
},


addDecoration: function(lineNumber, element)
{
this._mainPanel.addDecoration(lineNumber, element);
this._gutterPanel.addDecoration(lineNumber, element);
this._syncDecorationsForLine(lineNumber);
},


removeDecoration: function(lineNumber, element)
{
this._mainPanel.removeDecoration(lineNumber, element);
this._gutterPanel.removeDecoration(lineNumber, element);
this._syncDecorationsForLine(lineNumber);
},


markAndRevealRange: function(range)
{
if (range)
this.setSelection(range);
this._mainPanel.markAndRevealRange(range);
},


highlightLine: function(lineNumber)
{
if (typeof lineNumber !== "number" || lineNumber < 0)
return;

lineNumber = Math.min(lineNumber, this._textModel.linesCount - 1);
this._mainPanel.highlightLine(lineNumber);
},

clearLineHighlight: function()
{
this._mainPanel.clearLineHighlight();
},


elementsToRestoreScrollPositionsFor: function()
{
return [this._mainPanel.element];
},


inheritScrollPositions: function(textEditor)
{
this._mainPanel.element._scrollTop = textEditor._mainPanel.element.scrollTop;
this._mainPanel.element._scrollLeft = textEditor._mainPanel.element.scrollLeft;
},

beginUpdates: function()
{
this._mainPanel.beginUpdates();
this._gutterPanel.beginUpdates();
},

endUpdates: function()
{
this._mainPanel.endUpdates();
this._gutterPanel.endUpdates();
this._updatePanelOffsets();
},

onResize: function()
{
this._mainPanel.resize();
this._gutterPanel.resize();
this._updatePanelOffsets();
},

_textChanged: function(event)
{
this._mainPanel.textChanged(event.data.oldRange, event.data.newRange);
this._gutterPanel.textChanged(event.data.oldRange, event.data.newRange);
this._updatePanelOffsets();
if (event.data.editRange)
this._delegate.onTextChanged(event.data.oldRange, event.data.newRange);
},


editRange: function(range, text)
{
return this._textModel.editRange(range, text, this.lastSelection());
},

_updatePanelOffsets: function()
{
var lineNumbersWidth = this._gutterPanel.element.offsetWidth;
if (lineNumbersWidth)
this._mainPanel.element.style.setProperty("left", (lineNumbersWidth + 2) + "px");
else
this._mainPanel.element.style.removeProperty("left"); 
},

_syncScroll: function()
{
var mainElement = this._mainPanel.element;
var gutterElement = this._gutterPanel.element;

this._gutterPanel.syncClientHeight(mainElement.clientHeight);
gutterElement.scrollTop = mainElement.scrollTop;
},


_syncDecorationsForLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return;

var mainChunk = this._mainPanel.chunkForLine(lineNumber);
if (mainChunk.linesCount === 1 && mainChunk.isDecorated()) {
var gutterChunk = this._gutterPanel.makeLineAChunk(lineNumber);
var height = mainChunk.height;
if (height)
gutterChunk.element.style.setProperty("height", height + "px");
else
gutterChunk.element.style.removeProperty("height");
} else {
var gutterChunk = this._gutterPanel.chunkForLine(lineNumber);
if (gutterChunk.linesCount === 1)
gutterChunk.element.style.removeProperty("height");
}
},


_syncLineHeight: function(gutterRow)
{
if (this._lineHeightSynced)
return;
if (gutterRow && gutterRow.offsetHeight) {

this.element.style.setProperty("line-height", gutterRow.offsetHeight + "px");
this._lineHeightSynced = true;
}
},

_registerShortcuts: function()
{
var keys = WebInspector.KeyboardShortcut.Keys;
var modifiers = WebInspector.KeyboardShortcut.Modifiers;

this._shortcuts = {};

this._shortcuts[WebInspector.KeyboardShortcut.SelectAll] = this._handleSelectAll.bind(this);
this._wordMovementController._registerShortcuts(this._shortcuts);
},

_handleSelectAll: function()
{
this.setSelection(this._textModel.range());
return true;
},

_handleKeyDown: function(e)
{


if (e.target.enclosingNodeOrSelfWithClass("webkit-line-decorations"))
return;

var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);

var handler = this._shortcuts[shortcutKey];
if (handler && handler()) {
e.consume(true);
return;
}
this._mainPanel.handleKeyDown(shortcutKey, e);
},

_contextMenu: function(event)
{
var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
if (anchor)
return;
var contextMenu = new WebInspector.ContextMenu(event);
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (target)
this._delegate.populateLineGutterContextMenu(contextMenu, target.lineNumber);
else {
this._mainPanel.populateContextMenu(event.target, contextMenu);
}
contextMenu.show();
},

_handleScrollChanged: function(event)
{
var visibleFrom = this._mainPanel.scrollTop();
var firstVisibleLineNumber = this._mainPanel.lineNumberAtOffset(visibleFrom);
this._delegate.scrollChanged(firstVisibleLineNumber);
},


scrollToLine: function(lineNumber)
{
this._mainPanel.scrollToLine(lineNumber);
},


selection: function()
{
return this._mainPanel.selection();
},


lastSelection: function()
{
return this._mainPanel.lastSelection();
},


setSelection: function(textRange)
{
this._mainPanel.setSelection(textRange);
},


setText: function(text)
{
this._textModel.setText(text);
},


text: function()
{
return this._textModel.text();
},


range: function()
{
return this._textModel.range();
},


line: function(lineNumber)
{
return this._textModel.line(lineNumber);
},


get linesCount()
{
return this._textModel.linesCount;
},


setAttribute: function(line, name, value)
{
this._textModel.setAttribute(line, name, value);
},


getAttribute: function(line, name)
{
return this._textModel.getAttribute(line, name);
},


removeAttribute: function(line, name)
{
this._textModel.removeAttribute(line, name);
},

wasShown: function()
{
if (!this.readOnly())
WebInspector.markBeingEdited(this.element, true);

this._mainPanel.wasShown();
},

willHide: function()
{
this._mainPanel.willHide();
this._gutterPanel.willHide();

if (!this.readOnly())
WebInspector.markBeingEdited(this.element, false);
},


highlightRangesWithStyleClass: function(element, resultRanges, styleClass, changes)
{
this._mainPanel.beginDomUpdates();
WebInspector.highlightRangesWithStyleClass(element, resultRanges, styleClass, changes);
this._mainPanel.endDomUpdates();
},


overrideViewportForTest: function(scrollTop, clientHeight, chunkSize)
{
this._mainPanel.overrideViewportForTest(scrollTop, clientHeight, chunkSize);
},

__proto__: WebInspector.View.prototype
}


WebInspector.TextEditorChunkedPanel = function(textModel)
{
this._textModel = textModel;

this.element = document.createElement("div");
this.element.addEventListener("scroll", this._scroll.bind(this), false);

this._defaultChunkSize = 50;
this._paintCoalescingLevel = 0;
this._domUpdateCoalescingLevel = 0;
}

WebInspector.TextEditorChunkedPanel.prototype = {

scrollToLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return;

var chunk = this.makeLineAChunk(lineNumber);
this.element.scrollTop = chunk.offsetTop;
},


revealLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return;

var chunk = this.makeLineAChunk(lineNumber);
chunk.element.scrollIntoViewIfNeeded();
},


addDecoration: function(lineNumber, decoration)
{
if (lineNumber >= this._textModel.linesCount)
return;

var chunk = this.makeLineAChunk(lineNumber);
chunk.addDecoration(decoration);
},


removeDecoration: function(lineNumber, decoration)
{
if (lineNumber >= this._textModel.linesCount)
return;

var chunk = this.chunkForLine(lineNumber);
chunk.removeDecoration(decoration);
},

buildChunks: function()
{
this.beginDomUpdates();

this._container.removeChildren();

this._textChunks = [];
for (var i = 0; i < this._textModel.linesCount; i += this._defaultChunkSize) {
var chunk = this.createNewChunk(i, i + this._defaultChunkSize);
this._textChunks.push(chunk);
this._container.appendChild(chunk.element);
}

this.repaintAll();

this.endDomUpdates();
},


makeLineAChunk: function(lineNumber)
{
var chunkNumber = this.chunkNumberForLine(lineNumber);
var oldChunk = this._textChunks[chunkNumber];

if (!oldChunk) {
console.error("No chunk for line number: " + lineNumber);
return null;
}

if (oldChunk.linesCount === 1)
return oldChunk;

return this.splitChunkOnALine(lineNumber, chunkNumber, true);
},


splitChunkOnALine: function(lineNumber, chunkNumber, createSuffixChunk)
{
this.beginDomUpdates();

var oldChunk = this._textChunks[chunkNumber];
var wasExpanded = oldChunk.expanded();
oldChunk.collapse();

var insertIndex = chunkNumber + 1;


if (lineNumber > oldChunk.startLine) {
var prefixChunk = this.createNewChunk(oldChunk.startLine, lineNumber);
this._textChunks.splice(insertIndex++, 0, prefixChunk);
this._container.insertBefore(prefixChunk.element, oldChunk.element);
}


var endLine = createSuffixChunk ? lineNumber + 1 : oldChunk.startLine + oldChunk.linesCount;
var lineChunk = this.createNewChunk(lineNumber, endLine);
this._textChunks.splice(insertIndex++, 0, lineChunk);
this._container.insertBefore(lineChunk.element, oldChunk.element);


if (oldChunk.startLine + oldChunk.linesCount > endLine) {
var suffixChunk = this.createNewChunk(endLine, oldChunk.startLine + oldChunk.linesCount);
this._textChunks.splice(insertIndex, 0, suffixChunk);
this._container.insertBefore(suffixChunk.element, oldChunk.element);
}


this._textChunks.splice(chunkNumber, 1);
this._container.removeChild(oldChunk.element);

if (wasExpanded) {
if (prefixChunk)
prefixChunk.expand();
lineChunk.expand();
if (suffixChunk)
suffixChunk.expand();
}

this.endDomUpdates();

return lineChunk;
},

createNewChunk: function(startLine, endLine)
{
throw new Error("createNewChunk() should be implemented by descendants");
},

_scroll: function()
{
this._scheduleRepaintAll();
if (this._syncScrollListener)
this._syncScrollListener();
},

_scheduleRepaintAll: function()
{
if (this._repaintAllTimer)
clearTimeout(this._repaintAllTimer);
this._repaintAllTimer = setTimeout(this.repaintAll.bind(this), 50);
},

beginUpdates: function()
{
this._paintCoalescingLevel++;
},

endUpdates: function()
{
this._paintCoalescingLevel--;
if (!this._paintCoalescingLevel)
this.repaintAll();
},

beginDomUpdates: function()
{
this._domUpdateCoalescingLevel++;
},

endDomUpdates: function()
{
this._domUpdateCoalescingLevel--;
},


chunkNumberForLine: function(lineNumber)
{
function compareLineNumbers(value, chunk)
{
return value < chunk.startLine ? -1 : 1;
}
var insertBefore = insertionIndexForObjectInListSortedByFunction(lineNumber, this._textChunks, compareLineNumbers);
return insertBefore - 1;
},


chunkForLine: function(lineNumber)
{
return this._textChunks[this.chunkNumberForLine(lineNumber)];
},


_findFirstVisibleChunkNumber: function(visibleFrom)
{
function compareOffsetTops(value, chunk)
{
return value < chunk.offsetTop ? -1 : 1;
}
var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, this._textChunks, compareOffsetTops);
return insertBefore - 1;
},


findVisibleChunks: function(visibleFrom, visibleTo)
{
var span = (visibleTo - visibleFrom) * 0.5;
visibleFrom = Math.max(visibleFrom - span, 0);
visibleTo = visibleTo + span;

var from = this._findFirstVisibleChunkNumber(visibleFrom);
for (var to = from + 1; to < this._textChunks.length; ++to) {
if (this._textChunks[to].offsetTop >= visibleTo)
break;
}
return { start: from, end: to };
},


lineNumberAtOffset: function(visibleFrom)
{
var chunk = this._textChunks[this._findFirstVisibleChunkNumber(visibleFrom)];
if (!chunk.expanded())
return chunk.startLine;

var lineNumbers = [];
for (var i = 0; i < chunk.linesCount; ++i) {
lineNumbers.push(chunk.startLine + i);
}

function compareLineRowOffsetTops(value, lineNumber)
{
var lineRow = chunk.expandedLineRow(lineNumber);
return value < lineRow.offsetTop ? -1 : 1;
}
var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, lineNumbers, compareLineRowOffsetTops);
return lineNumbers[insertBefore - 1];
},

repaintAll: function()
{
delete this._repaintAllTimer;

if (this._paintCoalescingLevel)
return;

var visibleFrom = this.scrollTop();
var visibleTo = visibleFrom + this.clientHeight();

if (visibleTo) {
var result = this.findVisibleChunks(visibleFrom, visibleTo);
this.expandChunks(result.start, result.end);
}
},

scrollTop: function()
{
return typeof this._scrollTopOverrideForTest === "number" ? this._scrollTopOverrideForTest : this.element.scrollTop;
},

clientHeight: function()
{
return typeof this._clientHeightOverrideForTest === "number" ? this._clientHeightOverrideForTest : this.element.clientHeight;
},


expandChunks: function(fromIndex, toIndex)
{

for (var i = 0; i < fromIndex; ++i)
this._textChunks[i].collapse();
for (var i = toIndex; i < this._textChunks.length; ++i)
this._textChunks[i].collapse();
for (var i = fromIndex; i < toIndex; ++i)
this._textChunks[i].expand();
},


totalHeight: function(firstElement, lastElement)
{
lastElement = (lastElement || firstElement).nextElementSibling;
if (lastElement)
return lastElement.offsetTop - firstElement.offsetTop;

var offsetParent = firstElement.offsetParent;
if (offsetParent && offsetParent.scrollHeight > offsetParent.clientHeight)
return offsetParent.scrollHeight - firstElement.offsetTop;

var total = 0;
while (firstElement && firstElement !== lastElement) {
total += firstElement.offsetHeight;
firstElement = firstElement.nextElementSibling;
}
return total;
},

resize: function()
{
this.repaintAll();
}
}


WebInspector.TextEditorGutterPanel = function(textModel, syncDecorationsForLineListener, syncLineHeightListener)
{
WebInspector.TextEditorChunkedPanel.call(this, textModel);

this._syncDecorationsForLineListener = syncDecorationsForLineListener;
this._syncLineHeightListener = syncLineHeightListener;

this.element.className = "text-editor-lines";

this._container = document.createElement("div");
this._container.className = "inner-container";
this.element.appendChild(this._container);

this._freeCachedElements();
this.buildChunks();
this._decorations = {};
}

WebInspector.TextEditorGutterPanel.prototype = {
_freeCachedElements: function()
{
this._cachedRows = [];
},

willHide: function()
{
this._freeCachedElements();
},


createNewChunk: function(startLine, endLine)
{
return new WebInspector.TextEditorGutterChunk(this, startLine, endLine);
},


textChanged: function(oldRange, newRange)
{
this.beginDomUpdates();

var linesDiff = newRange.linesCount - oldRange.linesCount;
if (linesDiff) {

for (var chunkNumber = this._textChunks.length - 1; chunkNumber >= 0; --chunkNumber) {
var chunk = this._textChunks[chunkNumber];
if (chunk.startLine + chunk.linesCount <= this._textModel.linesCount)
break;
chunk.collapse();
this._container.removeChild(chunk.element);
}
this._textChunks.length = chunkNumber + 1;


var totalLines = 0;
if (this._textChunks.length) {
var lastChunk = this._textChunks[this._textChunks.length - 1];
totalLines = lastChunk.startLine + lastChunk.linesCount;
}

for (var i = totalLines; i < this._textModel.linesCount; i += this._defaultChunkSize) {
var chunk = this.createNewChunk(i, i + this._defaultChunkSize);
this._textChunks.push(chunk);
this._container.appendChild(chunk.element);
}


var decorationsToRestore = {};
for (var lineNumber in this._decorations) {
lineNumber = parseInt(lineNumber, 10);


if (lineNumber < oldRange.startLine)
continue;

if (lineNumber === oldRange.startLine && oldRange.startColumn)
continue;

var lineDecorationsCopy = this._decorations[lineNumber].slice();
for (var i = 0; i < lineDecorationsCopy.length; ++i)
this.removeDecoration(lineNumber, lineDecorationsCopy[i]);

if (lineNumber >= oldRange.endLine)
decorationsToRestore[lineNumber] = lineDecorationsCopy;
}
for (var lineNumber in decorationsToRestore) {
lineNumber = parseInt(lineNumber, 10);
var lineDecorationsCopy = decorationsToRestore[lineNumber];
for (var i = 0; i < lineDecorationsCopy.length; ++i)
this.addDecoration(lineNumber + linesDiff, lineDecorationsCopy[i]);
}


this.repaintAll();
} else {

var chunkNumber = this.chunkNumberForLine(newRange.startLine);
var chunk = this._textChunks[chunkNumber];
while (chunk && chunk.startLine <= newRange.endLine) {
if (chunk.linesCount === 1)
this._syncDecorationsForLineListener(chunk.startLine);
chunk = this._textChunks[++chunkNumber];
}
}

this.endDomUpdates();
},


syncClientHeight: function(clientHeight)
{
if (this.element.offsetHeight > clientHeight)
this._container.style.setProperty("padding-bottom", (this.element.offsetHeight - clientHeight) + "px");
else
this._container.style.removeProperty("padding-bottom");
},


addDecoration: function(lineNumber, decoration)
{
WebInspector.TextEditorChunkedPanel.prototype.addDecoration.call(this, lineNumber, decoration);
var decorations = this._decorations[lineNumber];
if (!decorations) {
decorations = [];
this._decorations[lineNumber] = decorations;
}
decorations.push(decoration);
},


removeDecoration: function(lineNumber, decoration)
{
WebInspector.TextEditorChunkedPanel.prototype.removeDecoration.call(this, lineNumber, decoration);
var decorations = this._decorations[lineNumber];
if (decorations) {
decorations.remove(decoration);
if (!decorations.length)
delete this._decorations[lineNumber];
}
},

__proto__: WebInspector.TextEditorChunkedPanel.prototype
}


WebInspector.TextEditorGutterChunk = function(chunkedPanel, startLine, endLine)
{
this._chunkedPanel = chunkedPanel;
this._textModel = chunkedPanel._textModel;

this.startLine = startLine;
endLine = Math.min(this._textModel.linesCount, endLine);
this.linesCount = endLine - startLine;

this._expanded = false;

this.element = document.createElement("div");
this.element.lineNumber = startLine;
this.element.className = "webkit-line-number";

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.element.appendChild(outerSpan);
} else {
var lineNumbers = [];
for (var i = startLine; i < endLine; ++i)
lineNumbers.push(i + 1);
this.element.textContent = lineNumbers.join("\n");
}
}

WebInspector.TextEditorGutterChunk.prototype = {

addDecoration: function(decoration)
{
this._chunkedPanel.beginDomUpdates();
if (typeof decoration === "string")
this.element.addStyleClass(decoration);
this._chunkedPanel.endDomUpdates();
},


removeDecoration: function(decoration)
{
this._chunkedPanel.beginDomUpdates();
if (typeof decoration === "string")
this.element.removeStyleClass(decoration);
this._chunkedPanel.endDomUpdates();
},


expanded: function()
{
return this._expanded;
},

expand: function()
{
if (this.linesCount === 1)
this._chunkedPanel._syncDecorationsForLineListener(this.startLine);

if (this._expanded)
return;

this._expanded = true;

if (this.linesCount === 1)
return;

this._chunkedPanel.beginDomUpdates();

this._expandedLineRows = [];
var parentElement = this.element.parentElement;
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
var lineRow = this._createRow(i);
parentElement.insertBefore(lineRow, this.element);
this._expandedLineRows.push(lineRow);
}
parentElement.removeChild(this.element);
this._chunkedPanel._syncLineHeightListener(this._expandedLineRows[0]);

this._chunkedPanel.endDomUpdates();
},

collapse: function()
{
if (this.linesCount === 1)
this._chunkedPanel._syncDecorationsForLineListener(this.startLine);

if (!this._expanded)
return;

this._expanded = false;

if (this.linesCount === 1)
return;

this._chunkedPanel.beginDomUpdates();

var elementInserted = false;
for (var i = 0; i < this._expandedLineRows.length; ++i) {
var lineRow = this._expandedLineRows[i];
var parentElement = lineRow.parentElement;
if (parentElement) {
if (!elementInserted) {
elementInserted = true;
parentElement.insertBefore(this.element, lineRow);
}
parentElement.removeChild(lineRow);
}
this._chunkedPanel._cachedRows.push(lineRow);
}
delete this._expandedLineRows;

this._chunkedPanel.endDomUpdates();
},


get height()
{
if (!this._expandedLineRows)
return this._chunkedPanel.totalHeight(this.element);
return this._chunkedPanel.totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]);
},


get offsetTop()
{
return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop;
},


_createRow: function(lineNumber)
{
var lineRow = this._chunkedPanel._cachedRows.pop() || document.createElement("div");
lineRow.lineNumber = lineNumber;
lineRow.className = "webkit-line-number";
lineRow.textContent = lineNumber + 1;
return lineRow;
}
}


WebInspector.TextEditorMainPanel = function(delegate, textModel, url, syncScrollListener, syncDecorationsForLineListener)
{
WebInspector.TextEditorChunkedPanel.call(this, textModel);

this._delegate = delegate;
this._syncScrollListener = syncScrollListener;
this._syncDecorationsForLineListener = syncDecorationsForLineListener;

this._url = url;
this._highlighter = new WebInspector.TextEditorHighlighter(textModel, this._highlightDataReady.bind(this));
this._readOnly = true;

this.element.className = "text-editor-contents";
this.element.tabIndex = 0;

this._container = document.createElement("div");
this._container.className = "inner-container";
this._container.tabIndex = 0;
this.element.appendChild(this._container);

this.element.addEventListener("focus", this._handleElementFocus.bind(this), false);
this.element.addEventListener("textInput", this._handleTextInput.bind(this), false);
this.element.addEventListener("cut", this._handleCut.bind(this), false);
this.element.addEventListener("keypress", this._handleKeyPress.bind(this), false);

this._showWhitespace = WebInspector.experimentsSettings.showWhitespaceInEditor.isEnabled();

this._container.addEventListener("focus", this._handleFocused.bind(this), false);

this._highlightDescriptors = [];

this._tokenHighlighter = new WebInspector.TextEditorMainPanel.TokenHighlighter(this, textModel);
this._braceMatcher = new WebInspector.TextEditorModel.BraceMatcher(textModel);
this._braceHighlighter = new WebInspector.TextEditorMainPanel.BraceHighlightController(this, textModel, this._braceMatcher);
this._smartBraceController = new WebInspector.TextEditorMainPanel.SmartBraceController(this, textModel, this._braceMatcher);

this._freeCachedElements();
this.buildChunks();
this._registerShortcuts();
}

WebInspector.TextEditorMainPanel._ConsecutiveWhitespaceChars = {
1: " ",
2: "  ",
4: "    ",
8: "        ",
16: "                "
};

WebInspector.TextEditorMainPanel.prototype = {

tokenAtTextPosition: function(lineNumber, column)
{
if (lineNumber >= this._textModel.linesCount || lineNumber < 0)
return null;
var line = this._textModel.line(lineNumber);
if (column >= line.length || column < 0)
return null;
var highlight = this._textModel.getAttribute(lineNumber, "highlight");
if (!highlight)
return this._tokenAtUnhighlightedLine(line, column);
function compare(value, object)
{
if (value >= object.startColumn && value <= object.endColumn)
return 0;
return value - object.startColumn;
}
var index = binarySearch(column, highlight.ranges, compare);
if (index >= 0) {
var range = highlight.ranges[index];
return {
startColumn: range.startColumn,
endColumn: range.endColumn,
type: range.token
};
}
return null;
},


cursorPositionToCoordinates: function(lineNumber, column)
{
if (lineNumber >= this._textModel.linesCount || lineNumber < 0)
return null;
var line = this._textModel.line(lineNumber);
if (column > line.length || column < 0)
return null;

var chunk = this.chunkForLine(lineNumber);
if (!chunk.expanded())
return null;
var lineRow = chunk.expandedLineRow(lineNumber);
var ranges = [{
startColumn: column,
endColumn: column,
token: "measure-cursor-position"
}];
var selection = this.selection();

this.beginDomUpdates();
this._renderRanges(lineRow, line, ranges);
var spans = lineRow.getElementsByClassName("webkit-measure-cursor-position");
if (WebInspector.debugDefaultTextEditor)
console.assert(spans.length === 0);
var totalOffset = spans[0].totalOffset();
var height = spans[0].offsetHeight;
this._paintLineRows([lineRow]);
this.endDomUpdates();

this._restoreSelection(selection);
return {
x: totalOffset.left,
y: totalOffset.top,
height: height
};
},


coordinatesToCursorPosition: function(x, y)
{
var element = document.elementFromPoint(x, y);
if (!element)
return null;
var lineRow = element.enclosingNodeOrSelfWithClass("webkit-line-content");
if (!lineRow)
return null;

var line = this._textModel.line(lineRow.lineNumber) + " ";
var ranges = [];
const prefix = "character-position-";
for(var i = 0; i < line.length; ++i) {
ranges.push({
startColumn: i,
endColumn: i,
token: prefix + i
});
}

var selection = this.selection();

this.beginDomUpdates();
this._renderRanges(lineRow, line, ranges);
var charElement = document.elementFromPoint(x, y);
this._paintLineRows([lineRow]);
this.endDomUpdates();

this._restoreSelection(selection);
var className = charElement.className;
if (className.indexOf(prefix) < 0)
return null;
var column = parseInt(className.substring(className.indexOf(prefix) + prefix.length), 10);

return WebInspector.TextRange.createFromLocation(lineRow.lineNumber, column);
},


_tokenAtUnhighlightedLine: function(line, column)
{
var tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(this.mimeType);
tokenizer.condition = tokenizer.createInitialCondition();
tokenizer.line = line;
var lastTokenizedColumn = 0;
while (lastTokenizedColumn < line.length) {
var newColumn = tokenizer.nextToken(lastTokenizedColumn);
if (column < newColumn) {
if (!tokenizer.tokenType)
return null;
return {
startColumn: lastTokenizedColumn,
endColumn: newColumn - 1,
type: tokenizer.tokenType
};
} else
lastTokenizedColumn = newColumn;
}
return null;
},

_registerShortcuts: function()
{
var keys = WebInspector.KeyboardShortcut.Keys;
var modifiers = WebInspector.KeyboardShortcut.Modifiers;

this._shortcuts = {};

this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Enter.code, WebInspector.KeyboardShortcut.Modifiers.None)] = this._handleEnterKey.bind(this);
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.CtrlOrMeta)] = this._handleUndoRedo.bind(this, false);

var handleRedo = this._handleUndoRedo.bind(this, true);
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.Shift | modifiers.CtrlOrMeta)] = handleRedo;
if (!WebInspector.isMac())
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("y", modifiers.CtrlOrMeta)] = handleRedo;

var handleTabKey = this._handleTabKeyPress.bind(this, false);
var handleShiftTabKey = this._handleTabKeyPress.bind(this, true);
this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code)] = handleTabKey;
this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code, modifiers.Shift)] = handleShiftTabKey;

var homeKey = WebInspector.isMac() ? keys.Right : keys.Home;
var homeModifier = WebInspector.isMac() ? modifiers.Meta : modifiers.None;
this._shortcuts[WebInspector.KeyboardShortcut.makeKey(homeKey.code, homeModifier)] = this._handleHomeKey.bind(this, false);
this._shortcuts[WebInspector.KeyboardShortcut.makeKey(homeKey.code, homeModifier | modifiers.Shift)] = this._handleHomeKey.bind(this, true);

this._charOverrides = {};

this._smartBraceController.registerShortcuts(this._shortcuts);
this._smartBraceController.registerCharOverrides(this._charOverrides);
},

_handleKeyPress: function(event)
{
if (event.target.enclosingNodeOrSelfWithClass("webkit-line-decorations"))
return;

var char = String.fromCharCode(event.which);
var handler = this._charOverrides[char];
if (handler && handler()) {
event.consume(true);
return;
}
this._keyDownCode = event.keyCode;
},


_handleHomeKey: function(shift)
{
var selection = this.selection();

var line = this._textModel.line(selection.endLine);
var firstNonBlankCharacter = 0;
while (firstNonBlankCharacter < line.length) {
var char = line.charAt(firstNonBlankCharacter);
if (char === " " || char === "\t")
++firstNonBlankCharacter;
else
break;
}
if (firstNonBlankCharacter >= line.length || selection.endColumn === firstNonBlankCharacter)
return false;

selection.endColumn = firstNonBlankCharacter;
if (!shift)
selection = selection.collapseToEnd();
this._restoreSelection(selection);
return true;
},


highlightRegex: function(regex, cssClass)
{
var highlightDescriptor = new WebInspector.TextEditorMainPanel.RegexHighlightDescriptor(new RegExp(regex, "g"), cssClass);
this._highlightDescriptors.push(highlightDescriptor);
this._repaintLineRowsAffectedByHighlightDescriptors([highlightDescriptor]);
return highlightDescriptor;
},


removeHighlight: function(highlightDescriptor)
{
this._highlightDescriptors.remove(highlightDescriptor);
this._repaintLineRowsAffectedByHighlightDescriptors([highlightDescriptor]);
},


highlightRange: function(range, cssClass)
{
var highlightDescriptor = new WebInspector.TextEditorMainPanel.RangeHighlightDescriptor(range, cssClass);
this._highlightDescriptors.push(highlightDescriptor);
this._repaintLineRowsAffectedByHighlightDescriptors([highlightDescriptor]);
return highlightDescriptor;
},


_repaintLineRowsAffectedByHighlightDescriptors: function(highlightDescriptors)
{
var visibleFrom = this.scrollTop();
var visibleTo = visibleFrom + this.clientHeight();

var visibleChunks = this.findVisibleChunks(visibleFrom, visibleTo);

var affectedLineRows = [];
for (var i = visibleChunks.start; i < visibleChunks.end; ++i) {
var chunk = this._textChunks[i];
if (!chunk.expanded())
continue;
for (var lineNumber = chunk.startLine; lineNumber < chunk.startLine + chunk.linesCount; ++lineNumber) {
var lineRow = chunk.expandedLineRow(lineNumber);
var line = this._textModel.line(lineNumber);
for(var j = 0; j < highlightDescriptors.length; ++j) {
if (highlightDescriptors[j].affectsLine(lineNumber, line)) {
affectedLineRows.push(lineRow);
break;
}
}
}
}
if (affectedLineRows.length === 0)
return;
var selection = this.selection();
this._paintLineRows(affectedLineRows);
this._restoreSelection(selection);
},

resize: function()
{
WebInspector.TextEditorChunkedPanel.prototype.resize.call(this);
this._repaintLineRowsAffectedByHighlightDescriptors(this._highlightDescriptors);
},

wasShown: function()
{
this._boundSelectionChangeListener = this._handleSelectionChange.bind(this);
document.addEventListener("selectionchange", this._boundSelectionChangeListener, false);

this._isShowing = true;
this._attachMutationObserver();
},

willHide: function()
{
document.removeEventListener("selectionchange", this._boundSelectionChangeListener, false);
delete this._boundSelectionChangeListener;

this._detachMutationObserver();
this._isShowing = false;
this._freeCachedElements();
},


populateContextMenu: function(eventTarget, contextMenu)
{
var target = this._enclosingLineRowOrSelf(eventTarget);
this._delegate.populateTextAreaContextMenu(contextMenu, target && target.lineNumber);
},


setSelection: function(textRange)
{
this._lastSelection = textRange;
if (this.element.isAncestor(document.activeElement))
this._restoreSelection(textRange);
},

_handleFocused: function()
{
if (this._lastSelection)
this.setSelection(this._lastSelection);
},

_attachMutationObserver: function()
{
if (!this._isShowing)
return;

if (this._mutationObserver)
this._mutationObserver.disconnect();
this._mutationObserver = new NonLeakingMutationObserver(this._handleMutations.bind(this));
this._mutationObserver.observe(this._container, { subtree: true, childList: true, characterData: true });
},

_detachMutationObserver: function()
{
if (!this._isShowing)
return;

if (this._mutationObserver) {
this._mutationObserver.disconnect();
delete this._mutationObserver;
}
},


set mimeType(mimeType)
{
this._highlighter.mimeType = mimeType;
},

get mimeType()
{
return this._highlighter.mimeType;
},


setReadOnly: function(readOnly, requestFocus)
{
if (this._readOnly === readOnly)
return;

this.beginDomUpdates();
this._readOnly = readOnly;
if (this._readOnly)
this._container.removeStyleClass("text-editor-editable");
else {
this._container.addStyleClass("text-editor-editable");
if (requestFocus)
this._updateSelectionOnStartEditing();
}
this.endDomUpdates();
},


readOnly: function()
{
return this._readOnly;
},

_handleElementFocus: function()
{
if (!this._readOnly)
this._container.focus();
},


defaultFocusedElement: function()
{
if (this._readOnly)
return this.element;
return this._container;
},

_updateSelectionOnStartEditing: function()
{




this._container.focus();
var selection = window.getSelection();
if (selection.rangeCount) {
var commonAncestorContainer = selection.getRangeAt(0).commonAncestorContainer;
if (this._container.isSelfOrAncestor(commonAncestorContainer))
return;
}

selection.removeAllRanges();
var range = document.createRange();
range.setStart(this._container, 0);
range.setEnd(this._container, 0);
selection.addRange(range);
},


markAndRevealRange: function(range)
{
if (this._rangeToMark) {
var markedLine = this._rangeToMark.startLine;
delete this._rangeToMark;

this.beginDomUpdates();
var chunk = this.chunkForLine(markedLine);
var wasExpanded = chunk.expanded();
chunk.collapse();
chunk.updateCollapsedLineRow();
if (wasExpanded)
chunk.expand();
this.endDomUpdates();
}

if (range) {
this._rangeToMark = range;
this.revealLine(range.startLine);
var chunk = this.makeLineAChunk(range.startLine);
this._paintLines(chunk.startLine, chunk.startLine + 1);
if (this._markedRangeElement)
this._markedRangeElement.scrollIntoViewIfNeeded();
}
delete this._markedRangeElement;
},


highlightLine: function(lineNumber)
{
this.clearLineHighlight();
this._highlightedLine = lineNumber;
this.revealLine(lineNumber);

if (!this._readOnly)
this._restoreSelection(WebInspector.TextRange.createFromLocation(lineNumber, 0), false);

this.addDecoration(lineNumber, "webkit-highlighted-line");
},

clearLineHighlight: function()
{
if (typeof this._highlightedLine === "number") {
this.removeDecoration(this._highlightedLine, "webkit-highlighted-line");
delete this._highlightedLine;
}
},

_freeCachedElements: function()
{
this._cachedSpans = [];
this._cachedTextNodes = [];
this._cachedRows = [];
},

undo: function()
{
this._handleUndoRedo(false);
},

redo: function()
{
this._handleUndoRedo(true);
},


_handleUndoRedo: function(redo)
{
if (this.readOnly())
return false;

this.beginUpdates();

var range = redo ? this._textModel.redo() : this._textModel.undo();

this.endUpdates();


if (range)
this._restoreSelection(range, true);

return true;
},


_handleTabKeyPress: function(shiftKey)
{
if (this.readOnly())
return false;

var selection = this.selection();
if (!selection)
return false;

var range = selection.normalize();

this.beginUpdates();

var newRange;
var rangeWasEmpty = range.isEmpty();
if (shiftKey)
newRange = this._textModel.unindentLines(range);
else {
if (rangeWasEmpty)
newRange = this._textModel.editRange(range, WebInspector.settings.textEditorIndent.get());
else
newRange = this._textModel.indentLines(range);
}

this.endUpdates();
if (rangeWasEmpty)
newRange.startColumn = newRange.endColumn;
this._restoreSelection(newRange, true);
return true;
},

_handleEnterKey: function()
{
if (this.readOnly())
return false;

var range = this.selection();
if (!range)
return false;

range = range.normalize();

if (range.endColumn === 0)
return false;

var line = this._textModel.line(range.startLine);
var linePrefix = line.substring(0, range.startColumn);
var indentMatch = linePrefix.match(/^\s+/);
var currentIndent = indentMatch ? indentMatch[0] : "";

var textEditorIndent = WebInspector.settings.textEditorIndent.get();
var indent = WebInspector.TextEditorModel.endsWithBracketRegex.test(linePrefix) ? currentIndent + textEditorIndent : currentIndent;

if (!indent)
return false;

this.beginDomUpdates();

var lineBreak = this._textModel.lineBreak;
var newRange;
if (range.isEmpty() && line.substr(range.endColumn - 1, 2) === '{}') {





newRange = this._textModel.editRange(range, lineBreak + indent + lineBreak + currentIndent);
newRange.endLine--;
newRange.endColumn += textEditorIndent.length;
} else
newRange = this._textModel.editRange(range, lineBreak + indent);

this.endDomUpdates();
this._restoreSelection(newRange.collapseToEnd(), true);

return true;
},


splitChunkOnALine: function(lineNumber, chunkNumber, createSuffixChunk)
{
var selection = this.selection();
var chunk = WebInspector.TextEditorChunkedPanel.prototype.splitChunkOnALine.call(this, lineNumber, chunkNumber, createSuffixChunk);
this._restoreSelection(selection);
return chunk;
},

beginDomUpdates: function()
{
if (!this._domUpdateCoalescingLevel)
this._detachMutationObserver();
WebInspector.TextEditorChunkedPanel.prototype.beginDomUpdates.call(this);
},

endDomUpdates: function()
{
WebInspector.TextEditorChunkedPanel.prototype.endDomUpdates.call(this);
if (!this._domUpdateCoalescingLevel)
this._attachMutationObserver();
},

buildChunks: function()
{
for (var i = 0; i < this._textModel.linesCount; ++i)
this._textModel.removeAttribute(i, "highlight");

WebInspector.TextEditorChunkedPanel.prototype.buildChunks.call(this);
},


createNewChunk: function(startLine, endLine)
{
return new WebInspector.TextEditorMainChunk(this, startLine, endLine);
},


expandChunks: function(fromIndex, toIndex)
{
var lastChunk = this._textChunks[toIndex - 1];
var lastVisibleLine = lastChunk.startLine + lastChunk.linesCount;

var selection = this.selection();

this._muteHighlightListener = true;
this._highlighter.highlight(lastVisibleLine);
delete this._muteHighlightListener;

WebInspector.TextEditorChunkedPanel.prototype.expandChunks.call(this, fromIndex, toIndex);

this._restoreSelection(selection);
},


_highlightDataReady: function(fromLine, toLine)
{
if (this._muteHighlightListener)
return;
this._paintLines(fromLine, toLine, true  );
},


_paintLines: function(fromLine, toLine, restoreSelection)
{
var lineRows = [];
var chunk;
for (var lineNumber = fromLine; lineNumber < toLine; ++lineNumber) {
if (!chunk || lineNumber < chunk.startLine || lineNumber >= chunk.startLine + chunk.linesCount)
chunk = this.chunkForLine(lineNumber);
var lineRow = chunk.expandedLineRow(lineNumber);
if (!lineRow)
continue;
lineRows.push(lineRow);
}
if (lineRows.length === 0)
return;

var selection;
if (restoreSelection)
selection = this.selection();

this._paintLineRows(lineRows);

if (restoreSelection)
this._restoreSelection(selection);
},


_paintLineRows: function(lineRows)
{
var highlight = {};
this.beginDomUpdates();
for(var i = 0; i < this._highlightDescriptors.length; ++i) {
var highlightDescriptor = this._highlightDescriptors[i];
this._measureHighlightDescriptor(highlight, lineRows, highlightDescriptor);
}

for(var i = 0; i < lineRows.length; ++i)
this._paintLine(lineRows[i], highlight[lineRows[i].lineNumber]);

this.endDomUpdates();
},


_measureHighlightDescriptor: function(highlight, lineRows, highlightDescriptor)
{
var rowsToMeasure = [];
for(var i = 0; i < lineRows.length; ++i) {
var lineRow = lineRows[i];
var line = this._textModel.line(lineRow.lineNumber);
var ranges = highlightDescriptor.rangesForLine(lineRow.lineNumber, line);
if (ranges.length === 0)
continue;
for(var j = 0; j < ranges.length; ++j)
ranges[j].token = "measure-span";

this._renderRanges(lineRow, line, ranges);
rowsToMeasure.push(lineRow);
}

for(var i = 0; i < rowsToMeasure.length; ++i) {
var lineRow = rowsToMeasure[i];
var lineNumber = lineRow.lineNumber;
var metrics = this._measureSpans(lineRow);

if (!highlight[lineNumber])
highlight[lineNumber] = [];

highlight[lineNumber].push(new WebInspector.TextEditorMainPanel.LineOverlayHighlight(metrics, highlightDescriptor.cssClass()));
}
},


_measureSpans: function(lineRow)
{
var spans = lineRow.getElementsByClassName("webkit-measure-span");
var metrics = [];
for(var i = 0; i < spans.length; ++i)
metrics.push(new WebInspector.TextEditorMainPanel.ElementMetrics(spans[i]));
return metrics;
},


_appendOverlayHighlight: function(lineRow, highlight)
{
var metrics = highlight.metrics;
var cssClass = highlight.cssClass;
for(var i = 0; i < metrics.length; ++i) {
var highlightSpan = document.createElement("span");
highlightSpan._isOverlayHighlightElement = true;
highlightSpan.addStyleClass(cssClass);
highlightSpan.style.left = metrics[i].left + "px";
highlightSpan.style.width = metrics[i].width + "px";
highlightSpan.style.height = metrics[i].height + "px";
highlightSpan.addStyleClass("text-editor-overlay-highlight");
lineRow.insertBefore(highlightSpan, lineRow.decorationsElement);
}
},


_renderRanges: function(lineRow, line, ranges, splitWhitespaceSequences)
{
var decorationsElement = lineRow.decorationsElement;

if (!decorationsElement)
lineRow.removeChildren();
else {
while (true) {
var child = lineRow.firstChild;
if (!child || child === decorationsElement)
break;
lineRow.removeChild(child);
}
}

if (!line)
lineRow.insertBefore(document.createElement("br"), decorationsElement);

var plainTextStart = 0;
for(var i = 0; i < ranges.length; i++) {
var rangeStart = ranges[i].startColumn;
var rangeEnd = ranges[i].endColumn;

if (plainTextStart < rangeStart) {
this._insertSpanBefore(lineRow, decorationsElement, line.substring(plainTextStart, rangeStart));
}

if (splitWhitespaceSequences && ranges[i].token === "whitespace")
this._renderWhitespaceCharsWithFixedSizeSpans(lineRow, decorationsElement, rangeEnd - rangeStart + 1);
else
this._insertSpanBefore(lineRow, decorationsElement, line.substring(rangeStart, rangeEnd + 1), ranges[i].token ? "webkit-" + ranges[i].token : "");
plainTextStart = rangeEnd + 1;
}
if (plainTextStart < line.length) {
this._insertSpanBefore(lineRow, decorationsElement, line.substring(plainTextStart, line.length));
}
},


_renderWhitespaceCharsWithFixedSizeSpans: function(lineRow, decorationsElement, length)
{
for (var whitespaceLength = 16; whitespaceLength > 0; whitespaceLength >>= 1) {
var cssClass = "webkit-whitespace webkit-whitespace-" + whitespaceLength;
for (; length >= whitespaceLength; length -= whitespaceLength)
this._insertSpanBefore(lineRow, decorationsElement, WebInspector.TextEditorMainPanel._ConsecutiveWhitespaceChars[whitespaceLength], cssClass);
}
},


_paintLine: function(lineRow, overlayHighlight)
{
var lineNumber = lineRow.lineNumber;

this.beginDomUpdates();
try {
var syntaxHighlight = this._textModel.getAttribute(lineNumber, "highlight");

var line = this._textModel.line(lineNumber);
var ranges = syntaxHighlight ? syntaxHighlight.ranges : [];
this._renderRanges(lineRow, line, ranges, this._showWhitespace);

if (overlayHighlight)
for(var i = 0; i < overlayHighlight.length; ++i)
this._appendOverlayHighlight(lineRow, overlayHighlight[i]);
} finally {
if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
this._markedRangeElement = WebInspector.highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
this.endDomUpdates();
}
},


_releaseLinesHighlight: function(lineRow)
{
if (!lineRow)
return;
if ("spans" in lineRow) {
var spans = lineRow.spans;
for (var j = 0; j < spans.length; ++j)
this._cachedSpans.push(spans[j]);
delete lineRow.spans;
}
if ("textNodes" in lineRow) {
var textNodes = lineRow.textNodes;
for (var j = 0; j < textNodes.length; ++j)
this._cachedTextNodes.push(textNodes[j]);
delete lineRow.textNodes;
}
this._cachedRows.push(lineRow);
},


selection: function(lastUndamagedLineRow)
{
var selection = window.getSelection();
if (!selection.rangeCount)
return null;

if (!this._container.isAncestor(selection.anchorNode) || !this._container.isAncestor(selection.focusNode))
return null;

if (selection.focusNode.enclosingNodeOrSelfWithClass("webkit-line-decorations", this._container))
return null;
var start = this._selectionToPosition(selection.anchorNode, selection.anchorOffset, lastUndamagedLineRow);
var end = selection.isCollapsed ? start : this._selectionToPosition(selection.focusNode, selection.focusOffset, lastUndamagedLineRow);
return new WebInspector.TextRange(start.line, start.column, end.line, end.column);
},

lastSelection: function()
{
return this._lastSelection;
},


_restoreSelection: function(range, scrollIntoView)
{
if (!range)
return;

var start = this._positionToSelection(range.startLine, range.startColumn);
var end = range.isEmpty() ? start : this._positionToSelection(range.endLine, range.endColumn);
window.getSelection().setBaseAndExtent(start.container, start.offset, end.container, end.offset);

if (scrollIntoView) {
for (var node = end.container; node; node = node.parentElement) {
if (node.scrollIntoViewIfNeeded) {
node.scrollIntoViewIfNeeded();
break;
}
}
}
this._lastSelection = range;
},


_selectionToPosition: function(container, offset, lastUndamagedLineRow)
{
if (container === this._container && offset === 0)
return { line: 0, column: 0 };
if (container === this._container && offset === 1)
return { line: this._textModel.linesCount - 1, column: this._textModel.lineLength(this._textModel.linesCount - 1) };



var lineNumber;
var column = 0;
var node;
var scopeNode;
if (lastUndamagedLineRow === null) {

node = this._container.firstChild;
scopeNode = this._container;
lineNumber = 0;
} else {
var lineRow = this._enclosingLineRowOrSelf(container);
if (!lastUndamagedLineRow || (typeof lineRow.lineNumber === "number" && lineRow.lineNumber <= lastUndamagedLineRow.lineNumber)) {

node = lineRow;
scopeNode = node;
lineNumber = node.lineNumber;
} else {

node = lastUndamagedLineRow.nextSibling;
scopeNode = this._container;
lineNumber = lastUndamagedLineRow.lineNumber + 1;
}
}


if (container === node && offset === 0)
return { line: lineNumber, column: 0 };


for (; node && node !== container; node = node.traverseNextNode(scopeNode)) {
if (node.nodeName.toLowerCase() === "br") {
lineNumber++;
column = 0;
} else if (node.nodeType === Node.TEXT_NODE) {
var text = node.textContent;
for (var i = 0; i < text.length; ++i) {
if (text.charAt(i) === "\n") {
lineNumber++;
column = 0;
} else
column++;
}
}
}


if (node === container && offset) {
var text = node.textContent;

var textOffset = (node._chunk && offset === 1) ? text.length : offset;
for (var i = 0; i < textOffset; ++i) {
if (text.charAt(i) === "\n") {
lineNumber++;
column = 0;
} else
column++;
}
}
return { line: lineNumber, column: column };
},


_positionToSelection: function(line, column)
{
var chunk = this.chunkForLine(line);

var lineRow = chunk.linesCount === 1 ? chunk.element : chunk.expandedLineRow(line);
if (lineRow)
var rangeBoundary = lineRow.rangeBoundaryForOffset(column);
else {
var offset = column;
for (var i = chunk.startLine; i < line && i < this._textModel.linesCount; ++i)
offset += this._textModel.lineLength(i) + 1; 
lineRow = chunk.element;
if (lineRow.firstChild)
var rangeBoundary = { container: lineRow.firstChild, offset: offset };
else
var rangeBoundary = { container: lineRow, offset: 0 };
}
return rangeBoundary;
},


_enclosingLineRowOrSelf: function(element)
{
var lineRow = element.enclosingNodeOrSelfWithClass("webkit-line-content");
if (lineRow)
return lineRow;

for (lineRow = element; lineRow; lineRow = lineRow.parentElement) {
if (lineRow.parentElement === this._container)
return lineRow;
}
return null;
},


_insertSpanBefore: function(element, oldChild, content, className)
{
if (className === "html-resource-link" || className === "html-external-link") {
element.insertBefore(this._createLink(content, className === "html-external-link"), oldChild);
return;
}

var span = this._cachedSpans.pop() || document.createElement("span");
if (!className)
span.removeAttribute("class");
else
span.className = className;
if (WebInspector.FALSE) 
span.addStyleClass("debug-fadeout");
span.textContent = content;
element.insertBefore(span, oldChild);
if (!("spans" in element))
element.spans = [];
element.spans.push(span);
},


_insertTextNodeBefore: function(element, oldChild, text)
{
var textNode = this._cachedTextNodes.pop();
if (textNode)
textNode.nodeValue = text;
else
textNode = document.createTextNode(text);
element.insertBefore(textNode, oldChild);
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 span = document.createElement("span");
span.className = "webkit-html-attribute-value";
if (quote)
span.appendChild(document.createTextNode(quote));
span.appendChild(this._delegate.createLink(content, isExternal));
if (quote)
span.appendChild(document.createTextNode(quote));
return span;
},


_handleMutations: function(mutations)
{
if (this._readOnly) {
delete this._keyDownCode;
return;
}


var filteredMutations = mutations.slice();
var addedBRs = new Map();
for (var i = 0; i < mutations.length; ++i) {
var mutation = mutations[i];
if (mutation.type !== "childList")
continue;
if (mutation.addedNodes.length === 1 && mutation.addedNodes[0].nodeName === "BR")
addedBRs.put(mutation.addedNodes[0], mutation);
else if (mutation.removedNodes.length === 1 && mutation.removedNodes[0].nodeName === "BR") {
var noopMutation = addedBRs.get(mutation.removedNodes[0]);
if (noopMutation) {
filteredMutations.remove(mutation);
filteredMutations.remove(noopMutation);
}
}
}

var dirtyLines;
for (var i = 0; i < filteredMutations.length; ++i) {
var mutation = filteredMutations[i];
var changedNodes = [];
if (mutation.type === "childList" && mutation.addedNodes.length)
changedNodes = Array.prototype.slice.call(mutation.addedNodes);
else if (mutation.type === "childList" && mutation.removedNodes.length)
changedNodes = Array.prototype.slice.call(mutation.removedNodes);
changedNodes.push(mutation.target);

for (var j = 0; j < changedNodes.length; ++j) {
var lines = this._collectDirtyLines(mutation, changedNodes[j]);
if (!lines)
continue;
if (!dirtyLines) {
dirtyLines = lines;
continue;
}
dirtyLines.start = Math.min(dirtyLines.start, lines.start);
dirtyLines.end = Math.max(dirtyLines.end, lines.end);
}
}
if (dirtyLines) {
delete this._rangeToMark;
this._applyDomUpdates(dirtyLines);
}

this._assertDOMMatchesTextModel();

delete this._keyDownCode;
},


_collectDirtyLines: function(mutation, target)
{
var lineRow = this._enclosingLineRowOrSelf(target);
if (!lineRow)
return null;

if (lineRow.decorationsElement && lineRow.decorationsElement.isSelfOrAncestor(target)) {
if (this._syncDecorationsForLineListener)
this._syncDecorationsForLineListener(lineRow.lineNumber);
return null;
}

if (typeof lineRow.lineNumber !== "number")
return null;

var startLine = lineRow.lineNumber;
var endLine = lineRow._chunk ? lineRow._chunk.endLine - 1 : lineRow.lineNumber;
return { start: startLine, end: endLine };
},


_applyDomUpdates: function(dirtyLines)
{
var lastUndamagedLineNumber = dirtyLines.start - 1; 
var firstUndamagedLineNumber = dirtyLines.end + 1; 

var lastUndamagedLineChunk = lastUndamagedLineNumber >= 0 ? this._textChunks[this.chunkNumberForLine(lastUndamagedLineNumber)] : null;
var firstUndamagedLineChunk = firstUndamagedLineNumber < this._textModel.linesCount ? this._textChunks[this.chunkNumberForLine(firstUndamagedLineNumber)] : null;

var collectLinesFromNode = lastUndamagedLineChunk ? lastUndamagedLineChunk.lineRowContainingLine(lastUndamagedLineNumber) : null;
var collectLinesToNode = firstUndamagedLineChunk ? firstUndamagedLineChunk.lineRowContainingLine(firstUndamagedLineNumber) : null;
var lines = this._collectLinesFromDOM(collectLinesFromNode, collectLinesToNode);

var startLine = dirtyLines.start;
var endLine = dirtyLines.end;

var originalSelection = this._lastSelection;
var editInfo = this._guessEditRangeBasedOnSelection(startLine, endLine, lines);
if (!editInfo) {
if (WebInspector.debugDefaultTextEditor)
console.warn("Falling back to expensive edit");
var range = new WebInspector.TextRange(startLine, 0, endLine, this._textModel.lineLength(endLine));
if (!lines.length) {

editInfo = new WebInspector.DefaultTextEditor.EditInfo(this._textModel.growRangeRight(range), "");
} else
editInfo = new WebInspector.DefaultTextEditor.EditInfo(range, lines.join("\n"));
}

var selection = this.selection(collectLinesFromNode);


if (editInfo.text === "}" && editInfo.range.isEmpty() && selection.isEmpty() && !this._textModel.line(editInfo.range.endLine).trim()) {
var offset = this._closingBlockOffset(editInfo.range);
if (offset >= 0) {
editInfo.range.startColumn = offset;
selection.startColumn = offset + 1;
selection.endColumn = offset + 1;
}
}

this._textModel.editRange(editInfo.range, editInfo.text, originalSelection);
this._restoreSelection(selection);
},


_guessEditRangeBasedOnSelection: function(startLine, endLine, lines)
{

var textInputData = this._textInputData;
delete this._textInputData;
var isBackspace = this._keyDownCode === WebInspector.KeyboardShortcut.Keys.Backspace.code;
var isDelete = this._keyDownCode === WebInspector.KeyboardShortcut.Keys.Delete.code;

if (!textInputData && (isDelete || isBackspace))
textInputData = "";


if (typeof textInputData === "undefined" || !this._lastSelection)
return null;


textInputData = textInputData || "";
var range = this._lastSelection.normalize();
if (isBackspace && range.isEmpty())
range = this._textModel.growRangeLeft(range);
else if (isDelete && range.isEmpty())
range = this._textModel.growRangeRight(range);


if (startLine > range.endLine || endLine < range.startLine)
return null;

var replacementLineCount = textInputData.split("\n").length - 1;
var lineCountDelta = replacementLineCount - range.linesCount;
if (startLine + lines.length - endLine - 1 !== lineCountDelta)
return null;


var cloneFromLine = Math.min(range.startLine, startLine);
var postLastLine = startLine + lines.length + lineCountDelta;
var cloneToLine = Math.min(Math.max(postLastLine, range.endLine) + 1, this._textModel.linesCount);
var domModel = this._textModel.slice(cloneFromLine, cloneToLine);
domModel.editRange(range.shift(-cloneFromLine), textInputData);


for (var i = 0; i < lines.length; ++i) {
if (domModel.line(i + startLine - cloneFromLine) !== lines[i])
return null;
}
return new WebInspector.DefaultTextEditor.EditInfo(range, textInputData);
},

_assertDOMMatchesTextModel: function()
{
if (!WebInspector.debugDefaultTextEditor)
return;

console.assert(this.element.innerText === this._textModel.text() + "\n", "DOM does not match model.");
for (var lineRow = this._container.firstChild; lineRow; lineRow = lineRow.nextSibling) {
var lineNumber = lineRow.lineNumber;
if (typeof lineNumber !== "number") {
console.warn("No line number on line row");
continue;
}
if (lineRow._chunk) {
var chunk = lineRow._chunk;
console.assert(lineNumber === chunk.startLine);
var chunkText = this._textModel.copyRange(new WebInspector.TextRange(chunk.startLine, 0, chunk.endLine - 1, this._textModel.lineLength(chunk.endLine - 1)));
if (chunkText !== lineRow.textContent)
console.warn("Chunk is not matching: %d %O", lineNumber, lineRow);
} else if (this._textModel.line(lineNumber) !== lineRow.textContent)
console.warn("Line is not matching: %d %O", lineNumber, lineRow);
}
},


_closingBlockOffset: function(oldRange)
{
var leftBrace = this._braceMatcher.findLeftCandidate(oldRange.startLine, oldRange.startColumn);
if (!leftBrace || leftBrace.token !== "block-start")
return -1;
var lineContent = this._textModel.line(leftBrace.lineNumber);
return lineContent.length - lineContent.trimLeft().length;
},


textChanged: function(oldRange, newRange)
{
this.beginDomUpdates();
this._removeDecorationsInRange(oldRange);
this._updateChunksForRanges(oldRange, newRange);
this._updateHighlightsForRange(newRange);
this.endDomUpdates();
},


_removeDecorationsInRange: function(range)
{
for (var i = this.chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i) {
var chunk = this._textChunks[i];
if (chunk.startLine > range.endLine)
break;
chunk.removeAllDecorations();
}
},


_updateChunksForRanges: function(oldRange, newRange)
{
var firstDamagedChunkNumber = this.chunkNumberForLine(oldRange.startLine);
var lastDamagedChunkNumber = firstDamagedChunkNumber;
while (lastDamagedChunkNumber + 1 < this._textChunks.length) {
if (this._textChunks[lastDamagedChunkNumber + 1].startLine > oldRange.endLine)
break;
++lastDamagedChunkNumber;
}

var firstDamagedChunk = this._textChunks[firstDamagedChunkNumber];
var lastDamagedChunk = this._textChunks[lastDamagedChunkNumber];

var linesDiff = newRange.linesCount - oldRange.linesCount;


if (linesDiff) {
for (var chunkNumber = lastDamagedChunkNumber + 1; chunkNumber < this._textChunks.length; ++chunkNumber)
this._textChunks[chunkNumber].startLine += linesDiff;
}


var lastUndamagedChunk = firstDamagedChunkNumber > 0 ? this._textChunks[firstDamagedChunkNumber - 1] : null;
var firstUndamagedChunk = lastDamagedChunkNumber + 1 < this._textChunks.length ? this._textChunks[lastDamagedChunkNumber + 1] : null;

var removeDOMFromNode = lastUndamagedChunk ? lastUndamagedChunk.lastElement().nextSibling : this._container.firstChild;
var removeDOMToNode = firstUndamagedChunk ? firstUndamagedChunk.firstElement() : null;


if (!linesDiff && firstDamagedChunk === lastDamagedChunk && firstDamagedChunk._expandedLineRows) {
var lastUndamagedLineRow = lastDamagedChunk.expandedLineRow(oldRange.startLine - 1);
var firstUndamagedLineRow = firstDamagedChunk.expandedLineRow(oldRange.endLine + 1);
var localRemoveDOMFromNode = lastUndamagedLineRow ? lastUndamagedLineRow.nextSibling : removeDOMFromNode;
var localRemoveDOMToNode = firstUndamagedLineRow || removeDOMToNode;
removeSubsequentNodes(localRemoveDOMFromNode, localRemoveDOMToNode);
for (var i = newRange.startLine; i < newRange.endLine + 1; ++i) {
var row = firstDamagedChunk._createRow(i);
firstDamagedChunk._expandedLineRows[i - firstDamagedChunk.startLine] = row;
this._container.insertBefore(row, localRemoveDOMToNode);
}
firstDamagedChunk.updateCollapsedLineRow();
this._assertDOMMatchesTextModel();
return;
}

removeSubsequentNodes(removeDOMFromNode, removeDOMToNode);
this._textChunks.splice(firstDamagedChunkNumber, lastDamagedChunkNumber - firstDamagedChunkNumber + 1);


var startLine = firstDamagedChunk.startLine;
var endLine = lastDamagedChunk.endLine + linesDiff;
var lineSpan = endLine - startLine;


var insertionIndex = firstDamagedChunkNumber;
var chunkSize = Math.ceil(lineSpan / Math.ceil(lineSpan / this._defaultChunkSize));

for (var i = startLine; i < endLine; i += chunkSize) {
var chunk = this.createNewChunk(i, Math.min(endLine, i + chunkSize));
this._textChunks.splice(insertionIndex++, 0, chunk);
this._container.insertBefore(chunk.element, removeDOMToNode);
}

this._assertDOMMatchesTextModel();
},


_updateHighlightsForRange: function(range)
{
var visibleFrom = this.scrollTop();
var visibleTo = visibleFrom + this.clientHeight();

var result = this.findVisibleChunks(visibleFrom, visibleTo);
var chunk = this._textChunks[result.end - 1];
var lastVisibleLine = chunk.startLine + chunk.linesCount;

lastVisibleLine = Math.max(lastVisibleLine, range.endLine + 1);
lastVisibleLine = Math.min(lastVisibleLine, this._textModel.linesCount);

var updated = this._highlighter.updateHighlight(range.startLine, lastVisibleLine);
if (!updated) {

for (var i = this.chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i)
this._textChunks[i].collapse();
}

this.repaintAll();
},


_collectLinesFromDOM: function(from, to)
{
var textContents = [];
var hasContent = false;
for (var node = from ? from.nextSibling : this._container; node && node !== to; node = node.traverseNextNode(this._container)) {

while (node && node !== to && (node._isDecorationsElement || node._isOverlayHighlightElement))
node = node.nextSibling;
if (!node || node === to)
break;

hasContent = true;
if (node.nodeName.toLowerCase() === "br")
textContents.push("\n");
else if (node.nodeType === Node.TEXT_NODE)
textContents.push(node.textContent);
}
if (!hasContent)
return [];

var textContent = textContents.join("");

textContent = textContent.replace(/\n$/, "");

return textContent.split("\n");
},


_handleSelectionChange: function(event)
{
var textRange = this.selection();
if (textRange)
this._lastSelection = textRange;

this._tokenHighlighter.handleSelectionChange(textRange);
this._braceHighlighter.handleSelectionChange(textRange);
this._delegate.selectionChanged(textRange);
},


_handleTextInput: function(event)
{
this._textInputData = event.data;
},


handleKeyDown: function(shortcutKey, event)
{
var handler = this._shortcuts[shortcutKey];
if (handler && handler()) {
event.consume(true);
return;
}

this._keyDownCode = event.keyCode;
},


_handleCut: function(event)
{
this._keyDownCode = WebInspector.KeyboardShortcut.Keys.Delete.code;
},


overrideViewportForTest: function(scrollTop, clientHeight, chunkSize)
{
this._scrollTopOverrideForTest = scrollTop;
this._clientHeightOverrideForTest = clientHeight;
this._defaultChunkSize = chunkSize;
},

__proto__: WebInspector.TextEditorChunkedPanel.prototype
}


WebInspector.TextEditorMainPanel.HighlightDescriptor = function() { }

WebInspector.TextEditorMainPanel.HighlightDescriptor.prototype = {

affectsLine: function(lineNumber, line) { return false; },


rangesForLine: function(lineNumber, line) { return []; },


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


WebInspector.TextEditorMainPanel.RegexHighlightDescriptor = function(regex, cssClass)
{
this._cssClass = cssClass;
this._regex = regex;
}

WebInspector.TextEditorMainPanel.RegexHighlightDescriptor.prototype = {

affectsLine: function(lineNumber, line)
{
this._regex.lastIndex = 0;
return this._regex.test(line);
},


rangesForLine: function(lineNumber, line)
{
var ranges = [];
var regexResult;
this._regex.lastIndex = 0;
while (regexResult = this._regex.exec(line)) {
ranges.push({
startColumn: regexResult.index,
endColumn: regexResult.index + regexResult[0].length - 1
});
}
return ranges;
},


cssClass: function()
{
return this._cssClass;
}
}


WebInspector.TextEditorMainPanel.RangeHighlightDescriptor = function(range, cssClass)
{
this._cssClass = cssClass;
this._range = range;
}

WebInspector.TextEditorMainPanel.RangeHighlightDescriptor.prototype = {

affectsLine: function(lineNumber, line)
{
return this._range.startLine <= lineNumber && lineNumber <= this._range.endLine && line.length > 0;
},


rangesForLine: function(lineNumber, line)
{
if (!this.affectsLine(lineNumber, line))
return [];

var startColumn = lineNumber === this._range.startLine ? this._range.startColumn : 0;
var endColumn = lineNumber === this._range.endLine ? Math.min(this._range.endColumn, line.length) : line.length;
return [{
startColumn: startColumn,
endColumn: endColumn
}];
},


cssClass: function()
{
return this._cssClass;
}
}


WebInspector.TextEditorMainPanel.ElementMetrics = function(element)
{
this.width = element.offsetWidth;
this.height = element.offsetHeight;
this.left = element.offsetLeft;
}


WebInspector.TextEditorMainPanel.LineOverlayHighlight = function(metrics, cssClass)
{
this.metrics = metrics;
this.cssClass = cssClass;
}


WebInspector.TextEditorMainChunk = function(chunkedPanel, startLine, endLine)
{
this._chunkedPanel = chunkedPanel;
this._textModel = chunkedPanel._textModel;

this.element = document.createElement("div");
this.element.lineNumber = startLine;
this.element.className = "webkit-line-content";
this.element._chunk = this;

this._startLine = startLine;
endLine = Math.min(this._textModel.linesCount, endLine);
this.linesCount = endLine - startLine;

this._expanded = false;

this.updateCollapsedLineRow();
}

WebInspector.TextEditorMainChunk.prototype = {

addDecoration: function(decoration)
{
this._chunkedPanel.beginDomUpdates();
if (typeof decoration === "string")
this.element.addStyleClass(decoration);
else {
if (!this.element.decorationsElement) {
this.element.decorationsElement = document.createElement("div");
this.element.decorationsElement.className = "webkit-line-decorations";
this.element.decorationsElement._isDecorationsElement = true;
this.element.appendChild(this.element.decorationsElement);
}
this.element.decorationsElement.appendChild(decoration);
}
this._chunkedPanel.endDomUpdates();
},


removeDecoration: function(decoration)
{
this._chunkedPanel.beginDomUpdates();
if (typeof decoration === "string")
this.element.removeStyleClass(decoration);
else if (this.element.decorationsElement)
this.element.decorationsElement.removeChild(decoration);
this._chunkedPanel.endDomUpdates();
},

removeAllDecorations: function()
{
this._chunkedPanel.beginDomUpdates();
this.element.className = "webkit-line-content";
if (this.element.decorationsElement) {
if (this.element.decorationsElement.parentElement)
this.element.removeChild(this.element.decorationsElement);
delete this.element.decorationsElement;
}
this._chunkedPanel.endDomUpdates();
},


isDecorated: function()
{
return this.element.className !== "webkit-line-content" || !!(this.element.decorationsElement && this.element.decorationsElement.firstChild);
},


get startLine()
{
return this._startLine;
},


get endLine()
{
return this._startLine + this.linesCount;
},

set startLine(startLine)
{
this._startLine = startLine;
this.element.lineNumber = startLine;
if (this._expandedLineRows) {
for (var i = 0; i < this._expandedLineRows.length; ++i)
this._expandedLineRows[i].lineNumber = startLine + i;
}
},


expanded: function()
{
return this._expanded;
},

expand: function()
{
if (this._expanded)
return;

this._expanded = true;

if (this.linesCount === 1) {
this._chunkedPanel._paintLines(this.startLine, this.startLine + 1);
return;
}

this._chunkedPanel.beginDomUpdates();

this._expandedLineRows = [];
var parentElement = this.element.parentElement;
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
var lineRow = this._createRow(i);
parentElement.insertBefore(lineRow, this.element);
this._expandedLineRows.push(lineRow);
}
parentElement.removeChild(this.element);
this._chunkedPanel._paintLines(this.startLine, this.startLine + this.linesCount);

this._chunkedPanel.endDomUpdates();
},

collapse: function()
{
if (!this._expanded)
return;

this._expanded = false;
if (this.linesCount === 1)
return;

this._chunkedPanel.beginDomUpdates();

var elementInserted = false;
for (var i = 0; i < this._expandedLineRows.length; ++i) {
var lineRow = this._expandedLineRows[i];
var parentElement = lineRow.parentElement;
if (parentElement) {
if (!elementInserted) {
elementInserted = true;
parentElement.insertBefore(this.element, lineRow);
}
parentElement.removeChild(lineRow);
}
this._chunkedPanel._releaseLinesHighlight(lineRow);
}
delete this._expandedLineRows;

this._chunkedPanel.endDomUpdates();
},


get height()
{
if (!this._expandedLineRows)
return this._chunkedPanel.totalHeight(this.element);
return this._chunkedPanel.totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]);
},


get offsetTop()
{
return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop;
},


_createRow: function(lineNumber)
{
var lineRow = this._chunkedPanel._cachedRows.pop() || document.createElement("div");
lineRow.lineNumber = lineNumber;
lineRow.className = "webkit-line-content";
lineRow.textContent = this._textModel.line(lineNumber);
if (!lineRow.textContent)
lineRow.appendChild(document.createElement("br"));
return lineRow;
},


lineRowContainingLine: function(lineNumber)
{
if (!this._expanded)
return this.element;
return this.expandedLineRow(lineNumber);
},


expandedLineRow: function(lineNumber)
{
if (!this._expanded || lineNumber < this.startLine || lineNumber >= this.startLine + this.linesCount)
return null;
if (!this._expandedLineRows)
return this.element;
return this._expandedLineRows[lineNumber - this.startLine];
},

updateCollapsedLineRow: function()
{
if (this.linesCount === 1 && this._expanded)
return;

var lines = [];
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i)
lines.push(this._textModel.line(i));

if (WebInspector.FALSE)
console.log("Rebuilding chunk with " + lines.length + " lines");

this.element.removeChildren();
this.element.textContent = lines.join("\n");

if (!lines[lines.length - 1])
this.element.appendChild(document.createElement("br"));
},

firstElement: function()
{
return this._expandedLineRows ? this._expandedLineRows[0] : this.element;
},


lastElement: function()
{
return this._expandedLineRows ? this._expandedLineRows[this._expandedLineRows.length - 1] : this.element;
}
}


WebInspector.TextEditorMainPanel.TokenHighlighter = function(mainPanel, textModel)
{
this._mainPanel = mainPanel;
this._textModel = textModel;
}

WebInspector.TextEditorMainPanel.TokenHighlighter.prototype = {

handleSelectionChange: function(range)
{
if (!range) {
this._removeHighlight();
return;
}

if (range.startLine !== range.endLine) {
this._removeHighlight();
return;
}

range = range.normalize();
var selectedText = this._textModel.copyRange(range);
if (selectedText === this._selectedWord)
return;

if (selectedText === "") {
this._removeHighlight();
return;
}

if (this._isWord(range, selectedText))
this._highlight(selectedText);
else
this._removeHighlight();
},


_regexString: function(word)
{
return "\\b" + word + "\\b";
},


_highlight: function(selectedWord)
{
this._removeHighlight();
this._selectedWord = selectedWord;
this._highlightDescriptor = this._mainPanel.highlightRegex(this._regexString(selectedWord), "text-editor-token-highlight")
},

_removeHighlight: function()
{
if (this._selectedWord) {
this._mainPanel.removeHighlight(this._highlightDescriptor);
delete this._selectedWord;
delete this._highlightDescriptor;
}
},


_isWord: function(range, selectedText)
{
var line = this._textModel.line(range.startLine);
var leftBound = range.startColumn === 0 || !WebInspector.TextUtils.isWordChar(line.charAt(range.startColumn - 1));
var rightBound = range.endColumn === line.length || !WebInspector.TextUtils.isWordChar(line.charAt(range.endColumn));
return leftBound && rightBound && WebInspector.TextUtils.isWord(selectedText);
}
}


WebInspector.DefaultTextEditor.WordMovementController = function(textEditor, textModel)
{
this._textModel = textModel;
this._textEditor = textEditor;
}

WebInspector.DefaultTextEditor.WordMovementController.prototype = {


_registerShortcuts: function(shortcuts)
{
var keys = WebInspector.KeyboardShortcut.Keys;
var modifiers = WebInspector.KeyboardShortcut.Modifiers;

const wordJumpModifier = WebInspector.isMac() ? modifiers.Alt : modifiers.Ctrl;
shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Backspace.code, wordJumpModifier)] = this._handleCtrlBackspace.bind(this);
shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Left.code, wordJumpModifier)] = this._handleCtrlArrow.bind(this, "left");
shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Right.code, wordJumpModifier)] = this._handleCtrlArrow.bind(this, "right");
shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Left.code, modifiers.Shift | wordJumpModifier)] = this._handleCtrlShiftArrow.bind(this, "left");
shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Right.code, modifiers.Shift | wordJumpModifier)] = this._handleCtrlShiftArrow.bind(this, "right");
},


_rangeForCtrlArrowMove: function(selection, direction)
{
const isStopChar = WebInspector.TextUtils.isStopChar;
const isSpaceChar = WebInspector.TextUtils.isSpaceChar;

var lineNumber = selection.endLine;
var column = selection.endColumn;
if (direction === "left")
--column;

if (column === -1 && direction === "left") {
if (lineNumber > 0)
return new WebInspector.TextRange(selection.startLine, selection.startColumn, lineNumber - 1, this._textModel.line(lineNumber - 1).length);
else
return selection.clone();
}

var line = this._textModel.line(lineNumber);
if (column === line.length && direction === "right") {
if (lineNumber + 1 < this._textModel.linesCount)
return new WebInspector.TextRange(selection.startLine, selection.startColumn, selection.endLine + 1, 0);
else
return selection.clone();
}

var delta = direction === "left" ? -1 : +1;
var directionDependentEndColumnOffset = (delta + 1) / 2;

if (isSpaceChar(line.charAt(column))) {
while(column + delta >= 0 && column + delta < line.length && isSpaceChar(line.charAt(column + delta)))
column += delta;
if (column + delta < 0 || column + delta === line.length)
return new WebInspector.TextRange(selection.startLine, selection.startColumn, lineNumber, column + directionDependentEndColumnOffset);
else
column += delta;
}

var group = isStopChar(line.charAt(column));

while(column + delta >= 0 && column + delta < line.length && isStopChar(line.charAt(column + delta)) === group && !isSpaceChar(line.charAt(column + delta)))
column += delta;

return new WebInspector.TextRange(selection.startLine, selection.startColumn, lineNumber, column + directionDependentEndColumnOffset);
},


_handleCtrlArrow: function(direction)
{
var newSelection = this._rangeForCtrlArrowMove(this._textEditor.selection(), direction);
this._textEditor.setSelection(newSelection.collapseToEnd());
return true;
},


_handleCtrlShiftArrow: function(direction)
{
this._textEditor.setSelection(this._rangeForCtrlArrowMove(this._textEditor.selection(), direction));
return true;
},


_handleCtrlBackspace: function()
{
var selection = this._textEditor.selection();
if (!selection.isEmpty())
return false;

var newSelection = this._rangeForCtrlArrowMove(selection, "left");
this._textModel.editRange(newSelection.normalize(), "", selection);

this._textEditor.setSelection(newSelection.collapseToEnd());
return true;
}
}


WebInspector.TextEditorMainPanel.BraceHighlightController = function(textEditor, textModel, braceMatcher)
{
this._textEditor = textEditor;
this._textModel = textModel;
this._braceMatcher = braceMatcher;
this._highlightDescriptors = [];
}

WebInspector.TextEditorMainPanel.BraceHighlightController.prototype = {

activeBraceColumnForCursorPosition: function(line, column)
{
var char = line.charAt(column);
if (WebInspector.TextUtils.isOpeningBraceChar(char))
return column;

var previousChar = line.charAt(column - 1);
if (WebInspector.TextUtils.isBraceChar(previousChar))
return column - 1;

if (WebInspector.TextUtils.isBraceChar(char))
return column;
else
return -1;
},


handleSelectionChange: function(selectionRange)
{
if (!selectionRange || !selectionRange.isEmpty()) {
this._removeHighlight();
return;
}

if (this._highlightedRange && this._highlightedRange.compareTo(selectionRange) === 0)
return;

this._removeHighlight();
var lineNumber = selectionRange.startLine;
var column = selectionRange.startColumn;
var line = this._textModel.line(lineNumber);
column = this.activeBraceColumnForCursorPosition(line, column);
if (column < 0)
return;

var enclosingBraces = this._braceMatcher.enclosingBraces(lineNumber, column);
if (!enclosingBraces)
return;

this._highlightedRange = selectionRange;
this._highlightDescriptors.push(this._textEditor.highlightRange(WebInspector.TextRange.createFromLocation(enclosingBraces.leftBrace.lineNumber, enclosingBraces.leftBrace.column), "text-editor-brace-match"));
this._highlightDescriptors.push(this._textEditor.highlightRange(WebInspector.TextRange.createFromLocation(enclosingBraces.rightBrace.lineNumber, enclosingBraces.rightBrace.column), "text-editor-brace-match"));
},

_removeHighlight: function()
{
if (!this._highlightDescriptors.length)
return;

for(var i = 0; i < this._highlightDescriptors.length; ++i)
this._textEditor.removeHighlight(this._highlightDescriptors[i]);

this._highlightDescriptors = [];
delete this._highlightedRange;
}
}


WebInspector.TextEditorMainPanel.SmartBraceController = function(mainPanel, textModel, braceMatcher)
{
this._mainPanel = mainPanel;
this._textModel = textModel;
this._braceMatcher = braceMatcher
}

WebInspector.TextEditorMainPanel.SmartBraceController.prototype = {

registerShortcuts: function(shortcuts)
{
var keys = WebInspector.KeyboardShortcut.Keys;
var modifiers = WebInspector.KeyboardShortcut.Modifiers;

shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Backspace.code, modifiers.None)] = this._handleBackspace.bind(this);
},


registerCharOverrides: function(charOverrides)
{
charOverrides["("] = this._handleBracePairInsertion.bind(this, "()");
charOverrides[")"] = this._handleClosingBraceOverride.bind(this, ")");
charOverrides["{"] = this._handleBracePairInsertion.bind(this, "{}");
charOverrides["}"] = this._handleClosingBraceOverride.bind(this, "}");
},

_handleBackspace: function()
{
var selection = this._mainPanel.lastSelection();
if (!selection || !selection.isEmpty())
return false;

var column = selection.startColumn;
if (column == 0)
return false;

var lineNumber = selection.startLine;
var line = this._textModel.line(lineNumber);
if (column === line.length)
return false;

var pair = line.substr(column - 1, 2);
if (pair === "()" || pair === "{}") {
this._textModel.editRange(new WebInspector.TextRange(lineNumber, column - 1, lineNumber, column + 1), "");
this._mainPanel.setSelection(WebInspector.TextRange.createFromLocation(lineNumber, column - 1));
return true;
} else
return false;
},


_handleBracePairInsertion: function(bracePair)
{
var selection = this._mainPanel.lastSelection().normalize();
if (selection.isEmpty()) {
var lineNumber = selection.startLine;
var column = selection.startColumn;
var line = this._textModel.line(lineNumber);
if (column < line.length) {
var char = line.charAt(column);
if (WebInspector.TextUtils.isWordChar(char) || (!WebInspector.TextUtils.isBraceChar(char) && WebInspector.TextUtils.isStopChar(char)))
return false;
}
}
this._textModel.editRange(selection, bracePair);
this._mainPanel.setSelection(WebInspector.TextRange.createFromLocation(selection.startLine, selection.startColumn + 1));
return true;
},


_handleClosingBraceOverride: function(brace)
{
var selection = this._mainPanel.lastSelection().normalize();
if (!selection || !selection.isEmpty())
return false;

var lineNumber = selection.startLine;
var column = selection.startColumn;
var line = this._textModel.line(lineNumber);
if (line.charAt(column) !== brace)
return false;

var braces = this._braceMatcher.enclosingBraces(lineNumber, column);
if (braces && braces.rightBrace.lineNumber === lineNumber && braces.rightBrace.column === column) {
this._mainPanel.setSelection(WebInspector.TextRange.createFromLocation(lineNumber, column + 1));
return true;
} else
return false;
},
}

WebInspector.debugDefaultTextEditor = false;






WebInspector.SourceFrame = function(contentProvider)
{
WebInspector.View.call(this);
this.element.addStyleClass("script-view");
this.element.addStyleClass("fill");

this._url = contentProvider.contentURL();
this._contentProvider = contentProvider;

var textEditorDelegate = new WebInspector.TextEditorDelegateForSourceFrame(this);

if (WebInspector.settings.codemirror.get()) {
loadScript("CodeMirrorTextEditor.js");
this._textEditor = new WebInspector.CodeMirrorTextEditor(this._url, textEditorDelegate);
} else
this._textEditor = new WebInspector.DefaultTextEditor(this._url, textEditorDelegate);

this._currentSearchResultIndex = -1;
this._searchResults = [];

this._messages = [];
this._rowMessages = {};
this._messageBubbles = {};

this._textEditor.setReadOnly(!this.canEditSource());

this._shortcuts = {};
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)] = this._commitEditing.bind(this);
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);

this._sourcePosition = new WebInspector.StatusBarText("", "source-frame-cursor-position");
}


WebInspector.SourceFrame.createSearchRegex = function(query, modifiers)
{
var regex;
modifiers = modifiers || "";


try {
if (/^\/.*\/$/.test(query))
regex = new RegExp(query.substring(1, query.length - 1), modifiers);
} catch (e) {

}


if (!regex)
regex = createPlainTextSearchRegex(query, "i" + modifiers);

return regex;
}

WebInspector.SourceFrame.Events = {
ScrollChanged: "ScrollChanged",
SelectionChanged: "SelectionChanged"
}

WebInspector.SourceFrame.prototype = {
wasShown: function()
{
this._ensureContentLoaded();
this._textEditor.show(this.element);
this._editorAttached = true;
this._wasShownOrLoaded();
},


_isEditorShowing: function()
{
return this.isShowing() && this._editorAttached;
},

willHide: function()
{
WebInspector.View.prototype.willHide.call(this);

this._clearLineHighlight();
this._clearLineToReveal();
},


statusBarText: function()
{
return this._sourcePosition.element;
},


statusBarItems: function()
{
return [];
},

defaultFocusedElement: function()
{
return this._textEditor.defaultFocusedElement();
},

get loaded()
{
return this._loaded;
},

hasContent: function()
{
return true;
},

get textEditor()
{
return this._textEditor;
},

_ensureContentLoaded: function()
{
if (!this._contentRequested) {
this._contentRequested = true;
this._contentProvider.requestContent(this.setContent.bind(this));
}
},

addMessage: function(msg)
{
this._messages.push(msg);
if (this.loaded)
this.addMessageToSource(msg.line - 1, msg);
},

clearMessages: function()
{
for (var line in this._messageBubbles) {
var bubble = this._messageBubbles[line];
var lineNumber = parseInt(line, 10);
this._textEditor.removeDecoration(lineNumber, bubble);
}

this._messages = [];
this._rowMessages = {};
this._messageBubbles = {};
},


canHighlightLine: function(line)
{
return true;
},


highlightLine: function(line)
{
this._clearLineToReveal();
this._clearLineToScrollTo();
this._lineToHighlight = line;
this._innerHighlightLineIfNeeded();
this._textEditor.setSelection(WebInspector.TextRange.createFromLocation(line, 0));
},

_innerHighlightLineIfNeeded: function()
{
if (typeof this._lineToHighlight === "number") {
if (this.loaded && this._isEditorShowing()) {
this._textEditor.highlightLine(this._lineToHighlight);
delete this._lineToHighlight
}
}
},

_clearLineHighlight: function()
{
this._textEditor.clearLineHighlight();
delete this._lineToHighlight;
},


revealLine: function(line)
{
this._clearLineHighlight();
this._clearLineToScrollTo();
this._lineToReveal = line;
this._innerRevealLineIfNeeded();
},

_innerRevealLineIfNeeded: function()
{
if (typeof this._lineToReveal === "number") {
if (this.loaded && this._isEditorShowing()) {
this._textEditor.revealLine(this._lineToReveal);
delete this._lineToReveal
}
}
},

_clearLineToReveal: function()
{
delete this._lineToReveal;
},


scrollToLine: function(line)
{
this._clearLineHighlight();
this._clearLineToReveal();
this._lineToScrollTo = line;
this._innerScrollToLineIfNeeded();
},

_innerScrollToLineIfNeeded: function()
{
if (typeof this._lineToScrollTo === "number") {
if (this.loaded && this._isEditorShowing()) {
this._textEditor.scrollToLine(this._lineToScrollTo);
delete this._lineToScrollTo;
}
}
},

_clearLineToScrollTo: function()
{
delete this._lineToScrollTo;
},


setSelection: function(textRange)
{
this._selectionToSet = textRange;
this._innerSetSelectionIfNeeded();
},

_innerSetSelectionIfNeeded: function()
{
if (this._selectionToSet && this.loaded && this._isEditorShowing()) {
this._textEditor.setSelection(this._selectionToSet);
delete this._selectionToSet;
}
},

_wasShownOrLoaded: function()
{
this._innerHighlightLineIfNeeded();
this._innerRevealLineIfNeeded();
this._innerScrollToLineIfNeeded();
this._innerSetSelectionIfNeeded();
},

onTextChanged: function(oldRange, newRange)
{
if (!this._isReplacing)
WebInspector.searchController.cancelSearch();
this.clearMessages();
},

_simplifyMimeType: function(mimeType)
{
if (!mimeType)
return "";
if (mimeType.indexOf("javascript") >= 0 ||
mimeType.indexOf("jscript") >= 0 ||
mimeType.indexOf("ecmascript") >= 0)
return "text/javascript";
return mimeType;
},


setContent: function(content, contentEncoded, mimeType)
{
this._textEditor.mimeType = this._simplifyMimeType(mimeType);

if (!this._loaded) {
this._loaded = true;
this._textEditor.setText(content || "");
this._textEditor.markClean();
} else
this._textEditor.editRange(this._textEditor.range(), content || "");

this._textEditor.beginUpdates();

this._setTextEditorDecorations();

this._wasShownOrLoaded();

if (this._delayedFindSearchMatches) {
this._delayedFindSearchMatches();
delete this._delayedFindSearchMatches;
}

this.onTextEditorContentLoaded();

this._textEditor.endUpdates();
},

onTextEditorContentLoaded: function() {},

_setTextEditorDecorations: function()
{
this._rowMessages = {};
this._messageBubbles = {};

this._textEditor.beginUpdates();

this._addExistingMessagesToSource();

this._textEditor.endUpdates();
},


performSearch: function(query, callback)
{

this.searchCanceled();

function doFindSearchMatches(query)
{
this._currentSearchResultIndex = -1;
this._searchResults = [];

var regex = WebInspector.SourceFrame.createSearchRegex(query);
this._searchResults = this._collectRegexMatches(regex);
var shiftToIndex = 0;
var selection = this._textEditor.lastSelection();
for (var i = 0; selection && i < this._searchResults.length; ++i) {
if (this._searchResults[i].compareTo(selection) >= 0) {
shiftToIndex = i;
break;
}
}

if (shiftToIndex)
this._searchResults = this._searchResults.rotate(shiftToIndex);

callback(this, this._searchResults.length);
}

if (this.loaded)
doFindSearchMatches.call(this, query);
else
this._delayedFindSearchMatches = doFindSearchMatches.bind(this, query);

this._ensureContentLoaded();
},

searchCanceled: function()
{
delete this._delayedFindSearchMatches;
if (!this.loaded)
return;

this._currentSearchResultIndex = -1;
this._searchResults = [];
this._textEditor.markAndRevealRange(null);
},

hasSearchResults: function()
{
return this._searchResults.length > 0;
},

jumpToFirstSearchResult: function()
{
this.jumpToSearchResult(0);
},

jumpToLastSearchResult: function()
{
this.jumpToSearchResult(this._searchResults.length - 1);
},

jumpToNextSearchResult: function()
{
this.jumpToSearchResult(this._currentSearchResultIndex + 1);
},

jumpToPreviousSearchResult: function()
{
this.jumpToSearchResult(this._currentSearchResultIndex - 1);
},

showingFirstSearchResult: function()
{
return this._searchResults.length &&  this._currentSearchResultIndex === 0;
},

showingLastSearchResult: function()
{
return this._searchResults.length && this._currentSearchResultIndex === (this._searchResults.length - 1);
},

get currentSearchResultIndex()
{
return this._currentSearchResultIndex;
},

jumpToSearchResult: function(index)
{
if (!this.loaded || !this._searchResults.length)
return;
this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
this._textEditor.markAndRevealRange(this._searchResults[this._currentSearchResultIndex]);
},


replaceSearchMatchWith: function(text)
{
var range = this._searchResults[this._currentSearchResultIndex];
if (!range)
return;
this._textEditor.markAndRevealRange(null);

this._isReplacing = true;
var newRange = this._textEditor.editRange(range, text);
delete this._isReplacing;

this._textEditor.setSelection(newRange.collapseToEnd());
},


replaceAllWith: function(query, replacement)
{
this._textEditor.markAndRevealRange(null);

var text = this._textEditor.text();
var range = this._textEditor.range();
text = text.replace(WebInspector.SourceFrame.createSearchRegex(query, "g"), replacement);

this._isReplacing = true;
this._textEditor.editRange(range, text);
delete this._isReplacing;
},

_collectRegexMatches: function(regexObject)
{
var ranges = [];
for (var i = 0; i < this._textEditor.linesCount; ++i) {
var line = this._textEditor.line(i);
var offset = 0;
do {
var match = regexObject.exec(line);
if (match) {
if (match[0].length)
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 && line);
}
return ranges;
},

_addExistingMessagesToSource: function()
{
var length = this._messages.length;
for (var i = 0; i < length; ++i)
this.addMessageToSource(this._messages[i].line - 1, this._messages[i]);
},


addMessageToSource: function(lineNumber, msg)
{
if (lineNumber >= this._textEditor.linesCount)
lineNumber = this._textEditor.linesCount - 1;
if (lineNumber < 0)
lineNumber = 0;

var rowMessages = this._rowMessages[lineNumber];
if (!rowMessages) {
rowMessages = [];
this._rowMessages[lineNumber] = rowMessages;
}

for (var i = 0; i < rowMessages.length; ++i) {
if (rowMessages[i].consoleMessage.isEqual(msg)) {
rowMessages[i].repeatCount = msg.totalRepeatCount;
this._updateMessageRepeatCount(rowMessages[i]);
return;
}
}

var rowMessage = { consoleMessage: msg };
rowMessages.push(rowMessage);

this._textEditor.beginUpdates();
var messageBubbleElement = this._messageBubbles[lineNumber];
if (!messageBubbleElement) {
messageBubbleElement = document.createElement("div");
messageBubbleElement.className = "webkit-html-message-bubble";
this._messageBubbles[lineNumber] = messageBubbleElement;
this._textEditor.addDecoration(lineNumber, messageBubbleElement);
}

var imageElement = document.createElement("div");
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Error:
messageBubbleElement.addStyleClass("webkit-html-error-message");
imageElement.className = "error-icon-small";
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
messageBubbleElement.addStyleClass("webkit-html-warning-message");
imageElement.className = "warning-icon-small";
break;
}

var messageLineElement = document.createElement("div");
messageLineElement.className = "webkit-html-message-line";
messageBubbleElement.appendChild(messageLineElement);


messageLineElement.appendChild(imageElement);
messageLineElement.appendChild(document.createTextNode(msg.message));

rowMessage.element = messageLineElement;
rowMessage.repeatCount = msg.totalRepeatCount;
this._updateMessageRepeatCount(rowMessage);
this._textEditor.endUpdates();
},

_updateMessageRepeatCount: function(rowMessage)
{
if (rowMessage.repeatCount < 2)
return;

if (!rowMessage.repeatCountElement) {
var repeatCountElement = document.createElement("span");
rowMessage.element.appendChild(repeatCountElement);
rowMessage.repeatCountElement = repeatCountElement;
}

rowMessage.repeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", rowMessage.repeatCount);
},


removeMessageFromSource: function(lineNumber, msg)
{
if (lineNumber >= this._textEditor.linesCount)
lineNumber = this._textEditor.linesCount - 1;
if (lineNumber < 0)
lineNumber = 0;

var rowMessages = this._rowMessages[lineNumber];
for (var i = 0; rowMessages && i < rowMessages.length; ++i) {
var rowMessage = rowMessages[i];
if (rowMessage.consoleMessage !== msg)
continue;

var messageLineElement = rowMessage.element;
var messageBubbleElement = messageLineElement.parentElement;
messageBubbleElement.removeChild(messageLineElement);
rowMessages.remove(rowMessage);
if (!rowMessages.length)
delete this._rowMessages[lineNumber];
if (!messageBubbleElement.childElementCount) {
this._textEditor.removeDecoration(lineNumber, messageBubbleElement);
delete this._messageBubbles[lineNumber];
}
break;
}
},

populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
},

populateTextAreaContextMenu: function(contextMenu, lineNumber)
{
},

inheritScrollPositions: function(sourceFrame)
{
this._textEditor.inheritScrollPositions(sourceFrame._textEditor);
},


canEditSource: function()
{
return false;
},


commitEditing: function(text)
{
},


selectionChanged: function(textRange)
{
this._updateSourcePosition(textRange);
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged, textRange);
},


_updateSourcePosition: function(textRange)
{
if (!textRange)
return;

if (textRange.isEmpty()) {
this._sourcePosition.setText(WebInspector.UIString("Line %d, Column %d", textRange.endLine + 1, textRange.endColumn + 1));
return;
}
textRange = textRange.normalize();

var selectedText = this._textEditor.copyRange(textRange);
if (textRange.startLine === textRange.endLine)
this._sourcePosition.setText(WebInspector.UIString("%d characters selected", selectedText.length));
else
this._sourcePosition.setText(WebInspector.UIString("%d lines, %d characters selected", textRange.endLine - textRange.startLine + 1, selectedText.length));
},


scrollChanged: function(lineNumber)
{
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.ScrollChanged, lineNumber);
},

_handleKeyDown: function(e)
{
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
var handler = this._shortcuts[shortcutKey];
if (handler && handler())
e.consume(true);
},

_commitEditing: function()
{
if (this._textEditor.readOnly())
return false;

var content = this._textEditor.text();
this.commitEditing(content);
return true;
},

__proto__: WebInspector.View.prototype
}



WebInspector.TextEditorDelegateForSourceFrame = function(sourceFrame)
{
this._sourceFrame = sourceFrame;
}

WebInspector.TextEditorDelegateForSourceFrame.prototype = {
onTextChanged: function(oldRange, newRange)
{
this._sourceFrame.onTextChanged(oldRange, newRange);
},


selectionChanged: function(textRange)
{
this._sourceFrame.selectionChanged(textRange);
},


scrollChanged: function(lineNumber)
{
this._sourceFrame.scrollChanged(lineNumber);
},

populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
this._sourceFrame.populateLineGutterContextMenu(contextMenu, lineNumber);
},

populateTextAreaContextMenu: function(contextMenu, lineNumber)
{
this._sourceFrame.populateTextAreaContextMenu(contextMenu, lineNumber);
},


createLink: function(hrefValue, isExternal)
{
var targetLocation = WebInspector.ParsedURL.completeURL(this._sourceFrame._url, hrefValue);
return WebInspector.linkifyURLAsNode(targetLocation || hrefValue, hrefValue, undefined, isExternal);
},

__proto__: WebInspector.TextEditorDelegate.prototype
}






WebInspector.ResourceView = function(resource)
{
WebInspector.View.call(this);
this.registerRequiredCSS("resourceView.css");

this.element.addStyleClass("resource-view");
this.resource = resource;
}

WebInspector.ResourceView.prototype = {
hasContent: function()
{
return false;
},

__proto__: WebInspector.View.prototype
}


WebInspector.ResourceView.hasTextContent = function(resource)
{
if (resource.type.isTextType())
return true; 
if (resource.type === WebInspector.resourceTypes.Other)
return resource.content && !resource.contentEncoded;
return false;
}


WebInspector.ResourceView.nonSourceViewForResource = function(resource)
{
switch (resource.type) {
case WebInspector.resourceTypes.Image:
return new WebInspector.ImageView(resource);
case WebInspector.resourceTypes.Font:
return new WebInspector.FontView(resource);
default:
return new WebInspector.ResourceView(resource);
}
}


WebInspector.ResourceSourceFrame = function(resource)
{
this._resource = resource;
WebInspector.SourceFrame.call(this, resource);
}

WebInspector.ResourceSourceFrame.prototype = {
get resource()
{
return this._resource;
},

populateTextAreaContextMenu: function(contextMenu, lineNumber)
{
contextMenu.appendApplicableItems(this._resource);
if (this._resource.request)
contextMenu.appendApplicableItems(this._resource.request);
},

__proto__: WebInspector.SourceFrame.prototype
}


WebInspector.ResourceSourceFrameFallback = function(resource)
{
WebInspector.View.call(this);
this._resource = resource;
this.element.addStyleClass("fill");
this.element.addStyleClass("script-view");
this._content = this.element.createChild("div", "script-view-fallback monospace");
}

WebInspector.ResourceSourceFrameFallback.prototype = {
wasShown: function()
{
if (!this._contentRequested) {
this._contentRequested = true;
this._resource.requestContent(this._contentLoaded.bind(this));
}
},


_contentLoaded: function(content, contentEncoded, mimeType)
{
this._content.textContent = content;
},

__proto__: WebInspector.View.prototype
}





WebInspector.FontView = function(resource)
{
WebInspector.ResourceView.call(this, resource);

this.element.addStyleClass("font");
}

WebInspector.FontView._fontPreviewLines = [ "ABCDEFGHIJKLM", "NOPQRSTUVWXYZ", "abcdefghijklm", "nopqrstuvwxyz", "1234567890" ];

WebInspector.FontView._fontId = 0;

WebInspector.FontView._measureFontSize = 50;

WebInspector.FontView.prototype = {
hasContent: function()
{
return true;
},

_createContentIfNeeded: function()
{
if (this.fontPreviewElement)
return;

var uniqueFontName = "WebInspectorFontPreview" + (++WebInspector.FontView._fontId);

this.fontStyleElement = document.createElement("style");
this.fontStyleElement.textContent = "@font-face { font-family: \"" + uniqueFontName + "\"; src: url(" + this.resource.url + "); }";
document.head.appendChild(this.fontStyleElement);

var fontPreview = document.createElement("div");
for (var i = 0; i < WebInspector.FontView._fontPreviewLines.length; ++i) {
if (i > 0)
fontPreview.appendChild(document.createElement("br"));
fontPreview.appendChild(document.createTextNode(WebInspector.FontView._fontPreviewLines[i]));
}
this.fontPreviewElement = fontPreview.cloneNode(true);
this.fontPreviewElement.style.setProperty("font-family", uniqueFontName);
this.fontPreviewElement.style.setProperty("visibility", "hidden");

this._dummyElement = fontPreview;
this._dummyElement.style.visibility = "hidden";
this._dummyElement.style.zIndex = "-1";
this._dummyElement.style.display = "inline";
this._dummyElement.style.position = "absolute";
this._dummyElement.style.setProperty("font-family", uniqueFontName);
this._dummyElement.style.setProperty("font-size", WebInspector.FontView._measureFontSize + "px");

this.element.appendChild(this.fontPreviewElement);
},

wasShown: function()
{
this._createContentIfNeeded();

this.updateFontPreviewSize();
},

onResize: function()
{
if (this._inResize)
return;

this._inResize = true;
try {
this.updateFontPreviewSize();
} finally {
delete this._inResize;
}
},

_measureElement: function()
{
this.element.appendChild(this._dummyElement);
var result = { width: this._dummyElement.offsetWidth, height: this._dummyElement.offsetHeight };
this.element.removeChild(this._dummyElement);

return result;
},

updateFontPreviewSize: function()
{
if (!this.fontPreviewElement || !this.isShowing())
return;

this.fontPreviewElement.style.removeProperty("visibility");
var dimension = this._measureElement();

const height = dimension.height;
const width = dimension.width;


const containerWidth = this.element.offsetWidth - 50;
const containerHeight = this.element.offsetHeight - 30;

if (!height || !width || !containerWidth || !containerHeight) {
this.fontPreviewElement.style.removeProperty("font-size");
return;
}

var widthRatio = containerWidth / width;
var heightRatio = containerHeight / height;
var finalFontSize = Math.floor(WebInspector.FontView._measureFontSize * Math.min(widthRatio, heightRatio)) - 2;

this.fontPreviewElement.style.setProperty("font-size", finalFontSize + "px", null);
},

__proto__: WebInspector.ResourceView.prototype
}






WebInspector.ImageView = function(resource)
{
WebInspector.ResourceView.call(this, resource);

this.element.addStyleClass("image");
}

WebInspector.ImageView.prototype = {
hasContent: function()
{
return true;
},

wasShown: function()
{
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);
imagePreviewElement.addEventListener("contextmenu", this._contextMenu.bind(this), true);

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";

this.resource.populateImageSource(imagePreviewElement);

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) },
{ 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);
}
var dt = document.createElement("dt");
dt.textContent = WebInspector.UIString("URL");
infoListElement.appendChild(dt);
var dd = document.createElement("dd");
var externalResource = true;
dd.appendChild(WebInspector.linkifyURLAsNode(this.resource.url, undefined, undefined, externalResource));
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;
},

_contextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy image URL" : "Copy Image URL"), this._copyImageURL.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open image in new tab" : "Open Image in New Tab"), this._openInNewTab.bind(this));
contextMenu.show();
},

_copyImageURL: function()
{
InspectorFrontendHost.copyText(this.resource.url);
},

_openInNewTab: function()
{
InspectorFrontendHost.openInNewTab(this.resource.url);
},

__proto__: WebInspector.ResourceView.prototype
}






WebInspector.SplitView = function(isVertical, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight)
{
WebInspector.View.call(this);

this.registerRequiredCSS("splitView.css");

this.element.className = "split-view";

this._firstElement = this.element.createChild("div", "split-view-contents scroll-target split-view-contents-first");
this._secondElement = this.element.createChild("div", "split-view-contents scroll-target split-view-contents-second");

this._resizerElement = this.element.createChild("div", "split-view-resizer");
this.installResizer(this._resizerElement);
this._resizable = true;

this._savedSidebarWidth = defaultSidebarWidth || 200;
this._savedSidebarHeight = defaultSidebarHeight || this._savedSidebarWidth;

if (0 < this._savedSidebarWidth && this._savedSidebarWidth < 1 &&
0 < this._savedSidebarHeight && this._savedSidebarHeight < 1)
this._useFraction = true;

this._sidebarSizeSettingName = sidebarSizeSettingName;

this.setSecondIsSidebar(true);

this._innerSetVertical(isVertical);
}

WebInspector.SplitView.prototype = {

isVertical: function()
{
return this._isVertical;
},


setVertical: function(isVertical)
{
if (this._isVertical === isVertical)
return;

this._innerSetVertical(isVertical);

if (this.isShowing())
this._updateLayout();
},


_innerSetVertical: function(isVertical)
{
this.element.removeStyleClass(this._isVertical ? "split-view-vertical" : "split-view-horizontal");
this._isVertical = isVertical;
this.element.addStyleClass(this._isVertical ? "split-view-vertical" : "split-view-horizontal");
},

_updateLayout: function()
{
this._updateTotalSize();

delete this._sidebarSize;  
this.setSidebarSize(this._lastSidebarSize());
},


firstElement: function()
{
return this._firstElement;
},


secondElement: function()
{
return this._secondElement;
},


get mainElement()
{
return this.isSidebarSecond() ? this.firstElement() : this.secondElement();
},


get sidebarElement()
{
return this.isSidebarSecond() ? this.secondElement() : this.firstElement();
},


isSidebarSecond: function()
{
return this._secondIsSidebar;
},


setSecondIsSidebar: function(secondIsSidebar)
{
this.sidebarElement.removeStyleClass("split-view-sidebar");
this._secondIsSidebar = secondIsSidebar;
this.sidebarElement.addStyleClass("split-view-sidebar");
},


resizerElement: function()
{
return this._resizerElement;
},

showOnlyFirst: function()
{
this._showOnly(this._firstElement, this._secondElement);
},

showOnlySecond: function()
{
this._showOnly(this._secondElement, this._firstElement);
},


_showOnly: function(sideA, sideB)
{
sideA.removeStyleClass("hidden");
sideA.addStyleClass("maximized");
sideB.addStyleClass("hidden");
sideB.removeStyleClass("maximized");
this._removeAllLayoutProperties();

this._isShowingOne = true;
this.setResizable(false);
this.doResize();
},

_removeAllLayoutProperties: function()
{
this._firstElement.style.removeProperty("right");
this._firstElement.style.removeProperty("bottom");
this._firstElement.style.removeProperty("width");
this._firstElement.style.removeProperty("height");

this._secondElement.style.removeProperty("left");
this._secondElement.style.removeProperty("top");
this._secondElement.style.removeProperty("width");
this._secondElement.style.removeProperty("height");

this._resizerElement.style.removeProperty("left");
this._resizerElement.style.removeProperty("right");
this._resizerElement.style.removeProperty("top");
this._resizerElement.style.removeProperty("bottom");

this._resizerElement.style.removeProperty("margin-left");
this._resizerElement.style.removeProperty("margin-right");
this._resizerElement.style.removeProperty("margin-top");
this._resizerElement.style.removeProperty("margin-bottom");
},

showBoth: function()
{
this._isShowingOne = false;
this._firstElement.removeStyleClass("hidden");
this._firstElement.removeStyleClass("maximized");
this._secondElement.removeStyleClass("hidden");
this._secondElement.removeStyleClass("maximized");

this._updateLayout();

this.setResizable(true);
this.doResize();
},


setResizable: function(resizable)
{
if (this._resizable === resizable)
return;
this._resizable = resizable;
if (resizable)
this._resizerElement.removeStyleClass("hidden");
else
this._resizerElement.addStyleClass("hidden");
},


setSidebarSize: function(size)
{
if (this._sidebarSize === size)
return;

size = this.applyConstraints(size);
if (size < 0) {

this._sidebarSize = size;
return;
}
this._innerSetSidebarSize(size);
this._saveSidebarSize(size);
},


sidebarSize: function()
{
return this._sidebarSize;
},


totalSize: function()
{
return this._totalSize;
},

_updateTotalSize: function()
{
this._totalSize = this._isVertical ? this.element.offsetWidth : this.element.offsetHeight;
if (this._useFraction)
this._sidebarSize = this._lastSidebarSize();
},


_innerSetSidebarSize: function(size)
{
if (this._isShowingOne)
return;

this._removeAllLayoutProperties();

var sizeValue;
if (this._useFraction)
sizeValue = (size / this._totalSize) * 100 + "%";
else
sizeValue = size + "px";

if (this._isVertical) {
var resizerWidth = this._resizerElement.offsetWidth;
if (this._secondIsSidebar) {
this._firstElement.style.right = sizeValue;
this._secondElement.style.width = sizeValue;
this._resizerElement.style.right = sizeValue;
this._resizerElement.style.marginRight = -resizerWidth / 2 + "px";
} else {
this._firstElement.style.width = sizeValue;
this._secondElement.style.left = sizeValue;
this._resizerElement.style.left = sizeValue;
this._resizerElement.style.marginLeft = -resizerWidth / 2 + "px";
}
} else {
var resizerHeight = this._resizerElement.offsetHeight;

if (this._secondIsSidebar) {
this._firstElement.style.bottom = sizeValue;
this._secondElement.style.height = sizeValue;
this._resizerElement.style.bottom = sizeValue;
this._resizerElement.style.marginBottom = -resizerHeight / 2 + "px";
} else {
this._firstElement.style.height = sizeValue;
this._secondElement.style.top = sizeValue;
this._resizerElement.style.top = sizeValue;
this._resizerElement.style.marginTop = -resizerHeight / 2 + "px";
}
}

this._sidebarSize = size;
this.doResize();
},


applyConstraints: function(size)
{
const minSize = 20;
size = Math.max(size, minSize);
if (this._totalSize - size < minSize)
size = this._totalSize - minSize;
return size < minSize ? -1 : size;
},

wasShown: function()
{
this._updateLayout();
},

onResize: function()
{
if (this._sidebarSize < 0)
this._updateLayout();
else
this._updateTotalSize();
},


_startResizerDragging: function(event)
{
if (!this._resizable)
return false;

this._dragOffset = (this._secondIsSidebar ? this._totalSize - this._sidebarSize : this._sidebarSize) - (this._isVertical ? event.pageX : event.pageY);
return true;
},


_resizerDragging: function(event)
{
var newOffset = (this._isVertical ? event.pageX : event.pageY) + this._dragOffset;
var newSize = (this._secondIsSidebar ? this._totalSize - newOffset : newOffset);
this.setSidebarSize(newSize);
event.preventDefault();
},


_endResizerDragging: function(event)
{
delete this._dragOffset;
},


installResizer: function(resizerElement)
{
resizerElement.addEventListener("mousedown", this._onDragStart.bind(this), false);
},


_onDragStart: function(event)
{
WebInspector._elementDragStart(this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), this._isVertical ? "ew-resize" : "ns-resize", event);
},


_sizeSetting: function()
{
if (!this._sidebarSizeSettingName)
return null;

var settingName = this._sidebarSizeSettingName + (this._isVertical ? "" : "H");
if (!WebInspector.settings[settingName])
WebInspector.settings[settingName] = WebInspector.settings.createSetting(settingName, undefined);

return WebInspector.settings[settingName];
},


_lastSidebarSize: function()
{
var sizeSetting = this._sizeSetting();
var size = sizeSetting ? sizeSetting.get() : 0;
if (!size)
size = this._isVertical ? this._savedSidebarWidth : this._savedSidebarHeight;
if (this._useFraction)
size *= this._totalSize;
return size;
},


_saveSidebarSize: function(size)
{
if (this._useFraction)
size /= this._totalSize;

if (this._isVertical)
this._savedSidebarWidth = size;
else
this._savedSidebarHeight = size;

var sizeSetting = this._sizeSetting();
if (sizeSetting)
sizeSetting.set(size);
},

__proto__: WebInspector.View.prototype
}






WebInspector.SidebarView = function(sidebarPosition, sidebarWidthSettingName, defaultSidebarWidth, defaultSidebarHeight)
{
WebInspector.SplitView.call(this, true, sidebarWidthSettingName, defaultSidebarWidth, defaultSidebarHeight);

this._minimumSidebarWidth = Preferences.minSidebarWidth;
this._minimumMainWidthPercent = 50;

this._minimumSidebarHeight = Preferences.minSidebarHeight;
this._minimumMainHeightPercent = 50;

this._sidebarPosition = sidebarPosition || WebInspector.SidebarView.SidebarPosition.Start;
this.setSecondIsSidebar(this._sidebarPosition === WebInspector.SidebarView.SidebarPosition.End);
}

WebInspector.SidebarView.EventTypes = {
Resized: "Resized"
}


WebInspector.SidebarView.SidebarPosition = {
Start: "Start",
End: "End"
}

WebInspector.SidebarView.prototype = {

setMinimumSidebarWidth: function(width)
{
this._minimumSidebarWidth = width;
},


setMinimumSidebarHeight: function(height)
{
this._minimumSidebarHeight = height;
},


setMinimumMainWidthPercent: function(widthPercent)
{
this._minimumMainWidthPercent = widthPercent;
},


setMinimumMainHeightPercent: function(heightPercent)
{
this._minimumMainHeightPercent = heightPercent;
},


setSidebarWidth: function(width)
{
this.setSidebarSize(width);
},


sidebarWidth: function()
{
return this.sidebarSize();
},

onResize: function()
{
WebInspector.SplitView.prototype.onResize.call(this);
this.dispatchEventToListeners(WebInspector.SidebarView.EventTypes.Resized, this.sidebarWidth());
},


applyConstraints: function(size)
{
var from = this.isVertical() ? this._minimumSidebarWidth : this._minimumSidebarHeight;
var minMainSizePercent = this.isVertical() ? this._minimumMainWidthPercent : this._minimumMainHeightPercent;
var to = this.totalSize() * (100 - minMainSizePercent) / 100;
return from > to ? -1 : Number.constrain(size, from, to);
},

hideMainElement: function()
{
if (this.isSidebarSecond())
this.showOnlySecond();
else
this.showOnlyFirst();
},

showMainElement: function()
{
this.showBoth();
},

hideSidebarElement: function()
{
if (this.isSidebarSecond())
this.showOnlyFirst();
else
this.showOnlySecond();
},

showSidebarElement: function()
{
this.showBoth();
},


elementsToRestoreScrollPositionsFor: function()
{
return [ this.mainElement, this.sidebarElement ];
},

__proto__: WebInspector.SplitView.prototype
}






WebInspector.ConsolePanel = function()
{
WebInspector.Panel.call(this, "console");

WebInspector.consoleView.addEventListener(WebInspector.ConsoleView.Events.EntryAdded, this._consoleMessageAdded, this);
WebInspector.consoleView.addEventListener(WebInspector.ConsoleView.Events.ConsoleCleared, this._consoleCleared, this);
this._view = WebInspector.consoleView;
}

WebInspector.ConsolePanel.prototype = {
get statusBarItems()
{
return this._view.statusBarItems;
},

wasShown: function()
{
WebInspector.Panel.prototype.wasShown.call(this);
if (WebInspector.drawer.visible) {
WebInspector.drawer.hide(WebInspector.Drawer.AnimationType.Immediately);
this._drawerWasVisible = true;
}
this._view.show(this.element);
},

willHide: function()
{
if (this._drawerWasVisible) {
WebInspector.drawer.show(this._view, WebInspector.Drawer.AnimationType.Immediately);
delete this._drawerWasVisible;
}
WebInspector.Panel.prototype.willHide.call(this);
},

searchCanceled: function()
{
this._clearCurrentSearchResultHighlight();
delete this._searchResults;
delete this._searchRegex;
},


performSearch: function(query)
{
WebInspector.searchController.updateSearchMatchesCount(0, this);
this.searchCanceled();
this._searchRegex = createPlainTextSearchRegex(query, "gi");

this._searchResults = [];
var messages = WebInspector.console.messages;
for (var i = 0; i < messages.length; i++) {
if (messages[i].matchesRegex(this._searchRegex)) {
this._searchResults.push(messages[i]);
this._searchRegex.lastIndex = 0;
}
}
WebInspector.searchController.updateSearchMatchesCount(this._searchResults.length, this);
this._currentSearchResultIndex = -1;
if (this._searchResults.length)
this._jumpToSearchResult(0);
},

jumpToNextSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
this._jumpToSearchResult((this._currentSearchResultIndex + 1) % this._searchResults.length);
},

jumpToPreviousSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
var index = this._currentSearchResultIndex - 1;
if (index === -1)
index = this._searchResults.length - 1;
this._jumpToSearchResult(index);
},

_clearCurrentSearchResultHighlight: function()
{
if (!this._searchResults)
return;
var highlightedMessage = this._searchResults[this._currentSearchResultIndex];
if (highlightedMessage)
highlightedMessage.clearHighlight();
this._currentSearchResultIndex = -1;
},

_jumpToSearchResult: function(index)
{
this._clearCurrentSearchResultHighlight();
this._currentSearchResultIndex = index;
WebInspector.searchController.updateCurrentMatchIndex(this._currentSearchResultIndex, this);
this._searchResults[index].highlightSearchResults(this._searchRegex);
},

_consoleMessageAdded: function(event)
{
if (!this._searchRegex || !this.isShowing())
return;
var message = event.data;
this._searchRegex.lastIndex = 0;
if (message.matchesRegex(this._searchRegex)) {
this._searchResults.push(message);
WebInspector.searchController.updateSearchMatchesCount(this._searchResults.length, this);
}
},

_consoleCleared: function()
{
if (!this._searchResults)
return;
this._clearCurrentSearchResultHighlight();
this._searchResults.length = 0;
if (this.isShowing())
WebInspector.searchController.updateSearchMatchesCount(0, this);
},

__proto__: WebInspector.Panel.prototype
}





function defineCommonExtensionSymbols(apiPrivate)
{
if (!apiPrivate.audits)
apiPrivate.audits = {};
apiPrivate.audits.Severity = {
Info: "info",
Warning: "warning",
Severe: "severe"
};

if (!apiPrivate.console)
apiPrivate.console = {};
apiPrivate.console.Severity = {
Debug: "debug",
Log: "log",
Warning: "warning",
Error: "error"
};

if (!apiPrivate.panels)
apiPrivate.panels = {};
apiPrivate.panels.SearchAction = {
CancelSearch: "cancelSearch",
PerformSearch: "performSearch",
NextSearchResult: "nextSearchResult",
PreviousSearchResult: "previousSearchResult"
};

apiPrivate.Events = {
AuditStarted: "audit-started-",
ButtonClicked: "button-clicked-",
ConsoleMessageAdded: "console-message-added",
ElementsPanelObjectSelected: "panel-objectSelected-elements",
NetworkRequestFinished: "network-request-finished",
OpenResource: "open-resource",
PanelSearch: "panel-search-",
ResourceAdded: "resource-added",
ResourceContentCommitted: "resource-content-committed",
TimelineEventRecorded: "timeline-event-recorded",
ViewShown: "view-shown-",
ViewHidden: "view-hidden-"
};

apiPrivate.Commands = {
AddAuditCategory: "addAuditCategory",
AddAuditResult: "addAuditResult",
AddConsoleMessage: "addConsoleMessage",
AddRequestHeaders: "addRequestHeaders",
CreatePanel: "createPanel",
CreateSidebarPane: "createSidebarPane",
CreateStatusBarButton: "createStatusBarButton",
EvaluateOnInspectedPage: "evaluateOnInspectedPage",
GetConsoleMessages: "getConsoleMessages",
GetHAR: "getHAR",
GetPageResources: "getPageResources",
GetRequestContent: "getRequestContent",
GetResourceContent: "getResourceContent",
Reload: "Reload",
Subscribe: "subscribe",
SetOpenResourceHandler: "setOpenResourceHandler",
SetResourceContent: "setResourceContent",
SetSidebarContent: "setSidebarContent",
SetSidebarHeight: "setSidebarHeight",
SetSidebarPage: "setSidebarPage",
ShowPanel: "showPanel",
StopAuditCategoryRun: "stopAuditCategoryRun",
Reload: "Reload",
Unsubscribe: "unsubscribe",
UpdateAuditProgress: "updateAuditProgress",
UpdateButton: "updateButton",
InspectedURLChanged: "inspectedURLChanged"
};
}

function injectedExtensionAPI(injectedScriptId)
{

var apiPrivate = {};

defineCommonExtensionSymbols(apiPrivate);

var commands = apiPrivate.Commands;
var events = apiPrivate.Events;
var userAction = false;








function EventSinkImpl(type, customDispatch)
{
this._type = type;
this._listeners = [];
this._customDispatch = customDispatch;
}

EventSinkImpl.prototype = {
addListener: function(callback)
{
if (typeof callback !== "function")
throw "addListener: callback is not a function";
if (this._listeners.length === 0)
extensionServer.sendRequest({ command: commands.Subscribe, type: this._type });
this._listeners.push(callback);
extensionServer.registerHandler("notify-" + this._type, this._dispatch.bind(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: commands.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.network = new Network();
defineDeprecatedProperty(this, "webInspector", "resources", "network");
this.timeline = new Timeline();
this.console = new ConsoleAPI();
}


function ConsoleAPI()
{
this.onMessageAdded = new EventSink(events.ConsoleMessageAdded);
}

ConsoleAPI.prototype = {
getMessages: function(callback)
{
extensionServer.sendRequest({ command: commands.GetConsoleMessages }, callback);
},

addMessage: function(severity, text, url, line)
{
extensionServer.sendRequest({ command: commands.AddConsoleMessage, severity: severity, text: text, url: url, line: line });
},

get Severity()
{
return apiPrivate.console.Severity;
}
}


function Network()
{
function dispatchRequestEvent(message)
{
var request = message.arguments[1];
request.__proto__ = new Request(message.arguments[0]);
this._fire(request);
}
this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispatchRequestEvent);
defineDeprecatedProperty(this, "network", "onFinished", "onRequestFinished");
this.onNavigated = new EventSink(events.InspectedURLChanged);
}

Network.prototype = {
getHAR: function(callback)
{
function callbackWrapper(result)
{
var entries = (result && result.entries) || [];
for (var i = 0; i < entries.length; ++i) {
entries[i].__proto__ = new Request(entries[i]._requestId);
delete entries[i]._requestId;
}
callback(result);
}
return extensionServer.sendRequest({ command: commands.GetHAR }, callback && callbackWrapper);
},

addRequestHeaders: function(headers)
{
return extensionServer.sendRequest({ command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname });
}
}


function RequestImpl(id)
{
this._id = id;
}

RequestImpl.prototype = {
getContent: function(callback)
{
function callbackWrapper(response)
{
callback(response.content, response.encoding);
}
extensionServer.sendRequest({ command: commands.GetRequestContent, 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, panelGetter.bind(null, panel));
}

Panels.prototype = {
create: function(title, icon, page, callback)
{
var id = "extension-panel-" + extensionServer.nextObjectId();
var request = {
command: commands.CreatePanel,
id: id,
title: title,
icon: icon,
page: page
};
extensionServer.sendRequest(request, callback && callback.bind(this, new ExtensionPanel(id)));
},

setOpenResourceHandler: function(callback)
{
var hadHandler = extensionServer.hasHandler(events.OpenResource);

if (!callback)
extensionServer.unregisterHandler(events.OpenResource);
else {
function callbackWrapper(message)
{

userAction = true;
try {
callback.call(null, new Resource(message.resource), message.lineNumber);
} finally {
userAction = false;
}
}
extensionServer.registerHandler(events.OpenResource, callbackWrapper);
}

if (hadHandler === !callback)
extensionServer.sendRequest({ command: commands.SetOpenResourceHandler, "handlerPresent": !!callback });
},

get SearchAction()
{
return apiPrivate.panels.SearchAction;
}
}


function ExtensionViewImpl(id)
{
this._id = id;

function dispatchShowEvent(message)
{
var frameIndex = message.arguments[0];
this._fire(window.parent.frames[frameIndex]);
}
this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent);
this.onHidden = new EventSink(events.ViewHidden + id);
}


function PanelWithSidebarImpl(id)
{
this._id = id;
}

PanelWithSidebarImpl.prototype = {
createSidebarPane: function(title, callback)
{
var id = "extension-sidebar-" + extensionServer.nextObjectId();
var request = {
command: commands.CreateSidebarPane,
panel: this._id,
id: id,
title: title
};
function callbackWrapper()
{
callback(new ExtensionSidebarPane(id));
}
extensionServer.sendRequest(request, callback && callbackWrapper);
},

__proto__: ExtensionViewImpl.prototype
}


function ElementsPanel()
{
var id = "elements";
PanelWithSidebar.call(this, id);
this.onSelectionChanged = new EventSink(events.ElementsPanelObjectSelected);
}


function ExtensionPanelImpl(id)
{
ExtensionViewImpl.call(this, id);
this.onSearch = new EventSink(events.PanelSearch + id);
}

ExtensionPanelImpl.prototype = {
createStatusBarButton: function(iconPath, tooltipText, disabled)
{
var id = "button-" + extensionServer.nextObjectId();
var request = {
command: commands.CreateStatusBarButton,
panel: this._id,
id: id,
icon: iconPath,
tooltip: tooltipText,
disabled: !!disabled
};
extensionServer.sendRequest(request);
return new Button(id);
},

show: function()
{
if (!userAction)
return;

var request = {
command: commands.ShowPanel,
id: this._id
};
extensionServer.sendRequest(request);
},

__proto__: ExtensionViewImpl.prototype
}


function ExtensionSidebarPaneImpl(id)
{
ExtensionViewImpl.call(this, id);
}

ExtensionSidebarPaneImpl.prototype = {
setHeight: function(height)
{
extensionServer.sendRequest({ command: commands.SetSidebarHeight, id: this._id, height: height });
},

setExpression: function(expression, rootTitle, evaluateOptions)
{
var request = {
command: commands.SetSidebarContent,
id: this._id,
expression: expression,
rootTitle: rootTitle,
evaluateOnPage: true,
};
if (typeof evaluateOptions === "object")
request.evaluateOptions = evaluateOptions;
extensionServer.sendRequest(request, extractCallbackArgument(arguments));
},

setObject: function(jsonObject, rootTitle, callback)
{
extensionServer.sendRequest({ command: commands.SetSidebarContent, id: this._id, expression: jsonObject, rootTitle: rootTitle }, callback);
},

setPage: function(page)
{
extensionServer.sendRequest({ command: commands.SetSidebarPage, id: this._id, page: page });
}
}


function ButtonImpl(id)
{
this._id = id;
this.onClicked = new EventSink(events.ButtonClicked + id);
}

ButtonImpl.prototype = {
update: function(iconPath, tooltipText, disabled)
{
var request = {
command: commands.UpdateButton,
id: this._id,
icon: iconPath,
tooltip: tooltipText,
disabled: !!disabled
};
extensionServer.sendRequest(request);
}
};


function Audits()
{
}

Audits.prototype = {
addCategory: function(displayName, resultCount)
{
var id = "extension-audit-category-" + extensionServer.nextObjectId();
if (typeof resultCount !== "undefined")
console.warn("Passing resultCount to audits.addCategory() is deprecated. Use AuditResult.updateProgress() instead.");
extensionServer.sendRequest({ command: commands.AddAuditCategory, id: id, displayName: displayName, resultCount: resultCount });
return new AuditCategory(id);
}
}


function AuditCategoryImpl(id)
{
function dispatchAuditEvent(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(events.AuditStarted + id, dispatchAuditEvent);
}


function AuditResultImpl(id)
{
this._id = id;

this.createURL = this._nodeFactory.bind(null, "url");
this.createSnippet = this._nodeFactory.bind(null, "snippet");
this.createText = this._nodeFactory.bind(null, "text");
this.createObject = this._nodeFactory.bind(null, "object");
this.createNode = this._nodeFactory.bind(null, "node");
}

AuditResultImpl.prototype = {
addResult: function(displayName, description, severity, details)
{

if (details && !(details instanceof AuditResultNode))
details = new AuditResultNode(details instanceof Array ? details : [details]);

var request = {
command: commands.AddAuditResult,
resultId: this._id,
displayName: displayName,
description: description,
severity: severity,
details: details
};
extensionServer.sendRequest(request);
},

createResult: function()
{
return new AuditResultNode(Array.prototype.slice.call(arguments));
},

updateProgress: function(worked, totalWork)
{
extensionServer.sendRequest({ command: commands.UpdateAuditProgress, resultId: this._id, progress: worked / totalWork });
},

done: function()
{
extensionServer.sendRequest({ command: commands.StopAuditCategoryRun, resultId: this._id });
},

get Severity()
{
return apiPrivate.audits.Severity;
},

createResourceLink: function(url, lineNumber)
{
return {
type: "resourceLink",
arguments: [url, lineNumber && lineNumber - 1]
};
},

_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 = new AuditResultNode(Array.prototype.slice.call(arguments));
this.children.push(node);
return node;
}
};


function InspectedWindow()
{
function dispatchResourceEvent(message)
{
this._fire(new Resource(message.arguments[0]));
}
function dispatchResourceContentEvent(message)
{
this._fire(new Resource(message.arguments[0]), message.arguments[1]);
}
this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent);
this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent);
}

InspectedWindow.prototype = {
reload: function(optionsOrUserAgent)
{
var options = null;
if (typeof optionsOrUserAgent === "object")
options = optionsOrUserAgent;
else if (typeof optionsOrUserAgent === "string") {
options = { userAgent: optionsOrUserAgent };
console.warn("Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. " +
"Use inspectedWindow.reload({ userAgent: value}) instead.");
}
return extensionServer.sendRequest({ command: commands.Reload, options: options });
},

eval: function(expression, evaluateOptions)
{
var callback = extractCallbackArgument(arguments);
function callbackWrapper(result)
{
if (result.isError || result.isException)
callback(undefined, result);
else
callback(result.value);
}
var request = {
command: commands.EvaluateOnInspectedPage,
expression: expression
};
if (typeof evaluateOptions === "object")
request.evaluateOptions = evaluateOptions;
return extensionServer.sendRequest(request, callback && callbackWrapper);
},

getResources: function(callback)
{
function wrapResource(resourceData)
{
return new Resource(resourceData);
}
function callbackWrapper(resources)
{
callback(resources.map(wrapResource));
}
return extensionServer.sendRequest({ command: commands.GetPageResources }, callback && callbackWrapper);
}
}


function ResourceImpl(resourceData)
{
this._url = resourceData.url
this._type = resourceData.type;
}

ResourceImpl.prototype = {
get url()
{
return this._url;
},

get type()
{
return this._type;
},

getContent: function(callback)
{
function callbackWrapper(response)
{
callback(response.content, response.encoding);
}

return extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper);
},

setContent: function(content, commit, callback)
{
return extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback);
}
}


function TimelineImpl()
{
this.onEventRecorded = new EventSink(events.TimelineEventRecorded);
}


function ExtensionServerClient()
{
this._callbacks = {};
this._handlers = {};
this._lastRequestId = 0;
this._lastObjectId = 0;

this.registerHandler("callback", this._onCallback.bind(this));

var channel = new MessageChannel();
this._port = channel.port1;
this._port.addEventListener("message", this._onMessage.bind(this), false);
this._port.start();

window.parent.postMessage("registerExtension", [ channel.port2 ], "*");
}

ExtensionServerClient.prototype = {

sendRequest: function(message, callback)
{
if (typeof callback === "function")
message.requestId = this._registerCallback(callback);
return this._port.postMessage(message);
},

hasHandler: function(command)
{
return !!this._handlers[command];
},

registerHandler: function(command, handler)
{
this._handlers[command] = handler;
},

unregisterHandler: function(command)
{
delete this._handlers[command];
},

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) {
var callback = this._callbacks[request.requestId];
delete this._callbacks[request.requestId];
callback(request.result);
}
},

_onMessage: function(event)
{
var request = event.data;
var handler = this._handlers[request.command];
if (handler)
handler.call(this, request);
}
}

function populateInterfaceClass(interface, implementation)
{
for (var member in implementation) {
if (member.charAt(0) === "_")
continue;
var descriptor = null;

for (var owner = implementation; owner && !descriptor; owner = owner.__proto__)
descriptor = Object.getOwnPropertyDescriptor(owner, member);
if (!descriptor)
continue;
if (typeof descriptor.value === "function")
interface[member] = descriptor.value.bind(implementation);
else if (typeof descriptor.get === "function")
interface.__defineGetter__(member, descriptor.get.bind(implementation));
else
Object.defineProperty(interface, member, descriptor);
}
}

function declareInterfaceClass(implConstructor)
{
return function()
{
var impl = { __proto__: implConstructor.prototype };
implConstructor.apply(impl, arguments);
populateInterfaceClass(this, impl);
}
}

function defineDeprecatedProperty(object, className, oldName, newName)
{
var warningGiven = false;
function getter()
{
if (!warningGiven) {
console.warn(className + "." + oldName + " is deprecated. Use " + className + "." + newName + " instead");
warningGiven = true;
}
return object[newName];
}
object.__defineGetter__(oldName, getter);
}

function extractCallbackArgument(args)
{
var lastArgument = args[args.length - 1];
return typeof lastArgument === "function" ? lastArgument : undefined;
}

var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
var AuditResult = declareInterfaceClass(AuditResultImpl);
var Button = declareInterfaceClass(ButtonImpl);
var EventSink = declareInterfaceClass(EventSinkImpl);
var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
var Request = declareInterfaceClass(RequestImpl);
var Resource = declareInterfaceClass(ResourceImpl);
var Timeline = declareInterfaceClass(TimelineImpl);


if (!extensionServer)
extensionServer = new ExtensionServerClient();

return new InspectorExtensionAPI();
}


function buildExtensionAPIInjectedScript(extensionInfo)
{
return "(function(injectedScriptId){ " +
"var extensionServer;" +
defineCommonExtensionSymbols.toString() + ";" +
injectedExtensionAPI.toString() + ";" +
buildPlatformExtensionAPI(extensionInfo) + ";" +
"platformExtensionAPI(injectedExtensionAPI(injectedScriptId));" +
"return {};" +
"})";
}






WebInspector.ExtensionAuditCategory = function(extensionOrigin, id, displayName, ruleCount)
{
this._extensionOrigin = extensionOrigin;
this._id = id;
this._displayName = displayName;
this._ruleCount  = ruleCount;
}

WebInspector.ExtensionAuditCategory.prototype = {

get id()
{
return this._id;
},

get displayName()
{
return this._displayName;
},


run: function(requests, ruleResultCallback, categoryDoneCallback, progress)
{
var results = new WebInspector.ExtensionAuditCategoryResults(this, ruleResultCallback, categoryDoneCallback, progress);
WebInspector.extensionServer.startAuditRun(this, results);
}
}


WebInspector.ExtensionAuditCategoryResults = function(category, ruleResultCallback, categoryDoneCallback, progress)
{
this._category = category;
this._ruleResultCallback = ruleResultCallback;
this._categoryDoneCallback = categoryDoneCallback;
this._progress = progress;
this._progress.setTotalWork(1);
this._expectedResults = category._ruleCount;
this._actualResults = 0;

this.id = category.id + "-" + ++WebInspector.ExtensionAuditCategoryResults._lastId;
}

WebInspector.ExtensionAuditCategoryResults.prototype = {
done: function()
{
WebInspector.extensionServer.stopAuditRun(this);
this._progress.done();
this._categoryDoneCallback();
},

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 contents = WebInspector.auditFormatters.partiallyApply(WebInspector.ExtensionAuditFormatters, this, node.contents);
var addedNode = parent.addChild(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._ruleResultCallback(result);
++this._actualResults;
if (typeof this._expectedResults === "number") {
this._progress.setWorked(this._actualResults / this._expectedResults);
if (this._actualResults === this._expectedResults)
this.done();
}
},


updateProgress: function(progress)
{
this._progress.setWorked(progress);
},


evaluate: function(expression, evaluateOptions, callback)
{

function onEvaluate(error, result, wasThrown)
{
if (wasThrown)
return;
var object = WebInspector.RemoteObject.fromPayload(result);
callback(object);
}
WebInspector.extensionServer.evaluate(expression, false, false, evaluateOptions, this._category._extensionOrigin, onEvaluate);
}
}

WebInspector.ExtensionAuditFormatters = {

object: function(expression, title, evaluateOptions)
{
var parentElement = document.createElement("div");
function onEvaluate(remoteObject)
{
var section = new WebInspector.ObjectPropertiesSection(remoteObject, title);
section.expanded = true;
section.editable = false;
parentElement.appendChild(section.element);
}
this.evaluate(expression, evaluateOptions, onEvaluate);
return parentElement;
},


node: function(expression, evaluateOptions)
{
var parentElement = document.createElement("div");

function onNodeAvailable(nodeId)
{
if (!nodeId)
return;
var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true);
treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
treeOutline.element.addStyleClass("outline-disclosure");
treeOutline.setVisible(true);
parentElement.appendChild(treeOutline.element);
}

function onEvaluate(remoteObject)
{
remoteObject.pushNodeToFrontend(onNodeAvailable);
}
this.evaluate(expression, evaluateOptions, onEvaluate);
return parentElement;
}
}

WebInspector.ExtensionAuditCategoryResults._lastId = 0;






WebInspector.ExtensionServer = function()
{
this._clientObjects = {};
this._handlers = {};
this._subscribers = {};
this._subscriptionStartHandlers = {};
this._subscriptionStopHandlers = {};
this._extraHeaders = {};
this._requests = {};
this._lastRequestId = 0;
this._registeredExtensions = {};
this._status = new WebInspector.ExtensionStatus();

var commands = WebInspector.extensionAPI.Commands;

this._registerHandler(commands.AddAuditCategory, this._onAddAuditCategory.bind(this));
this._registerHandler(commands.AddAuditResult, this._onAddAuditResult.bind(this));
this._registerHandler(commands.AddConsoleMessage, this._onAddConsoleMessage.bind(this));
this._registerHandler(commands.AddRequestHeaders, this._onAddRequestHeaders.bind(this));
this._registerHandler(commands.CreatePanel, this._onCreatePanel.bind(this));
this._registerHandler(commands.CreateSidebarPane, this._onCreateSidebarPane.bind(this));
this._registerHandler(commands.CreateStatusBarButton, this._onCreateStatusBarButton.bind(this));
this._registerHandler(commands.EvaluateOnInspectedPage, this._onEvaluateOnInspectedPage.bind(this));
this._registerHandler(commands.GetHAR, this._onGetHAR.bind(this));
this._registerHandler(commands.GetConsoleMessages, this._onGetConsoleMessages.bind(this));
this._registerHandler(commands.GetPageResources, this._onGetPageResources.bind(this));
this._registerHandler(commands.GetRequestContent, this._onGetRequestContent.bind(this));
this._registerHandler(commands.GetResourceContent, this._onGetResourceContent.bind(this));
this._registerHandler(commands.Reload, this._onReload.bind(this));
this._registerHandler(commands.SetOpenResourceHandler, this._onSetOpenResourceHandler.bind(this));
this._registerHandler(commands.SetResourceContent, this._onSetResourceContent.bind(this));
this._registerHandler(commands.SetSidebarHeight, this._onSetSidebarHeight.bind(this));
this._registerHandler(commands.SetSidebarContent, this._onSetSidebarContent.bind(this));
this._registerHandler(commands.SetSidebarPage, this._onSetSidebarPage.bind(this));
this._registerHandler(commands.ShowPanel, this._onShowPanel.bind(this));
this._registerHandler(commands.StopAuditCategoryRun, this._onStopAuditCategoryRun.bind(this));
this._registerHandler(commands.Subscribe, this._onSubscribe.bind(this));
this._registerHandler(commands.Unsubscribe, this._onUnsubscribe.bind(this));
this._registerHandler(commands.UpdateButton, this._onUpdateButton.bind(this));
this._registerHandler(commands.UpdateAuditProgress, this._onUpdateAuditProgress.bind(this));

window.addEventListener("message", this._onWindowMessage.bind(this), false);
}

WebInspector.ExtensionServer.prototype = {
hasExtensions: function()
{
return !!Object.keys(this._registeredExtensions).length;
},

notifySearchAction: function(panelId, action, searchString)
{
this._postNotification(WebInspector.extensionAPI.Events.PanelSearch + panelId, action, searchString);
},

notifyViewShown: function(identifier, frameIndex)
{
this._postNotification(WebInspector.extensionAPI.Events.ViewShown + identifier, frameIndex);
},

notifyViewHidden: function(identifier)
{
this._postNotification(WebInspector.extensionAPI.Events.ViewHidden + identifier);
},

notifyButtonClicked: function(identifier)
{
this._postNotification(WebInspector.extensionAPI.Events.ButtonClicked + identifier);
},

_inspectedURLChanged: function(event)
{
this._requests = {};
var url = event.data;
this._postNotification(WebInspector.extensionAPI.Events.InspectedURLChanged, url);
},

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, vararg)
{
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 ];
if (this._subscriptionStartHandlers[message.type])
this._subscriptionStartHandlers[message.type]();
}
},

_onUnsubscribe: function(message, port)
{
var subscribers = this._subscribers[message.type];
if (!subscribers)
return;
subscribers.remove(port);
if (!subscribers.length) {
delete this._subscribers[message.type];
if (this._subscriptionStopHandlers[message.type])
this._subscriptionStopHandlers[message.type]();
}
},

_onAddRequestHeaders: function(message)
{
var id = message.extensionId;
if (typeof id !== "string")
return this._status.E_BADARGTYPE("extensionId", typeof id, "string");
var extensionHeaders = this._extraHeaders[id];
if (!extensionHeaders) {
extensionHeaders = {};
this._extraHeaders[id] = extensionHeaders;
}
for (var name in message.headers)
extensionHeaders[name] = message.headers[name];
var allHeaders =   ({});
for (var extension in this._extraHeaders) {
var headers = this._extraHeaders[extension];
for (name in headers) {
if (typeof headers[name] === "string")
allHeaders[name] = headers[name];
}
}
NetworkAgent.setExtraHTTPHeaders(allHeaders);
},

_onCreatePanel: function(message, port)
{
var id = message.id;


if (id in this._clientObjects || id in WebInspector.panels)
return this._status.E_EXISTS(id);

var page = this._expandResourcePath(port._extensionOrigin, message.page);
var panelDescriptor = new WebInspector.PanelDescriptor(id, message.title, undefined, undefined, new WebInspector.ExtensionPanel(id, page));
panelDescriptor.setIconURL(this._expandResourcePath(port._extensionOrigin, message.icon));
this._clientObjects[id] = panelDescriptor.panel();
WebInspector.inspectorView.addPanel(panelDescriptor);
return this._status.OK();
},

_onShowPanel: function(message)
{

WebInspector.showPanel(message.id);
},

_onCreateStatusBarButton: function(message, port)
{
var panel = this._clientObjects[message.panel];
if (!panel || !(panel instanceof WebInspector.ExtensionPanel))
return this._status.E_NOTFOUND(message.panel);
var button = new WebInspector.ExtensionButton(message.id, this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
this._clientObjects[message.id] = button;
panel.addStatusBarItem(button.element);
return this._status.OK();
},

_onUpdateButton: function(message, port)
{
var button = this._clientObjects[message.id];
if (!button || !(button instanceof WebInspector.ExtensionButton))
return this._status.E_NOTFOUND(message.id);
button.update(this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
return this._status.OK();
},

_onCreateSidebarPane: function(message)
{
var panel = WebInspector.panel(message.panel);
if (!panel)
return this._status.E_NOTFOUND(message.panel);
if (!panel.addExtensionSidebarPane)
return this._status.E_NOTSUPPORTED();
var id = message.id;
var sidebar = new WebInspector.ExtensionSidebarPane(message.title, message.id);
this._clientObjects[id] = sidebar;
panel.addExtensionSidebarPane(id, sidebar);

return this._status.OK();
},

_onSetSidebarHeight: function(message)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
sidebar.setHeight(message.height);
return this._status.OK();
},

_onSetSidebarContent: function(message, port)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
function callback(error)
{
var result = error ? this._status.E_FAILED(error) : this._status.OK();
this._dispatchCallback(message.requestId, port, result);
}
if (message.evaluateOnPage)
return sidebar.setExpression(message.expression, message.rootTitle, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
sidebar.setObject(message.expression, message.rootTitle, callback.bind(this));
},

_onSetSidebarPage: function(message, port)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
sidebar.setPage(this._expandResourcePath(port._extensionOrigin, message.page));
},

_onSetOpenResourceHandler: function(message, port)
{
var name = this._registeredExtensions[port._extensionOrigin].name || ("Extension " + port._extensionOrigin);
if (message.handlerPresent)
WebInspector.openAnchorLocationRegistry.registerHandler(name, this._handleOpenURL.bind(this, port));
else
WebInspector.openAnchorLocationRegistry.unregisterHandler(name);
},

_handleOpenURL: function(port, details)
{
var url =   (details.url);
var contentProvider = WebInspector.workspace.uiSourceCodeForOriginURL(url) || WebInspector.resourceForURL(url);
if (!contentProvider)
return false;

var lineNumber = details.lineNumber;
if (typeof lineNumber === "number")
lineNumber += 1;
port.postMessage({
command: "open-resource",
resource: this._makeResource(contentProvider),
lineNumber: lineNumber
});
return true;
},

_onReload: function(message)
{
var options =   (message.options || {});
NetworkAgent.setUserAgentOverride(typeof options.userAgent === "string" ? options.userAgent : "");
var injectedScript;
if (options.injectedScript)
injectedScript = "(function(){" + options.injectedScript + "})()";
PageAgent.reload(!!options.ignoreCache, injectedScript);
return this._status.OK();
},

_onEvaluateOnInspectedPage: function(message, port)
{

function callback(error, resultPayload, wasThrown)
{
var result;
if (error)
result = this._status.E_PROTOCOLERROR(error.toString());
else if (wasThrown)
result = { isException: true, value: resultPayload.description };
else
result = { value: resultPayload.value };

this._dispatchCallback(message.requestId, port, result);
}
return this.evaluate(message.expression, true, true, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
},

_onGetConsoleMessages: function()
{
return WebInspector.console.messages.map(this._makeConsoleMessage);
},

_onAddConsoleMessage: function(message)
{
function convertSeverity(level)
{
switch (level) {
case WebInspector.extensionAPI.console.Severity.Log:
return WebInspector.ConsoleMessage.MessageLevel.Log;
case WebInspector.extensionAPI.console.Severity.Warning:
return WebInspector.ConsoleMessage.MessageLevel.Warning;
case WebInspector.extensionAPI.console.Severity.Error:
return WebInspector.ConsoleMessage.MessageLevel.Error;
case WebInspector.extensionAPI.console.Severity.Debug:
return WebInspector.ConsoleMessage.MessageLevel.Debug;
}
}
var level = convertSeverity(message.severity);
if (!level)
return this._status.E_BADARG("message.severity", message.severity);

var consoleMessage = WebInspector.ConsoleMessage.create(
WebInspector.ConsoleMessage.MessageSource.JS,
level,
message.text,
WebInspector.ConsoleMessage.MessageType.Log,
message.url,
message.line);
WebInspector.console.addMessage(consoleMessage);
},

_makeConsoleMessage: function(message)
{
function convertLevel(level)
{
if (!level)
return;
switch (level) {
case WebInspector.ConsoleMessage.MessageLevel.Log:
return WebInspector.extensionAPI.console.Severity.Log;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
return WebInspector.extensionAPI.console.Severity.Warning;
case WebInspector.ConsoleMessage.MessageLevel.Error:
return WebInspector.extensionAPI.console.Severity.Error;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
return WebInspector.extensionAPI.console.Severity.Debug;
default:
return WebInspector.extensionAPI.console.Severity.Log;
}
}
var result = {
severity: convertLevel(message.level),
text: message.text,
};
if (message.url)
result.url = message.url;
if (message.line)
result.line = message.line;
return result;
},

_onGetHAR: function()
{
var requests = WebInspector.networkLog.requests;
var harLog = (new WebInspector.HARLog(requests)).build();
for (var i = 0; i < harLog.entries.length; ++i)
harLog.entries[i]._requestId = this._requestId(requests[i]);
return harLog;
},


_makeResource: function(contentProvider)
{
return {
url: contentProvider.contentURL(),
type: contentProvider.contentType().name()
};
},

_onGetPageResources: function()
{
var resources = {};

function pushResourceData(contentProvider)
{
if (!resources[contentProvider.contentURL()])
resources[contentProvider.contentURL()] = this._makeResource(contentProvider);
}
var uiSourceCodes = WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.Network);
uiSourceCodes.forEach(pushResourceData.bind(this));
WebInspector.resourceTreeModel.forAllResources(pushResourceData.bind(this));
return Object.values(resources);
},


_getResourceContent: function(contentProvider, message, port)
{

function onContentAvailable(content, contentEncoded, mimeType)
{
var response = {
encoding: contentEncoded ? "base64" : "",
content: content
};
this._dispatchCallback(message.requestId, port, response);
}
contentProvider.requestContent(onContentAvailable.bind(this));
},

_onGetRequestContent: function(message, port)
{
var request = this._requestById(message.id);
if (!request)
return this._status.E_NOTFOUND(message.id);
this._getResourceContent(request, message, port);
},

_onGetResourceContent: function(message, port)
{
var url =   (message.url);
var contentProvider = WebInspector.workspace.uiSourceCodeForOriginURL(url) || WebInspector.resourceForURL(url);
if (!contentProvider)
return this._status.E_NOTFOUND(url);
this._getResourceContent(contentProvider, message, port);
},

_onSetResourceContent: function(message, port)
{

function callbackWrapper(error)
{
var response = error ? this._status.E_FAILED(error) : this._status.OK();
this._dispatchCallback(message.requestId, port, response);
}

var url =   (message.url);
var uiSourceCode = WebInspector.workspace.uiSourceCodeForOriginURL(url);
if (!uiSourceCode) {
var resource = WebInspector.resourceTreeModel.resourceForURL(url);
if (!resource)
return this._status.E_NOTFOUND(url);
return this._status.E_NOTSUPPORTED("Resource is not editable")
}
uiSourceCode.setWorkingCopy(message.content);
if (message.commit)
uiSourceCode.commitWorkingCopy(callbackWrapper.bind(this));
else
callbackWrapper.call(this, null);
},

_requestId: function(request)
{
if (!request._extensionRequestId) {
request._extensionRequestId = ++this._lastRequestId;
this._requests[request._extensionRequestId] = request;
}
return request._extensionRequestId;
},

_requestById: function(id)
{
return this._requests[id];
},

_onAddAuditCategory: function(message, port)
{
var category = new WebInspector.ExtensionAuditCategory(port._extensionOrigin, message.id, message.displayName, message.resultCount);
if (WebInspector.panel("audits").getCategory(category.id))
return this._status.E_EXISTS(category.id);
this._clientObjects[message.id] = category;
WebInspector.panel("audits").addCategory(category);
},

_onAddAuditResult: function(message)
{
var auditResult = this._clientObjects[message.resultId];
if (!auditResult)
return this._status.E_NOTFOUND(message.resultId);
try {
auditResult.addResult(message.displayName, message.description, message.severity, message.details);
} catch (e) {
return e;
}
return this._status.OK();
},

_onUpdateAuditProgress: function(message)
{
var auditResult = this._clientObjects[message.resultId];
if (!auditResult)
return this._status.E_NOTFOUND(message.resultId);
auditResult.updateProgress(Math.min(Math.max(0, message.progress), 1));
},

_onStopAuditCategoryRun: function(message)
{
var auditRun = this._clientObjects[message.resultId];
if (!auditRun)
return this._status.E_NOTFOUND(message.resultId);
auditRun.done();
},

_dispatchCallback: function(requestId, port, result)
{
if (requestId)
port.postMessage({ command: "callback", requestId: requestId, result: result });
},

initExtensions: function()
{
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ConsoleMessageAdded,
WebInspector.console, WebInspector.ConsoleModel.Events.MessageAdded, this._notifyConsoleMessageAdded);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.NetworkRequestFinished,
WebInspector.networkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._notifyRequestFinished);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceAdded,
WebInspector.workspace,
WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded,
this._notifyResourceAdded);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ElementsPanelObjectSelected,
WebInspector.notifications,
WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged,
this._notifyElementsSelectionChanged);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceContentCommitted,
WebInspector.workspace,
WebInspector.Workspace.Events.UISourceCodeContentCommitted,
this._notifyUISourceCodeContentCommitted);

function onTimelineSubscriptionStarted()
{
WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded,
this._notifyTimelineEventRecorded, this);
WebInspector.timelineManager.start();
}
function onTimelineSubscriptionStopped()
{
WebInspector.timelineManager.stop();
WebInspector.timelineManager.removeEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded,
this._notifyTimelineEventRecorded, this);
}
this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.TimelineEventRecorded,
onTimelineSubscriptionStarted.bind(this), onTimelineSubscriptionStopped.bind(this));

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged,
this._inspectedURLChanged, this);
this._initDone = true;
if (this._pendingExtensions) {
this._pendingExtensions.forEach(this._innerAddExtension, this);
delete this._pendingExtensions;
}
InspectorExtensionRegistry.getExtensionsAsync();
},

_notifyConsoleMessageAdded: function(event)
{
this._postNotification(WebInspector.extensionAPI.Events.ConsoleMessageAdded, this._makeConsoleMessage(event.data));
},

_notifyResourceAdded: function(event)
{
var uiSourceCode =   (event.data);
this._postNotification(WebInspector.extensionAPI.Events.ResourceAdded, this._makeResource(uiSourceCode));
},

_notifyUISourceCodeContentCommitted: function(event)
{
var uiSourceCode =   (event.data.uiSourceCode);
var content =   (event.data.content);
this._postNotification(WebInspector.extensionAPI.Events.ResourceContentCommitted, this._makeResource(uiSourceCode), content);
},

_notifyRequestFinished: function(event)
{
var request =   (event.data);
this._postNotification(WebInspector.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), (new WebInspector.HAREntry(request)).build());
},

_notifyElementsSelectionChanged: function()
{
this._postNotification(WebInspector.extensionAPI.Events.ElementsPanelObjectSelected);
},

_notifyTimelineEventRecorded: function(event)
{
this._postNotification(WebInspector.extensionAPI.Events.TimelineEventRecorded, event.data);
},


_addExtensions: function(extensions)
{
extensions.forEach(this._addExtension, this);
},


_addExtension: function(extensionInfo)
{
if (this._initDone) {
this._innerAddExtension(extensionInfo);
return;
}
if (this._pendingExtensions)
this._pendingExtensions.push(extensionInfo);
else
this._pendingExtensions = [extensionInfo];
},


_innerAddExtension: function(extensionInfo)
{
const urlOriginRegExp = new RegExp("([^:]+:\/\/[^/]*)\/"); 
var startPage = extensionInfo.startPage;
var name = extensionInfo.name;

try {
var originMatch = urlOriginRegExp.exec(startPage);
if (!originMatch) {
console.error("Skipping extension with invalid URL: " + startPage);
return false;
}
var extensionOrigin = originMatch[1];
if (!this._registeredExtensions[extensionOrigin]) {

InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, buildExtensionAPIInjectedScript(extensionInfo));
this._registeredExtensions[extensionOrigin] = { name: name };
}
var iframe = document.createElement("iframe");
iframe.src = startPage;
iframe.style.display = "none";
document.body.appendChild(iframe);
} catch (e) {
console.error("Failed to initialize extension " + startPage + ":" + e);
return false;
}
return true;
},

_onWindowMessage: function(event)
{
if (event.data === "registerExtension")
this._registerExtension(event.origin, event.ports[0]);
},

_registerExtension: function(origin, port)
{
if (!this._registeredExtensions.hasOwnProperty(origin)) {
if (origin !== window.location.origin) 
console.error("Ignoring unauthorized client request from " + origin);
return;
}
port._extensionOrigin = origin;
port.addEventListener("message", this._onmessage.bind(this), false);
port.start();
},

_onmessage: function(event)
{
var message = event.data;
var result;

if (message.command in this._handlers)
result = this._handlers[message.command](message, event.target);
else
result = this._status.E_NOTSUPPORTED(message.command);

if (result && message.requestId)
this._dispatchCallback(message.requestId, event.target, result);
},

_registerHandler: function(command, callback)
{
console.assert(command);
this._handlers[command] = callback;
},

_registerSubscriptionHandler: function(eventTopic, onSubscribeFirst, onUnsubscribeLast)
{
this._subscriptionStartHandlers[eventTopic] =  onSubscribeFirst;
this._subscriptionStopHandlers[eventTopic] =  onUnsubscribeLast;
},

_registerAutosubscriptionHandler: function(eventTopic, eventTarget, frontendEventType, handler)
{
this._registerSubscriptionHandler(eventTopic,
eventTarget.addEventListener.bind(eventTarget, frontendEventType, handler, this),
eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this));
},

_expandResourcePath: function(extensionPath, resourcePath)
{
if (!resourcePath)
return;
return extensionPath + this._normalizePath(resourcePath);
},

_normalizePath: function(path)
{
var source = path.split("/");
var result = [];

for (var i = 0; i < source.length; ++i) {
if (source[i] === ".")
continue;

if (source[i] === "")
continue;
if (source[i] === "..")
result.pop();
else
result.push(source[i]);
}
return "/" + result.join("/");
},


evaluate: function(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback) 
{
var contextId;
if (typeof options === "object") {

function resolveURLToFrame(url)
{
var found;
function hasMatchingURL(frame) 
{
found = (frame.url === url) ? frame : null;
return found;
}
WebInspector.resourceTreeModel.frames().some(hasMatchingURL);
return found;
}

var frame = options.frameURL ? resolveURLToFrame(options.frameURL) : WebInspector.resourceTreeModel.mainFrame;
if (!frame) {
if (options.frameURL)
console.warn("evaluate: there is no frame with URL " + options.frameURL);
else
console.warn("evaluate: the main frame is not yet available");
return this._status.E_NOTFOUND(options.frameURL || "<top>");
}

var contextSecurityOrigin;
if (options.useContentScriptContext)
contextSecurityOrigin = securityOrigin;
else if (options.scriptExecutionContext)
contextSecurityOrigin = options.scriptExecutionContext;

var frameContextList = WebInspector.runtimeModel.contextListByFrame(frame);
var context; 
if (contextSecurityOrigin) {
context = frameContextList.contextBySecurityOrigin(contextSecurityOrigin);
if (!context) {
console.warn("The JS context " + contextSecurityOrigin + " was not found in the frame " + frame.url)
return this._status.E_NOTFOUND(contextSecurityOrigin)
}
} else {
context = frameContextList.mainWorldContext();
if (!context) 
return this._status.E_FAILED(frame.url + " has no execution context");
}

contextId = context.id;
}
RuntimeAgent.evaluate(expression, "extension", exposeCommandLineAPI, true, contextId, returnByValue, false, callback);
}
}


WebInspector.ExtensionStatus = function()
{
function makeStatus(code, description)
{
var details = Array.prototype.slice.call(arguments, 2);
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;
}

this.OK = makeStatus.bind(null, "OK", "OK");
this.E_EXISTS = makeStatus.bind(null, "E_EXISTS", "Object already exists: %s");
this.E_BADARG = makeStatus.bind(null, "E_BADARG", "Invalid argument %s: %s");
this.E_BADARGTYPE = makeStatus.bind(null, "E_BADARGTYPE", "Invalid type for argument %s: got %s, expected %s");
this.E_NOTFOUND = makeStatus.bind(null, "E_NOTFOUND", "Object not found: %s");
this.E_NOTSUPPORTED = makeStatus.bind(null, "E_NOTSUPPORTED", "Object does not support requested operation: %s");
this.E_PROTOCOLERROR = makeStatus.bind(null, "E_PROTOCOLERROR", "Inspector protocol error: %s");
this.E_FAILED = makeStatus.bind(null, "E_FAILED", "Operation failed: %s");
}

WebInspector.addExtensions = function(extensions)
{
WebInspector.extensionServer._addExtensions(extensions);
}

WebInspector.extensionAPI = {};
defineCommonExtensionSymbols(WebInspector.extensionAPI);

WebInspector.extensionServer = new WebInspector.ExtensionServer();

window.addExtension = function(page, name)
{
WebInspector.extensionServer._addExtension({
startPage: page,
name: name,
});
}






WebInspector.ExtensionView = function(id, src, className)
{
WebInspector.View.call(this);
this.element.className = "fill";

this._id = id;
this._iframe = document.createElement("iframe");
this._iframe.addEventListener("load", this._onLoad.bind(this), false);
this._iframe.src = src;
this._iframe.className = className;
this.setDefaultFocusedElement(this._iframe);

this.element.appendChild(this._iframe);
}

WebInspector.ExtensionView.prototype = {
wasShown: function()
{
if (typeof this._frameIndex === "number")
WebInspector.extensionServer.notifyViewShown(this._id, this._frameIndex);
},

willHide: function()
{
if (typeof this._frameIndex === "number")
WebInspector.extensionServer.notifyViewHidden(this._id);
},

_onLoad: function()
{
var frames =   (window.frames);
this._frameIndex = Array.prototype.indexOf.call(frames, this._iframe.contentWindow);
if (this.isShowing())
WebInspector.extensionServer.notifyViewShown(this._id, this._frameIndex);
},

__proto__: WebInspector.View.prototype
}


WebInspector.ExtensionNotifierView = function(id)
{
WebInspector.View.call(this);

this._id = id;
}

WebInspector.ExtensionNotifierView.prototype = {
wasShown: function()
{
WebInspector.extensionServer.notifyViewShown(this._id);
},

willHide: function()
{
WebInspector.extensionServer.notifyViewHidden(this._id);
},

__proto__: WebInspector.View.prototype
}






WebInspector.ExtensionPanel = function(id, pageURL)
{
WebInspector.Panel.call(this, id);
this.setHideOnDetach();
this._statusBarItems = [];
var extensionView = new WebInspector.ExtensionView(id, pageURL, "extension panel");
extensionView.show(this.element);
this.setDefaultFocusedElement(extensionView.defaultFocusedElement());
}

WebInspector.ExtensionPanel.prototype = {
defaultFocusedElement: function()
{
return WebInspector.View.prototype.defaultFocusedElement.call(this);
},

get statusBarItems()
{
return this._statusBarItems;
},


addStatusBarItem: function(element)
{
this._statusBarItems.push(element);
},

searchCanceled: function(startingNewSearch)
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.CancelSearch);
WebInspector.Panel.prototype.searchCanceled.apply(this, arguments);
},


performSearch: function(query)
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PerformSearch, query);
WebInspector.Panel.prototype.performSearch.apply(this, arguments);
},

jumpToNextSearchResult: function()
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.NextSearchResult);
WebInspector.Panel.prototype.jumpToNextSearchResult.call(this);
},

jumpToPreviousSearchResult: function()
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PreviousSearchResult);
WebInspector.Panel.prototype.jumpToPreviousSearchResult.call(this);
},

__proto__: WebInspector.Panel.prototype
}


WebInspector.ExtensionButton = function(id, iconURL, tooltip, disabled)
{
this._id = id;
this.element = document.createElement("button");
this.element.className = "status-bar-item extension";
this.element.addEventListener("click", this._onClicked.bind(this), false);
this.update(iconURL, tooltip, disabled);
}

WebInspector.ExtensionButton.prototype = {

update: function(iconURL, tooltip, disabled)
{
if (typeof iconURL === "string")
this.element.style.backgroundImage = "url(" + iconURL + ")";
if (typeof tooltip === "string")
this.element.title = tooltip;
if (typeof disabled === "boolean")
this.element.disabled = disabled;
},

_onClicked: function()
{
WebInspector.extensionServer.notifyButtonClicked(this._id);
}
}


WebInspector.ExtensionSidebarPane = function(title, id)
{
WebInspector.SidebarPane.call(this, title);
this.setHideOnDetach();
this._id = id;
}

WebInspector.ExtensionSidebarPane.prototype = {

setObject: function(object, title, callback)
{
this._createObjectPropertiesView();
this._setObject(WebInspector.RemoteObject.fromLocalObject(object), title, callback);
},


setExpression: function(expression, title, evaluateOptions, securityOrigin, callback)
{
this._createObjectPropertiesView();
return WebInspector.extensionServer.evaluate(expression, true, false, evaluateOptions, securityOrigin, this._onEvaluate.bind(this, title, callback));
},


setPage: function(url)
{
if (this._objectPropertiesView) {
this._objectPropertiesView.detach();
delete this._objectPropertiesView;
}
if (this._extensionView)
this._extensionView.detach(true);

this._extensionView = new WebInspector.ExtensionView(this._id, url, "extension fill");
this._extensionView.show(this.bodyElement);

if (!this.bodyElement.style.height)
this.setHeight("150px");
},


setHeight: function(height)
{
this.bodyElement.style.height = height;
},


_onEvaluate: function(title, callback, error, result, wasThrown)
{
if (error)
callback(error.toString());
else
this._setObject(WebInspector.RemoteObject.fromPayload(result), title, callback);
},

_createObjectPropertiesView: function()
{
if (this._objectPropertiesView)
return;
if (this._extensionView) {
this._extensionView.detach(true);
delete this._extensionView;
}
this._objectPropertiesView = new WebInspector.ExtensionNotifierView(this._id);
this._objectPropertiesView.show(this.bodyElement);
},


_setObject: function(object, title, callback)
{

if (!this._objectPropertiesView) {
callback("operation cancelled");
return;
}
this._objectPropertiesView.element.removeChildren();
var section = new WebInspector.ObjectPropertiesSection(object, title);
if (!title)
section.headerElement.addStyleClass("hidden");
section.expanded = true;
section.editable = false;
this._objectPropertiesView.element.appendChild(section.element);
callback();
},

__proto__: WebInspector.SidebarPane.prototype
}






WebInspector.EmptyView = function(text)
{
WebInspector.View.call(this);
this._text = text;
}

WebInspector.EmptyView.prototype = {
wasShown: function()
{
this.element.className = "storage-empty-view";
this.element.textContent = this._text;
},

set text(text)
{
this._text = text;
if (this.isShowing())
this.element.textContent = this._text;
},

__proto__: WebInspector.View.prototype
}







WebInspector.Formatter = function()
{
}


WebInspector.Formatter.createFormatter = function(contentType)
{
if (contentType === WebInspector.resourceTypes.Script || contentType === WebInspector.resourceTypes.Document)
return new WebInspector.ScriptFormatter();
return new WebInspector.IdentityFormatter();
}


WebInspector.Formatter.locationToPosition = function(lineEndings, lineNumber, columnNumber)
{
var position = lineNumber ? lineEndings[lineNumber - 1] + 1 : 0;
return position + columnNumber;
}


WebInspector.Formatter.positionToLocation = function(lineEndings, position)
{
var lineNumber = lineEndings.upperBound(position - 1);
if (!lineNumber)
var columnNumber = position;
else
var columnNumber = position - lineEndings[lineNumber - 1] - 1;
return [lineNumber, columnNumber];
}

WebInspector.Formatter.prototype = {

formatContent: function(mimeType, content, callback)
{
}
}


WebInspector.ScriptFormatter = function()
{
this._tasks = [];
}

WebInspector.ScriptFormatter.prototype = {

formatContent: function(mimeType, content, callback)
{
content = content.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '');
const method = "format";
var parameters = { mimeType: mimeType, content: content, indentString: WebInspector.settings.textEditorIndent.get() };
this._tasks.push({ data: parameters, callback: callback });
this._worker.postMessage({ method: method, params: parameters });
},

_didFormatContent: function(event)
{
var task = this._tasks.shift();
var originalContent = task.data.content;
var formattedContent = event.data.content;
var mapping = event.data["mapping"];
var sourceMapping = new WebInspector.FormatterSourceMappingImpl(originalContent.lineEndings(), formattedContent.lineEndings(), mapping);
task.callback(formattedContent, sourceMapping);
},


get _worker()
{
if (!this._cachedWorker) {
this._cachedWorker = new Worker("ScriptFormatterWorker.js");
this._cachedWorker.onmessage =   (this._didFormatContent.bind(this));
}
return this._cachedWorker;
}
}


WebInspector.IdentityFormatter = function()
{
this._tasks = [];
}

WebInspector.IdentityFormatter.prototype = {

formatContent: function(mimeType, content, callback)
{
callback(content, new WebInspector.IdentityFormatterSourceMapping());
}
}


WebInspector.FormatterMappingPayload = function()
{
this.original = [];
this.formatted = [];
}


WebInspector.FormatterSourceMapping = function()
{
}

WebInspector.FormatterSourceMapping.prototype = {

originalToFormatted: function(lineNumber, columnNumber) { },


formattedToOriginal: function(lineNumber, columnNumber) { }
}


WebInspector.IdentityFormatterSourceMapping = function()
{
}

WebInspector.IdentityFormatterSourceMapping.prototype = {

originalToFormatted: function(lineNumber, columnNumber)
{
return [lineNumber, columnNumber || 0]; 
},


formattedToOriginal: function(lineNumber, columnNumber)
{
return [lineNumber, columnNumber || 0];
}
}


WebInspector.FormatterSourceMappingImpl = function(originalLineEndings, formattedLineEndings, mapping)
{
this._originalLineEndings = originalLineEndings;
this._formattedLineEndings = formattedLineEndings;
this._mapping = mapping;
}

WebInspector.FormatterSourceMappingImpl.prototype = {

originalToFormatted: function(lineNumber, columnNumber)
{
var originalPosition = WebInspector.Formatter.locationToPosition(this._originalLineEndings, lineNumber, columnNumber || 0);
var formattedPosition = this._convertPosition(this._mapping.original, this._mapping.formatted, originalPosition || 0);
return WebInspector.Formatter.positionToLocation(this._formattedLineEndings, formattedPosition);
},


formattedToOriginal: function(lineNumber, columnNumber)
{
var formattedPosition = WebInspector.Formatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber || 0);
var originalPosition = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition);
return WebInspector.Formatter.positionToLocation(this._originalLineEndings, originalPosition || 0);
},


_convertPosition: function(positions1, positions2, position)
{
var index = positions1.upperBound(position) - 1;
var convertedPosition = positions2[index] + position - positions1[index];
if (index < positions2.length - 1 && convertedPosition > positions2[index + 1])
convertedPosition = positions2[index + 1];
return convertedPosition;
}
}






WebInspector.DOMSyntaxHighlighter = function(mimeType, stripExtraWhitespace)
{
this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
this._stripExtraWhitespace = stripExtraWhitespace;
}

WebInspector.DOMSyntaxHighlighter.prototype = {
createSpan: function(content, className)
{
var span = document.createElement("span");
span.className = "webkit-" + className;
if (this._stripExtraWhitespace && className !== "whitespace")
content = content.replace(/^[\n\r]*/, "").replace(/\s*$/, "");
span.appendChild(document.createTextNode(content));
return span;
},

syntaxHighlightNode: function(node)
{
this._tokenizer.condition = this._tokenizer.createInitialCondition();
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.createFromLocation = function(line, column)
{
return new WebInspector.TextRange(line, column, line, column);
}


WebInspector.TextRange.fromObject = function (serializedTextRange)
{
return new WebInspector.TextRange(serializedTextRange.startLine, serializedTextRange.startColumn, serializedTextRange.endLine, serializedTextRange.endColumn);
}

WebInspector.TextRange.prototype = {

isEmpty: function()
{
return this.startLine === this.endLine && this.startColumn === this.endColumn;
},


immediatelyPrecedes: function(range)
{
if (!range)
return false;
return this.endLine === range.startLine && this.endColumn === range.startColumn;
},


immediatelyFollows: function(range)
{
if (!range)
return false;
return range.immediatelyPrecedes(this);
},


get linesCount()
{
return this.endLine - this.startLine;
},

collapseToEnd: function()
{
return new WebInspector.TextRange(this.endLine, this.endColumn, this.endLine, this.endColumn);
},


normalize: function()
{
if (this.startLine > this.endLine || (this.startLine === this.endLine && this.startColumn > this.endColumn))
return new WebInspector.TextRange(this.endLine, this.endColumn, this.startLine, this.startColumn);
else
return this.clone();
},


clone: function()
{
return new WebInspector.TextRange(this.startLine, this.startColumn, this.endLine, this.endColumn);
},


serializeToObject: function()
{
var serializedTextRange = {};
serializedTextRange.startLine = this.startLine;
serializedTextRange.startColumn = this.startColumn;
serializedTextRange.endLine = this.endLine;
serializedTextRange.endColumn = this.endColumn;
return serializedTextRange;
},


compareTo: function(other)
{
if (this.startLine > other.startLine)
return 1;
if (this.startLine < other.startLine)
return -1;
if (this.startColumn > other.startColumn)
return 1;
if (this.startColumn < other.startColumn)
return -1;
return 0;
},


shift: function(lineOffset)
{
return new WebInspector.TextRange(this.startLine + lineOffset, this.startColumn, this.endLine + lineOffset, this.endColumn);
},

toString: function()
{
return JSON.stringify(this);
}
}


WebInspector.TextEditorCommand = function(newRange, originalText, originalSelection)
{
this.newRange = newRange;
this.originalText = originalText;
this.originalSelection = originalSelection;
}


WebInspector.TextEditorModel = function()
{
this._lines = [""];
this._attributes = [];

this._undoStack = [];
this._noPunctuationRegex = /[^ !%&()*+,-.:;<=>?\[\]\^{|}~]+/;
this._lineBreak = "\n";
}

WebInspector.TextEditorModel.Events = {
TextChanged: "TextChanged"
}

WebInspector.TextEditorModel.endsWithBracketRegex = /[{(\[]\s*$/;

WebInspector.TextEditorModel.prototype = {

isClean: function()
{
return this._cleanState === this._undoStack.length;
},

markClean: function()
{
this._cleanState = this._undoStack.length;
},


get linesCount()
{
return this._lines.length;
},


text: function()
{
return this._lines.join(this._lineBreak);
},


range: function()
{
return new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length);
},


get lineBreak()
{
return this._lineBreak;
},


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(text)
{
this._resetUndoStack();
text = text || "";
var range = this.range();
this._lineBreak = /\r\n/.test(text) ? "\r\n" : "\n";
var newRange = this._innerSetText(range, text);
this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange});
},


_rangeHasOneCharacter: function(range)
{
if (range.startLine === range.endLine && range.endColumn - range.startColumn === 1)
return true;
if (range.endLine - range.startLine === 1 && range.endColumn === 0 && range.startColumn === this.lineLength(range.startLine))
return true;
return false;
},


_isEditRangeUndoBoundary: function(range, text, originalSelection)
{
if (originalSelection && !originalSelection.isEmpty())
return true;
if (text)
return text.length > 1 || !range.isEmpty();
return !this._rangeHasOneCharacter(range);
},


_isEditRangeAdjacentToLastCommand: function(range, text)
{
if (!this._lastCommand)
return true;
if (!text) {

return this._lastCommand.newRange.immediatelyPrecedes(range) || this._lastCommand.newRange.immediatelyFollows(range);
}
return text.indexOf("\n") === -1 && this._lastCommand.newRange.immediatelyPrecedes(range);
},


editRange: function(range, text, originalSelection)
{
var undoBoundary = this._isEditRangeUndoBoundary(range, text, originalSelection);
if (undoBoundary || !this._isEditRangeAdjacentToLastCommand(range, text))
this._markUndoableState();
var newRange = this._innerEditRange(range, text, originalSelection);
if (undoBoundary)
this._markUndoableState();
return newRange;
},


_innerEditRange: function(range, text, originalSelection)
{
var originalText = this.copyRange(range);
var newRange = this._innerSetText(range, text);
this._lastCommand = this._pushUndoableCommand(newRange, originalText, originalSelection || range);
this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange, editRange: true });
return newRange;
},


_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(/\r?\n/);

var prefix = this._lines[range.startLine].substring(0, range.startColumn);
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]);
this._insertLines(range, newLines);
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);
},


_insertLines: function(range, newLines)
{
var lines = new Array(this._lines.length + newLines.length - 1);
for (var i = 0; i <= range.startLine; ++i)
lines[i] = this._lines[i];

for (var i = 1; i < newLines.length; ++i)
lines[range.startLine + i] = newLines[i];
for (var i = range.startLine + newLines.length; i < lines.length; ++i)
lines[i] = this._lines[i - newLines.length + 1];
this._lines = lines;


var attributes = new Array(lines.length);
var insertionIndex = range.startColumn ? range.startLine + 1 : range.startLine;
for (var i = 0; i < insertionIndex; ++i)
attributes[i] = this._attributes[i];
for (var i = insertionIndex + newLines.length - 1; i < attributes.length; ++i)
attributes[i] = this._attributes[i - newLines.length + 1];
this._attributes = attributes;
},


_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._lines.splice(range.startLine + 1, range.endLine - range.startLine);

this._attributes.splice(range.startColumn ? range.startLine + 1 : range.startLine, range.endLine - range.startLine);
}
this._setLine(range.startLine, prefix + suffix);
},


_setLine: function(lineNumber, text)
{
this._lines[lineNumber] = text;
},


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 = this.range();

var clip = [];
if (range.startLine === range.endLine) {
clip.push(this._lines[range.startLine].substring(range.startColumn, range.endColumn));
return clip.join(this._lineBreak);
}
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(this._lineBreak);
},


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(newRange, originalText, originalSelection)
{
var command = new WebInspector.TextEditorCommand(newRange.clone(), originalText, originalSelection);
if (this._inUndo)
this._redoStack.push(command);
else {
if (!this._inRedo) {
this._redoStack = [];
if (typeof this._cleanState === "number" && this._cleanState > this._undoStack.length)
delete this._cleanState;
}
this._undoStack.push(command);
}
return command;
},


undo: function()
{
if (!this._undoStack.length)
return null;

this._markRedoableState();

this._inUndo = true;
var range = this._doUndo(this._undoStack);
delete this._inUndo;

return range;
},


redo: function()
{
if (!this._redoStack || !this._redoStack.length)
return null;
this._markUndoableState();

this._inRedo = true;
var range = this._doUndo(this._redoStack);
delete this._inRedo;

return range ? range.collapseToEnd() : null;
},


_doUndo: function(stack)
{
var range = null;
for (var i = stack.length - 1; i >= 0; --i) {
var command = stack[i];
stack.length = i;
this._innerEditRange(command.newRange, command.originalText);
range = command.originalSelection;
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()
{
delete this._cleanState;
this._undoStack = [];
this._redoStack = [];
},


indentLines: function(range)
{
this._markUndoableState();

var indent = WebInspector.settings.textEditorIndent.get();
var newRange = range.clone();

if (range.startColumn)
newRange.startColumn += indent.length;

var indentEndLine = range.endLine;
if (range.endColumn)
newRange.endColumn += indent.length;
else
indentEndLine--;

for (var lineNumber = range.startLine; lineNumber <= indentEndLine; lineNumber++)
this._innerEditRange(WebInspector.TextRange.createFromLocation(lineNumber, 0), indent);

return newRange;
},


unindentLines: function(range)
{
this._markUndoableState();

var indent = WebInspector.settings.textEditorIndent.get();
var indentLength = indent === WebInspector.TextUtils.Indent.TabCharacter ? 4 : indent.length;
var lineIndentRegex = new RegExp("^ {1," + indentLength + "}");
var newRange = range.clone();

var indentEndLine = range.endLine;
if (!range.endColumn)
indentEndLine--;

for (var lineNumber = range.startLine; lineNumber <= indentEndLine; lineNumber++) {
var line = this.line(lineNumber);
var firstCharacter = line.charAt(0);
var lineIndentLength;

if (firstCharacter === " ")
lineIndentLength = line.match(lineIndentRegex)[0].length;
else if (firstCharacter === "\t")
lineIndentLength = 1;
else
continue;

this._innerEditRange(new WebInspector.TextRange(lineNumber, 0, lineNumber, lineIndentLength), "");

if (lineNumber === range.startLine)
newRange.startColumn = Math.max(0, newRange.startColumn - lineIndentLength);
if (lineNumber === range.endLine)
newRange.endColumn = Math.max(0, newRange.endColumn - lineIndentLength);
}

return newRange;
},


slice: function(from, to)
{
var textModel = new WebInspector.TextEditorModel();
textModel._lines = this._lines.slice(from, to);
textModel._lineBreak = this._lineBreak;
return textModel;
},


growRangeLeft: function(range)
{
var result = range.clone();
if (result.startColumn)
--result.startColumn;
else if (result.startLine)
result.startColumn = this.lineLength(--result.startLine);
return result;
},


growRangeRight: function(range)
{
var result = range.clone();
if (result.endColumn < this.lineLength(result.endLine))
++result.endColumn;
else if (result.endLine < this.linesCount) {
result.endColumn = 0;
++result.endLine;
}
return result;
},

__proto__: WebInspector.Object.prototype
}


WebInspector.TextEditorModel.BraceMatcher = function(textModel)
{
this._textModel = textModel;
}

WebInspector.TextEditorModel.BraceMatcher.prototype = {

_braceRanges: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount || lineNumber < 0)
return null;

var attribute = this._textModel.getAttribute(lineNumber, "highlight");
if (!attribute)
return null;
else
return attribute.braces;
},


_matches: function(braceTokenLeft, braceTokenRight)
{
return ((braceTokenLeft === "brace-start" && braceTokenRight === "brace-end") || (braceTokenLeft === "block-start" && braceTokenRight === "block-end"));
},


findLeftCandidate: function(lineNumber, column, maxBraceIteration)
{
var braces = this._braceRanges(lineNumber);
if (!braces)
return null;

var braceIndex = braces.length - 1;
while (braceIndex >= 0 && braces[braceIndex].startColumn > column)
--braceIndex;

var brace = braceIndex >= 0 ? braces[braceIndex] : null;
if (brace && brace.startColumn === column && (brace.token === "block-end" || brace.token === "brace-end"))
--braceIndex;

var stack = [];
maxBraceIteration = maxBraceIteration || Number.MAX_VALUE;
while (--maxBraceIteration) {
if (braceIndex < 0) {
while ((braces = this._braceRanges(--lineNumber)) && !braces.length) {};
if (!braces)
return null;
braceIndex = braces.length - 1;
}
brace = braces[braceIndex];
if (brace.token === "block-end" || brace.token === "brace-end")
stack.push(brace.token);
else if (stack.length === 0)
return {
lineNumber: lineNumber,
column: brace.startColumn,
token: brace.token
};
else if (!this._matches(brace.token, stack.pop()))
return null;

--braceIndex;
}
return null;
},


findRightCandidate: function(lineNumber, column, maxBraceIteration)
{
var braces = this._braceRanges(lineNumber);
if (!braces)
return null;

var braceIndex = 0;
while (braceIndex < braces.length && braces[braceIndex].startColumn < column)
++braceIndex;

var brace = braceIndex < braces.length ? braces[braceIndex] : null;
if (brace && brace.startColumn === column && (brace.token === "block-start" || brace.token === "brace-start"))
++braceIndex;

var stack = [];
maxBraceIteration = maxBraceIteration || Number.MAX_VALUE;
while (--maxBraceIteration) {
if (braceIndex >= braces.length) {
while ((braces = this._braceRanges(++lineNumber)) && !braces.length) {};
if (!braces)
return null;
braceIndex = 0;
}
brace = braces[braceIndex];
if (brace.token === "block-start" || brace.token === "brace-start")
stack.push(brace.token);
else if (stack.length === 0)
return {
lineNumber: lineNumber,
column: brace.startColumn,
token: brace.token
};
else if (!this._matches(stack.pop(), brace.token))
return null;
++braceIndex;
}
return null;
},


enclosingBraces: function(lineNumber, column, maxBraceIteration)
{
var leftBraceLocation = this.findLeftCandidate(lineNumber, column, maxBraceIteration);
if (!leftBraceLocation)
return null;

var rightBraceLocation = this.findRightCandidate(lineNumber, column, maxBraceIteration);
if (!rightBraceLocation)
return null;

if (!this._matches(leftBraceLocation.token, rightBraceLocation.token))
return null;

return {
leftBrace: leftBraceLocation,
rightBrace: rightBraceLocation
};
},
}






WebInspector.TextEditorHighlighter = function(textModel, damageCallback)
{
this._textModel = textModel;
this._mimeType = "text/html";
this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(this._mimeType);
this._damageCallback = damageCallback;
this._highlightChunkLimit = 1000;
this._highlightLineLimit = 500;
}

WebInspector.TextEditorHighlighter._MaxLineCount = 10000;

WebInspector.TextEditorHighlighter.prototype = {

get mimeType()
{
return this._mimeType;
},


set mimeType(mimeType)
{
var tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
if (tokenizer) {
this._tokenizer = tokenizer;
this._mimeType = mimeType;
}
},

set highlightChunkLimit(highlightChunkLimit)
{
this._highlightChunkLimit = highlightChunkLimit;
},


setHighlightLineLimit: function(highlightLineLimit)
{
this._highlightLineLimit = highlightLineLimit;
},


highlight: function(endLine, forceRun)
{
if (this._textModel.linesCount > WebInspector.TextEditorHighlighter._MaxLineCount)
return;


var state = this._textModel.getAttribute(endLine - 1, "highlight");
if (state && state.postConditionStringified) {

return;
}

this._requestedEndLine = endLine;

if (this._highlightTimer && !forceRun) {

return;
}


var startLine = endLine;
while (startLine > 0) {
state = this._textModel.getAttribute(startLine - 1, "highlight");
if (state && state.postConditionStringified)
break;
startLine--;
}


this._highlightInChunks(startLine, endLine);
},

updateHighlight: function(startLine, endLine)
{
if (this._textModel.linesCount > WebInspector.TextEditorHighlighter._MaxLineCount)
return;


this._clearHighlightState(startLine);

if (startLine) {
var state = this._textModel.getAttribute(startLine - 1, "highlight");
if (!state || !state.postConditionStringified) {

return false;
}
}

var restored = this._highlightLines(startLine, endLine);
if (!restored) {
for (var i = this._lastHighlightedLine; i < this._textModel.linesCount; ++i) {
var state = this._textModel.getAttribute(i, "highlight");
if (!state && i > endLine)
break;
this._textModel.setAttribute(i, "highlight-outdated", state);
this._textModel.removeAttribute(i, "highlight");
}

if (this._highlightTimer) {
clearTimeout(this._highlightTimer);
this._requestedEndLine = endLine;
this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10);
}
}
return restored;
},

_highlightInChunks: function(startLine, endLine)
{
delete this._highlightTimer;


var state = this._textModel.getAttribute(this._requestedEndLine - 1, "highlight");
if (state && state.postConditionStringified)
return;

if (this._requestedEndLine !== endLine) {

this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, startLine, this._requestedEndLine), 100);
return;
}


if (this._requestedEndLine > this._textModel.linesCount)
this._requestedEndLine = this._textModel.linesCount;

this._highlightLines(startLine, this._requestedEndLine);


if (this._lastHighlightedLine < this._requestedEndLine)
this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10);
},

_highlightLines: function(startLine, endLine)
{

var state = this._textModel.getAttribute(startLine - 1, "highlight");
var postConditionStringified = state ? state.postConditionStringified : JSON.stringify(this._tokenizer.createInitialCondition());

var tokensCount = 0;
for (var lineNumber = startLine; lineNumber < endLine; ++lineNumber) {
state = this._selectHighlightState(lineNumber, postConditionStringified);
if (state.postConditionStringified) {

postConditionStringified = state.postConditionStringified;
} else {
var lastHighlightedColumn = 0;
if (state.midConditionStringified) {
lastHighlightedColumn = state.lastHighlightedColumn;
postConditionStringified = state.midConditionStringified;
}

var line = this._textModel.line(lineNumber);
this._tokenizer.line = line;
this._tokenizer.condition = JSON.parse(postConditionStringified);


state.ranges = state.ranges || [];
state.braces = state.braces || [];
do {
var newColumn = this._tokenizer.nextToken(lastHighlightedColumn);
var tokenType = this._tokenizer.tokenType;
if (tokenType && lastHighlightedColumn < this._highlightLineLimit) {
if (tokenType === "brace-start" || tokenType === "brace-end" || tokenType === "block-start" || tokenType === "block-end") {
state.braces.push({
startColumn: lastHighlightedColumn,
endColumn: newColumn - 1,
token: tokenType
});
} else {
state.ranges.push({
startColumn: lastHighlightedColumn,
endColumn: newColumn - 1,
token: tokenType
});
}
}
lastHighlightedColumn = newColumn;
if (++tokensCount > this._highlightChunkLimit)
break;
} while (lastHighlightedColumn < line.length);

postConditionStringified = JSON.stringify(this._tokenizer.condition);

if (lastHighlightedColumn < line.length) {

state.lastHighlightedColumn = lastHighlightedColumn;
state.midConditionStringified = postConditionStringified;
break;
} else {
delete state.lastHighlightedColumn;
delete state.midConditionStringified;
state.postConditionStringified = postConditionStringified;
}
}

var nextLineState = this._textModel.getAttribute(lineNumber + 1, "highlight");
if (nextLineState && nextLineState.preConditionStringified === state.postConditionStringified) {

++lineNumber;
this._damageCallback(startLine, lineNumber);


for (; lineNumber < endLine; ++lineNumber) {
state = this._textModel.getAttribute(lineNumber, "highlight");
if (!state || !state.postConditionStringified)
break;
}
this._lastHighlightedLine = lineNumber;
return true;
}
}

this._damageCallback(startLine, lineNumber);
this._lastHighlightedLine = lineNumber;
return false;
},

_selectHighlightState: function(lineNumber, preConditionStringified)
{
var state = this._textModel.getAttribute(lineNumber, "highlight");
if (state && state.preConditionStringified === preConditionStringified)
return state;

var outdatedState = this._textModel.getAttribute(lineNumber, "highlight-outdated");
if (outdatedState && outdatedState.preConditionStringified === preConditionStringified) {

this._textModel.setAttribute(lineNumber, "highlight", outdatedState);
this._textModel.setAttribute(lineNumber, "highlight-outdated", state);
return outdatedState;
}

if (state)
this._textModel.setAttribute(lineNumber, "highlight-outdated", state);

state = {};
state.preConditionStringified = preConditionStringified;
this._textModel.setAttribute(lineNumber, "highlight", state);
return state;
},

_clearHighlightState: function(lineNumber)
{
this._textModel.removeAttribute(lineNumber, "highlight");
this._textModel.removeAttribute(lineNumber, "highlight-outdated");
}
}





WebInspector.TextUtils = {

isStopChar: function(char)
{
return (char > " " && char < "0") ||
(char > "9" && char < "A") ||
(char > "Z" && char < "_") ||
(char > "_" && char < "a") ||
(char > "z" && char <= "~");
},


isWordChar: function(char)
{
return !WebInspector.TextUtils.isStopChar(char) && !WebInspector.TextUtils.isSpaceChar(char);
},


isSpaceChar: function(char)
{
return WebInspector.TextUtils._SpaceCharRegex.test(char);
},


isWord: function(word)
{
for (var i = 0; i < word.length; ++i) {
if (!WebInspector.TextUtils.isWordChar(word.charAt(i)))
return false;
}
return true;
},


isOpeningBraceChar: function(char)
{
return char === "(" || char === "{";
},


isClosingBraceChar: function(char)
{
return char === ")" || char === "}";
},


isBraceChar: function(char)
{
return WebInspector.TextUtils.isOpeningBraceChar(char) || WebInspector.TextUtils.isClosingBraceChar(char);
}
}

WebInspector.TextUtils._SpaceCharRegex = /\s/;


WebInspector.TextUtils.Indent = {
TwoSpaces: "  ",
FourSpaces: "    ",
EightSpaces: "        ",
TabCharacter: "\t"
}







WebInspector.SourceTokenizer = function()
{

this.tokenType = null;
}

WebInspector.SourceTokenizer.prototype = {
set line(line) {
this._line = line;
},

set condition(condition)
{
this._condition = condition;
},

get condition()
{
return this._condition;
},

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";
},

createInitialCondition: function()
{
},


nextToken: function(cursor)
{
}
}


WebInspector.SourceTokenizer.Registry = function() {
this._tokenizers = {};
this._tokenizerConstructors = {
"text/css": "SourceCSSTokenizer",
"text/html": "SourceHTMLTokenizer",
"text/javascript": "SourceJavaScriptTokenizer",
"text/x-scss": "SourceCSSTokenizer"
};
}


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[tokenizerClass] = tokenizer;
}
return tokenizer;
}
}











WebInspector.SourceCSSTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);

this._propertyKeywords = WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet();
this._colorKeywords = WebInspector.CSSMetadata.colors();

this._valueKeywords = [
"above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll",
"alternate", "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", "arabic-indic", "armenian", "asterisks",
"auto", "avoid", "background", "backwards", "baseline", "below", "bidi-override", "binary", "bengali", "blink",
"block", "block-axis", "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", "footnotes", "forwards", "from", "geometricPrecision",
"georgian", "graytext", "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", "line-through", "linear", "lines",
"list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "lower-greek",
"lower-hexadecimal", "lower-latin", "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "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", "open-quote", "optimizeLegibility",
"optimizeSpeed", "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",
"push-button", "radio", "read-only", "read-write", "read-write-plaintext-only", "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", "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", "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-armenian",
"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-pictograph",
"-webkit-right", "-webkit-small-control", "-webkit-text", "-webkit-xxx-large", "-webkit-zoom-in", "-webkit-zoom-out",
].keySet();

this._scssValueKeywords = [
"abs", "adjust-color", "adjust-hue", "alpha", "append", "ceil", "change-color", "comparable", "complement", "darken", "desaturate",
"fade-in", "fade-out", "floor", "grayscale", "hue", "ie-hex-str", "invert", "join", "length", "lighten",
"lightness", "max", "min", "mix", "nth", "opacify", "opacity", "percentage", "quote", "round", "saturate",
"saturation", "scale-color", "transparentize", "type-of", "unit", "unitless", "unquote", "zip"
].keySet();

this._lexConditions = {
INITIAL: 0,
COMMENT: 1,
DSTRING: 2,
SSTRING: 3
};

this._parseConditions = {
INITIAL: 0,
PROPERTY: 1,
PROPERTY_VALUE: 2,
AT_RULE: 3,
AT_MEDIA_RULE: 4
};

this.case_INITIAL = 1000;
this.case_COMMENT = 1002;
this.case_DSTRING = 1003;
this.case_SSTRING = 1004;

this.condition = this.createInitialCondition();
}

WebInspector.SourceCSSTokenizer.SCSSAtRelatedKeywords = ["from", "if", "in", "through"].keySet();

WebInspector.SourceCSSTokenizer.MediaTypes = ["all", "aural", "braille", "embossed", "handheld", "import", "print", "projection", "screen", "tty", "tv"].keySet();

WebInspector.SourceCSSTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
},


_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;
},

_setParseCondition: function(condition)
{
this._condition.parseCondition = condition;
},

nextToken: function(cursor)
{
var cursorOnEnter = cursor;
var gotoCase = 1;
var YYMARKER;
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 = 34; continue; };
if (yych <= '$') { gotoCase = 35; continue; };
if (yych >= '&') { gotoCase = 31; continue; };
}
} else {
if (yych <= '-') {
if (yych <= '\'') { gotoCase = 36; continue; };
if (yych >= '-') { gotoCase = 37; continue; };
} else {
if (yych <= '.') { gotoCase = 38; continue; };
if (yych <= '/') { gotoCase = 39; continue; };
if (yych <= '9') { gotoCase = 40; continue; };
{ gotoCase = 42; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '=') {
if (yych <= ';') { gotoCase = 44; continue; };
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; };
if (yych >= 'a') { gotoCase = 31; continue; };
} else {
if (yych <= '{') { gotoCase = 46; continue; };
if (yych == '}') { gotoCase = 48; continue; };
}
}
}
case 29:
++cursor;
case 30:
{ this.tokenType = null; return cursor; }
case 31:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 51; continue; };
case 32:
{
var token = this._line.substring(cursorOnEnter, cursor);
this.tokenType = null;
if (this._condition.parseCondition === this._parseConditions.INITIAL || this._condition.parseCondition === this._parseConditions.PROPERTY) {
if (token.charAt(0) === "@") {
this.tokenType = "css-at-rule";
this._setParseCondition(token === "@media" ? this._parseConditions.AT_MEDIA_RULE : this._parseConditions.AT_RULE);
this._condition.atKeyword = token;
} else if (this._condition.parseCondition === this._parseConditions.INITIAL)
this.tokenType = "css-selector";
else if (this._propertyKeywords.hasOwnProperty(token))
this.tokenType = "css-property";
} else if (this._condition.parseCondition === this._parseConditions.AT_MEDIA_RULE || this._condition.parseCondition === this._parseConditions.AT_RULE) {
if (WebInspector.SourceCSSTokenizer.SCSSAtRelatedKeywords.hasOwnProperty(token))
this.tokenType = "css-at-rule";
else if (WebInspector.SourceCSSTokenizer.MediaTypes.hasOwnProperty(token))
this.tokenType = "css-keyword";
}
if (this.tokenType)
return cursor;

if (this._isPropertyValue()) {
var firstChar = token.charAt(0);
if (firstChar === "$")
this.tokenType = "scss-variable";
else if (firstChar === "!")
this.tokenType = "css-bang-keyword";
else if (this._condition.atKeyword === "@extend")
this.tokenType = "css-selector";
else if (this._valueKeywords.hasOwnProperty(token) || this._scssValueKeywords.hasOwnProperty(token))
this.tokenType = "css-keyword";
else if (this._colorKeywords.hasOwnProperty(token)) {

this.tokenType = "css-color";
}
} else if (this._condition.parseCondition !== this._parseConditions.PROPERTY_VALUE)
this.tokenType = "css-selector";
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 = 132; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 116; continue; };
if (yych <= '%') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
} else {
if (yych == '-') { gotoCase = 130; continue; };
{ gotoCase = 132; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 130; continue; };
if (yych <= '<') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
} else {
if (yych <= '?') { gotoCase = 132; continue; };
if (yych <= '[') { gotoCase = 130; continue; };
{ gotoCase = 134; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
} else {
if (yych <= '`') { gotoCase = 132; continue; };
if (yych <= 'z') { gotoCase = 130; continue; };
{ gotoCase = 132; continue; };
}
}
}
case 34:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 30; continue; };
if (yych <= '9') { gotoCase = 127; continue; };
{ gotoCase = 30; continue; };
} else {
if (yych <= 'Z') { gotoCase = 127; continue; };
if (yych <= '`') { gotoCase = 30; continue; };
if (yych <= 'z') { gotoCase = 127; continue; };
{ gotoCase = 30; continue; };
}
case 35:
yych = this._charAt(++cursor);
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 30; continue; };
if (yych <= '"') { gotoCase = 124; continue; };
if (yych <= '%') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '-') {
if (yych <= ',') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '.') { gotoCase = 30; continue; };
if (yych <= '9') { gotoCase = 124; continue; };
{ gotoCase = 30; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 124; continue; };
{ gotoCase = 30; continue; };
} else {
if (yych == '\\') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '^') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '`') { gotoCase = 30; continue; };
if (yych <= 'z') { gotoCase = 124; continue; };
{ gotoCase = 30; continue; };
}
}
}
case 36:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '.') {
if (yych <= '"') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '%') { gotoCase = 118; continue; };
if (yych <= '&') { gotoCase = 114; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych == '-') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 114; continue; };
if (yych <= '<') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '?') { gotoCase = 118; continue; };
if (yych <= '[') { gotoCase = 114; continue; };
{ gotoCase = 120; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '`') { gotoCase = 118; continue; };
if (yych <= 'z') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
}
case 37:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '.') { gotoCase = 67; continue; };
if (yych <= '/') { gotoCase = 51; continue; };
if (yych <= '9') { gotoCase = 52; continue; };
{ gotoCase = 51; continue; };
case 38:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 30; continue; };
if (yych <= '9') { gotoCase = 70; continue; };
{ gotoCase = 30; continue; };
case 39:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '*') { gotoCase = 106; continue; };
{ gotoCase = 51; continue; };
case 40:
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 = 50; continue; };
case '%':    { gotoCase = 69; continue; };
case '.':    { gotoCase = 67; continue; };
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':    { gotoCase = 52; continue; };
case 'H':    { gotoCase = 54; continue; };
case '_':    { gotoCase = 55; continue; };
case 'c':    { gotoCase = 56; continue; };
case 'd':    { gotoCase = 57; continue; };
case 'e':    { gotoCase = 58; continue; };
case 'g':    { gotoCase = 59; continue; };
case 'i':    { gotoCase = 60; continue; };
case 'k':    { gotoCase = 61; continue; };
case 'm':    { gotoCase = 62; continue; };
case 'p':    { gotoCase = 63; continue; };
case 'r':    { gotoCase = 64; continue; };
case 's':    { gotoCase = 65; continue; };
case 't':    { gotoCase = 66; continue; };
default:    { gotoCase = 41; continue; };
}
case 41:
{
if (this._isPropertyValue())
this.tokenType = "css-number";
else
this.tokenType = null;
return cursor;
}
case 42:
++cursor;
{
this.tokenType = null;
if (this._condition.parseCondition === this._parseConditions.PROPERTY || this._condition.parseCondition === this._parseConditions.INITIAL)
this._setParseCondition(this._parseConditions.PROPERTY_VALUE);
return cursor;
}
case 44:
++cursor;
{
this.tokenType = null;
this._setParseCondition(this._condition.openBraces ? this._parseConditions.PROPERTY : this._parseConditions.INITIAL);
delete this._condition.atKeyword;
return cursor;
}
case 46:
++cursor;
{
this.tokenType = "block-start";
this._condition.openBraces = (this._condition.openBraces || 0) + 1;
if (this._condition.parseCondition === this._parseConditions.AT_MEDIA_RULE)
this._setParseCondition(this._parseConditions.INITIAL);
else
this._setParseCondition(this._parseConditions.PROPERTY);
return cursor;
}
case 48:
++cursor;
{
this.tokenType = "block-end";
if (this._condition.openBraces > 0)
--this._condition.openBraces;
this._setParseCondition(this._condition.openBraces ? this._parseConditions.PROPERTY : this._parseConditions.INITIAL);
delete this._condition.atKeyword;
return cursor;
}
case 50:
++cursor;
yych = this._charAt(cursor);
case 51:
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 32; continue; };
if (yych <= '"') { gotoCase = 50; continue; };
if (yych <= '%') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '-') {
if (yych <= ',') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '.') { gotoCase = 32; continue; };
if (yych <= '9') { gotoCase = 50; continue; };
{ gotoCase = 32; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 50; continue; };
{ gotoCase = 32; continue; };
} else {
if (yych == '\\') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '^') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '`') { gotoCase = 32; continue; };
if (yych <= 'z') { gotoCase = 50; continue; };
{ gotoCase = 32; continue; };
}
}
}
case 52:
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 = 50; continue; };
case '%':    { gotoCase = 69; continue; };
case '.':    { gotoCase = 67; continue; };
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':    { gotoCase = 52; continue; };
case 'H':    { gotoCase = 54; continue; };
case '_':    { gotoCase = 55; continue; };
case 'c':    { gotoCase = 56; continue; };
case 'd':    { gotoCase = 57; continue; };
case 'e':    { gotoCase = 58; continue; };
case 'g':    { gotoCase = 59; continue; };
case 'i':    { gotoCase = 60; continue; };
case 'k':    { gotoCase = 61; continue; };
case 'm':    { gotoCase = 62; continue; };
case 'p':    { gotoCase = 63; continue; };
case 'r':    { gotoCase = 64; continue; };
case 's':    { gotoCase = 65; continue; };
case 't':    { gotoCase = 66; continue; };
default:    { gotoCase = 41; continue; };
}
case 54:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 55:
yych = this._charAt(++cursor);
if (yych == '_') { gotoCase = 103; continue; };
{ gotoCase = 51; continue; };
case 56:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 57:
yych = this._charAt(++cursor);
if (yych == 'e') { gotoCase = 102; continue; };
{ gotoCase = 51; continue; };
case 58:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
if (yych == 'x') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 59:
yych = this._charAt(++cursor);
if (yych == 'r') { gotoCase = 100; continue; };
{ gotoCase = 51; continue; };
case 60:
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 61:
yych = this._charAt(++cursor);
if (yych == 'H') { gotoCase = 99; continue; };
{ gotoCase = 51; continue; };
case 62:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
if (yych == 's') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 63:
yych = this._charAt(++cursor);
if (yych <= 's') {
if (yych == 'c') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
} else {
if (yych <= 't') { gotoCase = 65; continue; };
if (yych == 'x') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
}
case 64:
yych = this._charAt(++cursor);
if (yych == 'a') { gotoCase = 97; continue; };
if (yych == 'e') { gotoCase = 98; continue; };
{ gotoCase = 51; continue; };
case 65:
yych = this._charAt(++cursor);
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 41; continue; };
if (yych <= '"') { gotoCase = 50; continue; };
if (yych <= '%') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '-') {
if (yych <= ',') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '.') { gotoCase = 41; continue; };
if (yych <= '9') { gotoCase = 50; continue; };
{ gotoCase = 41; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 50; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych == '\\') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '^') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '`') { gotoCase = 41; continue; };
if (yych <= 'z') { gotoCase = 50; continue; };
{ gotoCase = 41; continue; };
}
}
}
case 66:
yych = this._charAt(++cursor);
if (yych == 'u') { gotoCase = 95; continue; };
{ gotoCase = 51; continue; };
case 67:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 68; continue; };
if (yych <= '9') { gotoCase = 70; continue; };
case 68:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 32; continue; };
} else {
{ gotoCase = 41; continue; };
}
case 69:
yych = this._charAt(++cursor);
{ gotoCase = 41; continue; };
case 70:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'f') {
if (yych <= 'H') {
if (yych <= '/') {
if (yych == '%') { gotoCase = 69; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych <= '9') { gotoCase = 70; continue; };
if (yych <= 'G') { gotoCase = 41; continue; };
{ gotoCase = 82; continue; };
}
} else {
if (yych <= 'b') {
if (yych == '_') { gotoCase = 74; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych <= 'c') { gotoCase = 76; continue; };
if (yych <= 'd') { gotoCase = 79; continue; };
if (yych >= 'f') { gotoCase = 41; continue; };
}
}
} else {
if (yych <= 'm') {
if (yych <= 'i') {
if (yych <= 'g') { gotoCase = 80; continue; };
if (yych <= 'h') { gotoCase = 41; continue; };
{ gotoCase = 78; continue; };
} else {
if (yych == 'k') { gotoCase = 83; continue; };
if (yych <= 'l') { gotoCase = 41; continue; };
{ gotoCase = 77; continue; };
}
} else {
if (yych <= 'q') {
if (yych == 'p') { gotoCase = 75; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych <= 'r') { gotoCase = 73; continue; };
if (yych <= 's') { gotoCase = 69; continue; };
if (yych <= 't') { gotoCase = 81; continue; };
{ gotoCase = 41; continue; };
}
}
}
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
if (yych == 'x') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 73:
yych = this._charAt(++cursor);
if (yych == 'a') { gotoCase = 93; continue; };
if (yych == 'e') { gotoCase = 94; continue; };
{ gotoCase = 68; continue; };
case 74:
yych = this._charAt(++cursor);
if (yych == '_') { gotoCase = 90; continue; };
{ gotoCase = 68; continue; };
case 75:
yych = this._charAt(++cursor);
if (yych <= 's') {
if (yych == 'c') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
} else {
if (yych <= 't') { gotoCase = 69; continue; };
if (yych == 'x') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
}
case 76:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 77:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
if (yych == 's') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 78:
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 79:
yych = this._charAt(++cursor);
if (yych == 'e') { gotoCase = 89; continue; };
{ gotoCase = 68; continue; };
case 80:
yych = this._charAt(++cursor);
if (yych == 'r') { gotoCase = 87; continue; };
{ gotoCase = 68; continue; };
case 81:
yych = this._charAt(++cursor);
if (yych == 'u') { gotoCase = 85; continue; };
{ gotoCase = 68; continue; };
case 82:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 83:
yych = this._charAt(++cursor);
if (yych != 'H') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 85:
yych = this._charAt(++cursor);
if (yych != 'r') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 87:
yych = this._charAt(++cursor);
if (yych != 'a') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 89:
yych = this._charAt(++cursor);
if (yych == 'g') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 90:
yych = this._charAt(++cursor);
if (yych != 'q') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych != 'e') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 93:
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 94:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 95:
yych = this._charAt(++cursor);
if (yych != 'r') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 97:
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 98:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 99:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 100:
yych = this._charAt(++cursor);
if (yych != 'a') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 102:
yych = this._charAt(++cursor);
if (yych == 'g') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 103:
yych = this._charAt(++cursor);
if (yych != 'q') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych != 'e') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 106:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 110; continue; };
{ gotoCase = 106; continue; };
} else {
if (yych <= '\r') { gotoCase = 110; continue; };
if (yych != '*') { gotoCase = 106; continue; };
}
case 108:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 108; continue; };
if (yych == '/') { gotoCase = 112; continue; };
{ gotoCase = 106; continue; };
case 110:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "css-comment"; return cursor; }
case 112:
++cursor;
{ this.tokenType = "css-comment"; return cursor; }
case 114:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '"') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '%') { gotoCase = 118; continue; };
if (yych <= '&') { gotoCase = 114; continue; };
} else {
if (yych == '-') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 114; continue; };
if (yych <= '<') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '?') { gotoCase = 118; continue; };
if (yych <= '[') { gotoCase = 114; continue; };
{ gotoCase = 120; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '`') { gotoCase = 118; continue; };
if (yych <= 'z') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
}
case 116:
++cursor;
if ((yych = this._charAt(cursor)) <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 117; continue; };
if (yych <= '"') { gotoCase = 50; continue; };
if (yych >= '&') { gotoCase = 50; continue; };
} else {
if (yych <= '-') {
if (yych >= '-') { gotoCase = 50; continue; };
} else {
if (yych <= '.') { gotoCase = 117; continue; };
if (yych <= '9') { gotoCase = 50; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 50; continue; };
} else {
if (yych != '\\') { gotoCase = 50; continue; };
}
} else {
if (yych <= '_') {
if (yych >= '_') { gotoCase = 50; continue; };
} else {
if (yych <= '`') { gotoCase = 117; continue; };
if (yych <= 'z') { gotoCase = 50; continue; };
}
}
}
case 117:
{ return this._stringToken(cursor, true); }
case 118:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 68; continue; };
if (yych <= '\f') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 118; continue; };
{ gotoCase = 123; continue; };
} else {
if (yych != '\\') { gotoCase = 118; continue; };
}
}
case 120:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 68; continue; };
} else {
if (yych != '\r') { gotoCase = 68; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 118; continue; };
if (yych <= '&') { gotoCase = 68; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych == '\\') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 118; continue; };
if (yych <= 'e') { gotoCase = 68; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych == 'n') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 68; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych == 'v') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
}
}
}
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ return this._stringToken(cursor); }
case 123:
yych = this._charAt(++cursor);
{ gotoCase = 117; continue; };
case 124:
++cursor;
yych = this._charAt(cursor);
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 126; continue; };
if (yych <= '"') { gotoCase = 124; continue; };
if (yych >= '&') { gotoCase = 124; continue; };
} else {
if (yych <= '-') {
if (yych >= '-') { gotoCase = 124; continue; };
} else {
if (yych <= '.') { gotoCase = 126; continue; };
if (yych <= '9') { gotoCase = 124; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 124; continue; };
} else {
if (yych != '\\') { gotoCase = 124; continue; };
}
} else {
if (yych <= '_') {
if (yych >= '_') { gotoCase = 124; continue; };
} else {
if (yych <= '`') { gotoCase = 126; continue; };
if (yych <= 'z') { gotoCase = 124; continue; };
}
}
}
case 126:
{
if (this._condition.parseCondition === this._condition.parseCondition.INITIAL || this._condition.parseCondition === this._condition.parseCondition.AT_RULE)
this._setParseCondition(this._parseConditions.PROPERTY);
this.tokenType = "scss-variable";
return cursor;
}
case 127:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 129; continue; };
if (yych <= '9') { gotoCase = 127; continue; };
} else {
if (yych <= 'Z') { gotoCase = 127; continue; };
if (yych <= '`') { gotoCase = 129; continue; };
if (yych <= 'z') { gotoCase = 127; continue; };
}
case 129:
{
if (this._isPropertyValue())
this.tokenType = "css-color";
else if (this._condition.parseCondition === this._parseConditions.INITIAL)
this.tokenType = "css-selector";
else
this.tokenType = null;
return cursor;
}
case 130:
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 = 130; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 116; continue; };
if (yych >= '&') { gotoCase = 130; continue; };
} else {
if (yych == '-') { gotoCase = 130; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 130; continue; };
if (yych >= '=') { gotoCase = 130; continue; };
} else {
if (yych <= '?') { gotoCase = 132; continue; };
if (yych <= '[') { gotoCase = 130; continue; };
{ gotoCase = 134; continue; };
}
} else {
if (yych <= '_') {
if (yych != '^') { gotoCase = 130; continue; };
} else {
if (yych <= '`') { gotoCase = 132; continue; };
if (yych <= 'z') { gotoCase = 130; continue; };
}
}
}
case 132:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 68; continue; };
if (yych <= '\f') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 132; continue; };
{ gotoCase = 123; continue; };
} else {
if (yych != '\\') { gotoCase = 132; continue; };
}
}
case 134:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 68; continue; };
} else {
if (yych != '\r') { gotoCase = 68; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 132; continue; };
if (yych <= '&') { gotoCase = 68; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych == '\\') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 132; continue; };
if (yych <= 'e') { gotoCase = 68; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych == 'n') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 68; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych == 'v') { gotoCase = 132; continue; };
{ gotoCase = 68; 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 = 141; continue; };
if (yych <= '\f') { gotoCase = 140; continue; };
{ gotoCase = 141; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 140; continue; };
{ gotoCase = 143; continue; };
} else {
if (yych == '\\') { gotoCase = 145; continue; };
{ gotoCase = 140; continue; };
}
}
case 139:
{ return this._stringToken(cursor); }
case 140:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 147; continue; };
case 141:
++cursor;
case 142:
{ this.tokenType = null; return cursor; }
case 143:
++cursor;
case 144:
this.setLexCondition(this._lexConditions.INITIAL);
{ return this._stringToken(cursor, true); }
case 145:
yych = this._charAt(++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 146; continue; };
if (yych <= '&') { gotoCase = 142; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 142; continue; };
} else {
if (yych != 'b') { gotoCase = 142; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 142; continue; };
} else {
if (yych <= 'n') { gotoCase = 146; continue; };
if (yych <= 'q') { gotoCase = 142; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 142; continue; };
} else {
if (yych != 'v') { gotoCase = 142; continue; };
}
}
}
case 146:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 147:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 139; continue; };
if (yych <= '\f') { gotoCase = 146; continue; };
{ gotoCase = 139; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 146; continue; };
{ gotoCase = 150; continue; };
} else {
if (yych != '\\') { gotoCase = 146; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 146; continue; };
if (yych >= '\'') { gotoCase = 146; continue; };
} else {
if (yych <= '\\') {
if (yych >= '\\') { gotoCase = 146; continue; };
} else {
if (yych == 'b') { gotoCase = 146; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 146; continue; };
} else {
if (yych <= 'n') { gotoCase = 146; continue; };
if (yych >= 'r') { gotoCase = 146; continue; };
}
} else {
if (yych <= 't') {
if (yych >= 't') { gotoCase = 146; continue; };
} else {
if (yych == 'v') { gotoCase = 146; continue; };
}
}
}
cursor = YYMARKER;
{ gotoCase = 139; continue; };
case 150:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 144; continue; };
}

}
},

__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,
STYLE: 32
};

this.condition = this.createInitialCondition();
}

WebInspector.SourceHTMLTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
},

set line(line) {
if (this._condition.internalJavaScriptTokenizerCondition) {
var match = /<\/script/i.exec(line);
if (match) {
this._internalJavaScriptTokenizer.line = line.substring(0, match.index);
} else
this._internalJavaScriptTokenizer.line = line;
} else if (this._condition.internalCSSTokenizerCondition) {
var match = /<\/style/i.exec(line);
if (match) {
this._internalCSSTokenizer.line = line.substring(0, match.index);
} else
this._internalCSSTokenizer.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";
},

get _internalJavaScriptTokenizer()
{
return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
},

get _internalCSSTokenizer()
{
return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
},

scriptStarted: function(cursor)
{
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.createInitialCondition();
},

scriptEnded: function(cursor)
{
},

styleSheetStarted: function(cursor)
{
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.createInitialCondition();
},

styleSheetEnded: function(cursor)
{
},

nextToken: function(cursor)
{
if (this._condition.internalJavaScriptTokenizerCondition) {

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._condition.internalJavaScriptTokenizerCondition;
} else if (this._condition.internalCSSTokenizerCondition) {

this.line = this._line;
if (cursor !== this._internalCSSTokenizer._line.length) {

this._internalCSSTokenizer.condition = this._condition.internalCSSTokenizerCondition;
var result = this._internalCSSTokenizer.nextToken(cursor);
this.tokenType = this._internalCSSTokenizer.tokenType;
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.condition;
return result;
} else if (cursor !== this._line.length)
delete this._condition.internalCSSTokenizerCondition;
}

var cursorOnEnter = cursor;
var gotoCase = 1;
var YYMARKER;
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._parseConditions.STYLE)) {

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 = 73; continue; };
if (yych == 's') { gotoCase = 73; continue; };
{ gotoCase = 40; continue; };
case 42:
yych = this._charAt(++cursor);
if (yych <= 'T') {
if (yych == 'C') { gotoCase = 62; continue; };
if (yych >= 'T') { gotoCase = 63; continue; };
} else {
if (yych <= 'c') {
if (yych >= 'c') { gotoCase = 62; continue; };
} else {
if (yych == 't') { gotoCase = 63; 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 = 68; continue; };
if (yych == 'r') { gotoCase = 68; continue; };
{ gotoCase = 43; continue; };
case 63:
yych = this._charAt(++cursor);
if (yych == 'Y') { gotoCase = 64; continue; };
if (yych != 'y') { gotoCase = 43; continue; };
case 64:
yych = this._charAt(++cursor);
if (yych == 'L') { gotoCase = 65; continue; };
if (yych != 'l') { gotoCase = 43; continue; };
case 65:
yych = this._charAt(++cursor);
if (yych == 'E') { gotoCase = 66; continue; };
if (yych != 'e') { gotoCase = 43; continue; };
case 66:
++cursor;
this.setLexCondition(this._lexConditions.TAG);
{
if (this._condition.parseCondition & this._parseConditions.STYLE) {

this.setLexCondition(this._lexConditions.INITIAL);
this.tokenType = null;
return cursor;
}
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.STYLE;
this._setExpectingAttribute();
return cursor;
}
case 68:
yych = this._charAt(++cursor);
if (yych == 'I') { gotoCase = 69; continue; };
if (yych != 'i') { gotoCase = 43; continue; };
case 69:
yych = this._charAt(++cursor);
if (yych == 'P') { gotoCase = 70; continue; };
if (yych != 'p') { gotoCase = 43; continue; };
case 70:
yych = this._charAt(++cursor);
if (yych == 'T') { gotoCase = 71; continue; };
if (yych != 't') { gotoCase = 43; continue; };
case 71:
++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 73:
yych = this._charAt(++cursor);
if (yych <= 'T') {
if (yych == 'C') { gotoCase = 75; continue; };
if (yych <= 'S') { gotoCase = 43; continue; };
} else {
if (yych <= 'c') {
if (yych <= 'b') { gotoCase = 43; continue; };
{ gotoCase = 75; continue; };
} else {
if (yych != 't') { gotoCase = 43; continue; };
}
}
yych = this._charAt(++cursor);
if (yych == 'Y') { gotoCase = 81; continue; };
if (yych == 'y') { gotoCase = 81; continue; };
{ gotoCase = 43; continue; };
case 75:
yych = this._charAt(++cursor);
if (yych == 'R') { gotoCase = 76; continue; };
if (yych != 'r') { gotoCase = 43; continue; };
case 76:
yych = this._charAt(++cursor);
if (yych == 'I') { gotoCase = 77; continue; };
if (yych != 'i') { gotoCase = 43; continue; };
case 77:
yych = this._charAt(++cursor);
if (yych == 'P') { gotoCase = 78; continue; };
if (yych != 'p') { gotoCase = 43; continue; };
case 78:
yych = this._charAt(++cursor);
if (yych == 'T') { gotoCase = 79; continue; };
if (yych != 't') { gotoCase = 43; continue; };
case 79:
++cursor;
this.setLexCondition(this._lexConditions.TAG);
{
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.INITIAL;
this.scriptEnded(cursor - 8);
return cursor;
}
case 81:
yych = this._charAt(++cursor);
if (yych == 'L') { gotoCase = 82; continue; };
if (yych != 'l') { gotoCase = 43; continue; };
case 82:
yych = this._charAt(++cursor);
if (yych == 'E') { gotoCase = 83; continue; };
if (yych != 'e') { gotoCase = 43; continue; };
case 83:
++cursor;
this.setLexCondition(this._lexConditions.TAG);
{
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.INITIAL;
this.styleSheetEnded(cursor - 7);
return cursor;
}

case this.case_SSTRING:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 89; continue; };
{ gotoCase = 88; continue; };
} else {
if (yych <= '\r') { gotoCase = 89; continue; };
if (yych == '\'') { gotoCase = 91; continue; };
{ gotoCase = 88; continue; };
}
case 87:
{ return this._stringToken(cursor); }
case 88:
yych = this._charAt(++cursor);
{ gotoCase = 95; continue; };
case 89:
++cursor;
{ this.tokenType = null; return cursor; }
case 91:
++cursor;
case 92:
this.setLexCondition(this._lexConditions.TAG);
{ return this._stringToken(cursor, true); }
case 93:
yych = this._charAt(++cursor);
{ gotoCase = 92; continue; };
case 94:
++cursor;
yych = this._charAt(cursor);
case 95:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 87; continue; };
{ gotoCase = 94; continue; };
} else {
if (yych <= '\r') { gotoCase = 87; continue; };
if (yych == '\'') { gotoCase = 93; continue; };
{ gotoCase = 94; continue; };
}

case this.case_TAG:
yych = this._charAt(cursor);
if (yych <= '&') {
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 100; continue; };
if (yych >= '\r') { gotoCase = 100; continue; };
} else {
if (yych <= ' ') {
if (yych >= ' ') { gotoCase = 100; continue; };
} else {
if (yych == '"') { gotoCase = 102; continue; };
}
}
} else {
if (yych <= '>') {
if (yych <= ';') {
if (yych <= '\'') { gotoCase = 103; continue; };
} else {
if (yych <= '<') { gotoCase = 100; continue; };
if (yych <= '=') { gotoCase = 104; continue; };
{ gotoCase = 106; continue; };
}
} else {
if (yych <= '[') {
if (yych >= '[') { gotoCase = 100; continue; };
} else {
if (yych == ']') { gotoCase = 100; continue; };
}
}
}
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 119; continue; };
case 99:
{
if (this._condition.parseCondition === this._parseConditions.SCRIPT || this._condition.parseCondition === this._parseConditions.STYLE) {

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 100:
++cursor;
{ this.tokenType = null; return cursor; }
case 102:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 115; continue; };
case 103:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 109; continue; };
case 104:
++cursor;
{
if (this._isExpectingAttribute())
this._setExpectingAttributeValue();
this.tokenType = null;
return cursor;
}
case 106:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{
this.tokenType = "html-tag";
if (this._condition.parseCondition & this._parseConditions.SCRIPT) {
this.scriptStarted(cursor);

return cursor;
}

if (this._condition.parseCondition & this._parseConditions.STYLE) {
this.styleSheetStarted(cursor);

return cursor;
}

this._condition.parseCondition = this._parseConditions.INITIAL;
return cursor;
}
case 108:
++cursor;
yych = this._charAt(cursor);
case 109:
if (yych <= '\f') {
if (yych != '\n') { gotoCase = 108; continue; };
} else {
if (yych <= '\r') { gotoCase = 110; continue; };
if (yych == '\'') { gotoCase = 112; continue; };
{ gotoCase = 108; continue; };
}
case 110:
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ return this._stringToken(cursor); }
case 112:
++cursor;
{ return this._stringToken(cursor, true); }
case 114:
++cursor;
yych = this._charAt(cursor);
case 115:
if (yych <= '\f') {
if (yych != '\n') { gotoCase = 114; continue; };
} else {
if (yych <= '\r') { gotoCase = 116; continue; };
if (yych == '"') { gotoCase = 112; continue; };
{ gotoCase = 114; continue; };
}
case 116:
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ return this._stringToken(cursor); }
case 118:
++cursor;
yych = this._charAt(cursor);
case 119:
if (yych <= '"') {
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 99; continue; };
if (yych <= '\f') { gotoCase = 118; continue; };
{ gotoCase = 99; continue; };
} else {
if (yych == ' ') { gotoCase = 99; continue; };
if (yych <= '!') { gotoCase = 118; continue; };
{ gotoCase = 99; continue; };
}
} else {
if (yych <= '>') {
if (yych == '\'') { gotoCase = 99; continue; };
if (yych <= ';') { gotoCase = 118; continue; };
{ gotoCase = 99; continue; };
} else {
if (yych <= '[') {
if (yych <= 'Z') { gotoCase = 118; continue; };
{ gotoCase = 99; continue; };
} else {
if (yych == ']') { gotoCase = 99; continue; };
{ gotoCase = 118; continue; };
}
}
}
}

}
},

__proto__: WebInspector.SourceTokenizer.prototype
}









WebInspector.SourceJavaScriptTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);

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.condition = this.createInitialCondition();
}

WebInspector.SourceJavaScriptTokenizer.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();

WebInspector.SourceJavaScriptTokenizer.GlobalObjectValueProperties = {
"NaN": "javascript-nan",
"undefined": "javascript-undef",
"Infinity": "javascript-inf"
};

WebInspector.SourceJavaScriptTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.NODIV };
},

nextToken: function(cursor)
{
var cursorOnEnter = cursor;
var gotoCase = 1;
var YYMARKER;
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 <= String.fromCharCode(0x1F)) { gotoCase = 15; continue; };
if (yych <= ' ') { gotoCase = 17; continue; };
if (yych <= '!') { gotoCase = 19; continue; };
{ gotoCase = 21; continue; };
} else {
if (yych <= '$') {
if (yych >= '$') { gotoCase = 22; continue; };
} else {
if (yych <= '%') { gotoCase = 24; continue; };
if (yych <= '&') { gotoCase = 25; continue; };
{ gotoCase = 26; continue; };
}
}
} else {
if (yych <= ',') {
if (yych <= ')') {
if (yych <= '(') { gotoCase = 27; continue; };
{ gotoCase = 28; continue; };
} else {
if (yych <= '*') { gotoCase = 30; continue; };
if (yych <= '+') { gotoCase = 31; continue; };
{ gotoCase = 27; continue; };
}
} else {
if (yych <= '.') {
if (yych <= '-') { gotoCase = 32; continue; };
{ gotoCase = 33; continue; };
} else {
if (yych <= '/') { gotoCase = 34; continue; };
if (yych <= '0') { gotoCase = 36; continue; };
{ gotoCase = 38; continue; };
}
}
}
} else {
if (yych <= '\\') {
if (yych <= '>') {
if (yych <= ';') { gotoCase = 27; continue; };
if (yych <= '<') { gotoCase = 39; continue; };
if (yych <= '=') { gotoCase = 40; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych <= '@') {
if (yych <= '?') { gotoCase = 27; continue; };
} else {
if (yych <= 'Z') { gotoCase = 22; continue; };
if (yych <= '[') { gotoCase = 27; continue; };
{ gotoCase = 42; continue; };
}
}
} else {
if (yych <= 'z') {
if (yych <= '^') {
if (yych <= ']') { gotoCase = 27; continue; };
{ gotoCase = 43; continue; };
} else {
if (yych != '`') { gotoCase = 22; continue; };
}
} else {
if (yych <= '|') {
if (yych <= '{') { gotoCase = 27; continue; };
{ gotoCase = 44; continue; };
} else {
if (yych <= '~') { gotoCase = 27; continue; };
if (yych >= 0x80) { gotoCase = 22; continue; };
}
}
}
}
case 15:
++cursor;
case 16:
{ this.tokenType = null; return cursor; }
case 17:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 119; continue; };
case 18:
{this.tokenType = "whitespace"; return cursor; }
case 19:
++cursor;
if ((yych = this._charAt(cursor)) == '=') { gotoCase = 117; continue; };
case 20:
this.setLexCondition(this._lexConditions.NODIV);
{
var token = this._line.charAt(cursorOnEnter);
if (token === "{")
this.tokenType = "block-start";
else if (token === "}")
this.tokenType = "block-end";
else if (token === "(")
this.tokenType = "brace-start";
else this.tokenType = null;
return cursor;
}
case 21:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 16; continue; };
if (yych == '\r') { gotoCase = 16; continue; };
{ gotoCase = 109; continue; };
case 22:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 52; continue; };
case 23:
{
var token = this._line.substring(cursorOnEnter, cursor);
if (WebInspector.SourceJavaScriptTokenizer.GlobalObjectValueProperties.hasOwnProperty(token))
this.tokenType = WebInspector.SourceJavaScriptTokenizer.GlobalObjectValueProperties[token];
else if (WebInspector.SourceJavaScriptTokenizer.Keywords[token] === true && token !== "__proto__")
this.tokenType = "javascript-keyword";
else
this.tokenType = "javascript-ident";
return cursor;
}
case 24:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 25:
yych = this._charAt(++cursor);
if (yych == '&') { gotoCase = 45; continue; };
if (yych == '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 26:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 16; continue; };
if (yych == '\r') { gotoCase = 16; continue; };
{ gotoCase = 98; continue; };
case 27:
yych = this._charAt(++cursor);
{ gotoCase = 20; continue; };
case 28:
++cursor;
{ this.tokenType = "brace-end"; return cursor; }
case 30:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 31:
yych = this._charAt(++cursor);
if (yych == '+') { gotoCase = 45; continue; };
if (yych == '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 32:
yych = this._charAt(++cursor);
if (yych == '-') { gotoCase = 45; continue; };
if (yych == '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 33:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 20; continue; };
if (yych <= '9') { gotoCase = 91; continue; };
{ gotoCase = 20; continue; };
case 34:
yyaccept = 2;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '.') {
if (yych == '*') { gotoCase = 80; continue; };
} else {
if (yych <= '/') { gotoCase = 82; continue; };
if (yych == '=') { gotoCase = 79; continue; };
}
case 35:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = null; return cursor; }
case 36:
yyaccept = 3;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'E') {
if (yych <= '/') {
if (yych == '.') { gotoCase = 65; continue; };
} else {
if (yych <= '7') { gotoCase = 74; continue; };
if (yych >= 'E') { gotoCase = 64; continue; };
}
} else {
if (yych <= 'd') {
if (yych == 'X') { gotoCase = 76; continue; };
} else {
if (yych <= 'e') { gotoCase = 64; continue; };
if (yych == 'x') { gotoCase = 76; continue; };
}
}
case 37:
{ this.tokenType = "javascript-number"; return cursor; }
case 38:
yyaccept = 3;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 65; continue; };
if (yych <= '/') { gotoCase = 37; continue; };
{ gotoCase = 62; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 37; continue; };
{ gotoCase = 64; continue; };
} else {
if (yych == 'e') { gotoCase = 64; continue; };
{ gotoCase = 37; continue; };
}
}
case 39:
yych = this._charAt(++cursor);
if (yych <= ';') { gotoCase = 20; continue; };
if (yych <= '<') { gotoCase = 61; continue; };
if (yych <= '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 40:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 60; continue; };
{ gotoCase = 20; continue; };
case 41:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 20; continue; };
if (yych <= '=') { gotoCase = 45; continue; };
if (yych <= '>') { gotoCase = 58; continue; };
{ gotoCase = 20; continue; };
case 42:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == 'u') { gotoCase = 46; continue; };
{ gotoCase = 16; continue; };
case 43:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 44:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 45; continue; };
if (yych != '|') { gotoCase = 20; continue; };
case 45:
yych = this._charAt(++cursor);
{ gotoCase = 20; continue; };
case 46:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych <= '9') { gotoCase = 48; continue; };
} else {
if (yych <= 'F') { gotoCase = 48; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych <= 'f') { gotoCase = 48; continue; };
}
case 47:
cursor = YYMARKER;
if (yyaccept <= 1) {
if (yyaccept <= 0) {
{ gotoCase = 16; continue; };
} else {
{ gotoCase = 23; continue; };
}
} else {
if (yyaccept <= 2) {
{ gotoCase = 35; continue; };
} else {
{ gotoCase = 37; continue; };
}
}
case 48:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 49; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 49:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 50; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 50:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 51; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 51:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 52:
if (yych <= '[') {
if (yych <= '/') {
if (yych == '$') { gotoCase = 51; continue; };
{ gotoCase = 23; continue; };
} else {
if (yych <= '9') { gotoCase = 51; continue; };
if (yych <= '@') { gotoCase = 23; continue; };
if (yych <= 'Z') { gotoCase = 51; continue; };
{ gotoCase = 23; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '\\') { gotoCase = 53; continue; };
if (yych <= '^') { gotoCase = 23; continue; };
{ gotoCase = 51; continue; };
} else {
if (yych <= '`') { gotoCase = 23; continue; };
if (yych <= 'z') { gotoCase = 51; continue; };
if (yych <= String.fromCharCode(0x7F)) { gotoCase = 23; continue; };
{ gotoCase = 51; continue; };
}
}
case 53:
++cursor;
yych = this._charAt(cursor);
if (yych != 'u') { gotoCase = 47; continue; };
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 55; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 55:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 56; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 56:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 57; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 57:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych <= '9') { gotoCase = 51; continue; };
{ gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 51; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych <= 'f') { gotoCase = 51; continue; };
{ gotoCase = 47; continue; };
}
case 58:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 20; continue; };
if (yych <= '=') { gotoCase = 45; continue; };
if (yych >= '?') { gotoCase = 20; continue; };
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 60:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 61:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 62:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 65; continue; };
if (yych <= '/') { gotoCase = 37; continue; };
{ gotoCase = 62; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 37; continue; };
} else {
if (yych != 'e') { gotoCase = 37; continue; };
}
}
case 64:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych == '+') { gotoCase = 71; continue; };
{ gotoCase = 47; continue; };
} else {
if (yych <= '-') { gotoCase = 71; continue; };
if (yych <= '/') { gotoCase = 47; continue; };
if (yych <= '9') { gotoCase = 72; continue; };
{ gotoCase = 47; continue; };
}
case 65:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 37; continue; };
if (yych <= '9') { gotoCase = 65; continue; };
{ gotoCase = 37; continue; };
} else {
if (yych <= 'E') { gotoCase = 67; continue; };
if (yych != 'e') { gotoCase = 37; continue; };
}
case 67:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 47; continue; };
} else {
if (yych <= '-') { gotoCase = 68; continue; };
if (yych <= '/') { gotoCase = 47; continue; };
if (yych <= '9') { gotoCase = 69; continue; };
{ gotoCase = 47; continue; };
}
case 68:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
case 69:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 37; continue; };
if (yych <= '9') { gotoCase = 69; continue; };
{ gotoCase = 37; continue; };
case 71:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
case 72:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 37; continue; };
if (yych <= '9') { gotoCase = 72; continue; };
{ gotoCase = 37; continue; };
case 74:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 37; continue; };
if (yych <= '7') { gotoCase = 74; continue; };
{ gotoCase = 37; continue; };
case 76:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 77; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 77:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 37; continue; };
if (yych <= '9') { gotoCase = 77; continue; };
{ gotoCase = 37; continue; };
} else {
if (yych <= 'F') { gotoCase = 77; continue; };
if (yych <= '`') { gotoCase = 37; continue; };
if (yych <= 'f') { gotoCase = 77; continue; };
{ gotoCase = 37; continue; };
}
case 79:
yych = this._charAt(++cursor);
{ gotoCase = 35; continue; };
case 80:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 87; continue; };
{ gotoCase = 80; continue; };
} else {
if (yych <= '\r') { gotoCase = 87; continue; };
if (yych == '*') { gotoCase = 85; continue; };
{ gotoCase = 80; continue; };
}
case 82:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 84; continue; };
if (yych != '\r') { gotoCase = 82; continue; };
case 84:
{ this.tokenType = "javascript-comment"; return cursor; }
case 85:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 85; continue; };
if (yych == '/') { gotoCase = 89; continue; };
{ gotoCase = 80; continue; };
case 87:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "javascript-comment"; return cursor; }
case 89:
++cursor;
{ this.tokenType = "javascript-comment"; return cursor; }
case 91:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 37; continue; };
if (yych <= '9') { gotoCase = 91; continue; };
{ gotoCase = 37; continue; };
} else {
if (yych <= 'E') { gotoCase = 93; continue; };
if (yych != 'e') { gotoCase = 37; continue; };
}
case 93:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 47; continue; };
} else {
if (yych <= '-') { gotoCase = 94; continue; };
if (yych <= '/') { gotoCase = 47; continue; };
if (yych <= '9') { gotoCase = 95; continue; };
{ gotoCase = 47; continue; };
}
case 94:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
case 95:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 37; continue; };
if (yych <= '9') { gotoCase = 95; continue; };
{ gotoCase = 37; continue; };
case 97:
++cursor;
yych = this._charAt(cursor);
case 98:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 47; continue; };
if (yych <= '\f') { gotoCase = 97; continue; };
{ gotoCase = 47; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 97; continue; };
{ gotoCase = 100; continue; };
} else {
if (yych != '\\') { gotoCase = 97; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 47; continue; };
{ gotoCase = 103; continue; };
} else {
if (yych == '\r') { gotoCase = 103; continue; };
{ gotoCase = 47; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 97; continue; };
if (yych <= '&') { gotoCase = 47; continue; };
{ gotoCase = 97; continue; };
} else {
if (yych == '\\') { gotoCase = 97; continue; };
{ gotoCase = 47; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 97; continue; };
if (yych <= 'e') { gotoCase = 47; continue; };
{ gotoCase = 97; continue; };
} else {
if (yych == 'n') { gotoCase = 97; continue; };
{ gotoCase = 47; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 47; continue; };
{ gotoCase = 97; continue; };
} else {
if (yych <= 'u') { gotoCase = 102; continue; };
if (yych <= 'v') { gotoCase = 97; continue; };
{ gotoCase = 47; continue; };
}
}
}
case 100:
++cursor;
{ this.tokenType = "javascript-string"; return cursor; }
case 102:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych <= '9') { gotoCase = 105; continue; };
{ gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 105; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych <= 'f') { gotoCase = 105; continue; };
{ gotoCase = 47; continue; };
}
case 103:
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 105:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 106; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 106:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 107; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 107:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych <= '9') { gotoCase = 97; continue; };
{ gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 97; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych <= 'f') { gotoCase = 97; continue; };
{ gotoCase = 47; continue; };
}
case 108:
++cursor;
yych = this._charAt(cursor);
case 109:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 47; continue; };
if (yych <= '\f') { gotoCase = 108; continue; };
{ gotoCase = 47; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 108; continue; };
{ gotoCase = 100; continue; };
} else {
if (yych != '\\') { gotoCase = 108; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 47; continue; };
{ gotoCase = 112; continue; };
} else {
if (yych == '\r') { gotoCase = 112; continue; };
{ gotoCase = 47; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 108; continue; };
if (yych <= '&') { gotoCase = 47; continue; };
{ gotoCase = 108; continue; };
} else {
if (yych == '\\') { gotoCase = 108; continue; };
{ gotoCase = 47; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 108; continue; };
if (yych <= 'e') { gotoCase = 47; continue; };
{ gotoCase = 108; continue; };
} else {
if (yych == 'n') { gotoCase = 108; continue; };
{ gotoCase = 47; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 47; continue; };
{ gotoCase = 108; continue; };
} else {
if (yych <= 'u') { gotoCase = 111; continue; };
if (yych <= 'v') { gotoCase = 108; continue; };
{ gotoCase = 47; continue; };
}
}
}
case 111:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych <= '9') { gotoCase = 114; continue; };
{ gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 114; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych <= 'f') { gotoCase = 114; continue; };
{ gotoCase = 47; continue; };
}
case 112:
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 114:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 115; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 115:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych >= ':') { gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 116; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych >= 'g') { gotoCase = 47; continue; };
}
case 116:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 47; continue; };
if (yych <= '9') { gotoCase = 108; continue; };
{ gotoCase = 47; continue; };
} else {
if (yych <= 'F') { gotoCase = 108; continue; };
if (yych <= '`') { gotoCase = 47; continue; };
if (yych <= 'f') { gotoCase = 108; continue; };
{ gotoCase = 47; continue; };
}
case 117:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 45; continue; };
{ gotoCase = 20; continue; };
case 118:
++cursor;
yych = this._charAt(cursor);
case 119:
if (yych == ' ') { gotoCase = 118; continue; };
{ gotoCase = 18; continue; };

case this.case_DSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 124; continue; };
if (yych <= '\f') { gotoCase = 123; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 123; continue; };
{ gotoCase = 126; continue; };
} else {
if (yych == '\\') { gotoCase = 128; continue; };
{ gotoCase = 123; continue; };
}
}
case 122:
{ this.tokenType = "javascript-string"; return cursor; }
case 123:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 130; continue; };
case 124:
++cursor;
case 125:
{ this.tokenType = null; return cursor; }
case 126:
++cursor;
case 127:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-string"; return cursor; }
case 128:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 129; continue; };
if (yych <= '&') { gotoCase = 125; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 125; continue; };
} else {
if (yych != 'b') { gotoCase = 125; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 125; continue; };
} else {
if (yych <= 'n') { gotoCase = 129; continue; };
if (yych <= 'q') { gotoCase = 125; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 125; continue; };
} else {
if (yych <= 'u') { gotoCase = 131; continue; };
if (yych >= 'w') { gotoCase = 125; continue; };
}
}
}
case 129:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 130:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 122; continue; };
if (yych <= '\f') { gotoCase = 129; continue; };
{ gotoCase = 122; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 129; continue; };
{ gotoCase = 137; continue; };
} else {
if (yych == '\\') { gotoCase = 136; continue; };
{ gotoCase = 129; continue; };
}
}
case 131:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 132; continue; };
if (yych <= '9') { gotoCase = 133; continue; };
} else {
if (yych <= 'F') { gotoCase = 133; continue; };
if (yych <= '`') { gotoCase = 132; continue; };
if (yych <= 'f') { gotoCase = 133; continue; };
}
case 132:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 122; continue; };
} else {
{ gotoCase = 125; continue; };
}
case 133:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 132; continue; };
if (yych >= ':') { gotoCase = 132; continue; };
} else {
if (yych <= 'F') { gotoCase = 134; continue; };
if (yych <= '`') { gotoCase = 132; continue; };
if (yych >= 'g') { gotoCase = 132; continue; };
}
case 134:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 132; continue; };
if (yych >= ':') { gotoCase = 132; continue; };
} else {
if (yych <= 'F') { gotoCase = 135; continue; };
if (yych <= '`') { gotoCase = 132; continue; };
if (yych >= 'g') { gotoCase = 132; continue; };
}
case 135:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 132; continue; };
if (yych <= '9') { gotoCase = 129; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych <= 'F') { gotoCase = 129; continue; };
if (yych <= '`') { gotoCase = 132; continue; };
if (yych <= 'f') { gotoCase = 129; continue; };
{ gotoCase = 132; continue; };
}
case 136:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 129; continue; };
if (yych <= '&') { gotoCase = 132; continue; };
{ gotoCase = 129; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 132; continue; };
{ gotoCase = 129; continue; };
} else {
if (yych == 'b') { gotoCase = 129; continue; };
{ gotoCase = 132; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 129; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych <= 'n') { gotoCase = 129; continue; };
if (yych <= 'q') { gotoCase = 132; continue; };
{ gotoCase = 129; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 132; continue; };
{ gotoCase = 129; continue; };
} else {
if (yych <= 'u') { gotoCase = 131; continue; };
if (yych <= 'v') { gotoCase = 129; continue; };
{ gotoCase = 132; continue; };
}
}
}
case 137:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 127; continue; };

case this.case_NODIV:
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych <= '\'') {
if (yych <= '"') {
if (yych <= String.fromCharCode(0x1F)) { gotoCase = 140; continue; };
if (yych <= ' ') { gotoCase = 142; continue; };
if (yych <= '!') { gotoCase = 144; continue; };
{ gotoCase = 146; continue; };
} else {
if (yych <= '$') {
if (yych >= '$') { gotoCase = 147; continue; };
} else {
if (yych <= '%') { gotoCase = 149; continue; };
if (yych <= '&') { gotoCase = 150; continue; };
{ gotoCase = 151; continue; };
}
}
} else {
if (yych <= ',') {
if (yych <= ')') {
if (yych <= '(') { gotoCase = 152; continue; };
{ gotoCase = 153; continue; };
} else {
if (yych <= '*') { gotoCase = 155; continue; };
if (yych <= '+') { gotoCase = 156; continue; };
{ gotoCase = 152; continue; };
}
} else {
if (yych <= '.') {
if (yych <= '-') { gotoCase = 157; continue; };
{ gotoCase = 158; continue; };
} else {
if (yych <= '/') { gotoCase = 159; continue; };
if (yych <= '0') { gotoCase = 160; continue; };
{ gotoCase = 162; continue; };
}
}
}
} else {
if (yych <= '\\') {
if (yych <= '>') {
if (yych <= ';') { gotoCase = 152; continue; };
if (yych <= '<') { gotoCase = 163; continue; };
if (yych <= '=') { gotoCase = 164; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= '@') {
if (yych <= '?') { gotoCase = 152; continue; };
} else {
if (yych <= 'Z') { gotoCase = 147; continue; };
if (yych <= '[') { gotoCase = 152; continue; };
{ gotoCase = 166; continue; };
}
}
} else {
if (yych <= 'z') {
if (yych <= '^') {
if (yych <= ']') { gotoCase = 152; continue; };
{ gotoCase = 167; continue; };
} else {
if (yych != '`') { gotoCase = 147; continue; };
}
} else {
if (yych <= '|') {
if (yych <= '{') { gotoCase = 152; continue; };
{ gotoCase = 168; continue; };
} else {
if (yych <= '~') { gotoCase = 152; continue; };
if (yych >= 0x80) { gotoCase = 147; continue; };
}
}
}
}
case 140:
++cursor;
case 141:
{ this.tokenType = null; return cursor; }
case 142:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 268; continue; };
case 143:
{this.tokenType = "whitespace"; return cursor; }
case 144:
++cursor;
if ((yych = this._charAt(cursor)) == '=') { gotoCase = 266; continue; };
case 145:
{
var token = this._line.charAt(cursorOnEnter);
if (token === "{")
this.tokenType = "block-start";
else if (token === "}")
this.tokenType = "block-end";
else if (token === "(")
this.tokenType = "brace-start";
else this.tokenType = null;
return cursor;
}
case 146:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 141; continue; };
if (yych == '\r') { gotoCase = 141; continue; };
{ gotoCase = 258; continue; };
case 147:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 176; continue; };
case 148:
this.setLexCondition(this._lexConditions.DIV);
{
var token = this._line.substring(cursorOnEnter, cursor);
if (WebInspector.SourceJavaScriptTokenizer.GlobalObjectValueProperties.hasOwnProperty(token))
this.tokenType = WebInspector.SourceJavaScriptTokenizer.GlobalObjectValueProperties[token];
else if (WebInspector.SourceJavaScriptTokenizer.Keywords[token] === true && token !== "__proto__")
this.tokenType = "javascript-keyword";
else
this.tokenType = "javascript-ident";
return cursor;
}
case 149:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 150:
yych = this._charAt(++cursor);
if (yych == '&') { gotoCase = 169; continue; };
if (yych == '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 151:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 141; continue; };
if (yych == '\r') { gotoCase = 141; continue; };
{ gotoCase = 247; continue; };
case 152:
yych = this._charAt(++cursor);
{ gotoCase = 145; continue; };
case 153:
++cursor;
this.setLexCondition(this._lexConditions.DIV);
{ this.tokenType = "brace-end"; return cursor; }
case 155:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 156:
yych = this._charAt(++cursor);
if (yych == '+') { gotoCase = 169; continue; };
if (yych == '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 157:
yych = this._charAt(++cursor);
if (yych == '-') { gotoCase = 169; continue; };
if (yych == '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 158:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 145; continue; };
if (yych <= '9') { gotoCase = 240; continue; };
{ gotoCase = 145; continue; };
case 159:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 141; continue; };
{ gotoCase = 203; continue; };
} else {
if (yych <= '\r') { gotoCase = 141; continue; };
if (yych <= ')') { gotoCase = 203; continue; };
{ gotoCase = 208; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 210; continue; };
{ gotoCase = 203; continue; };
} else {
if (yych <= '[') { gotoCase = 206; continue; };
if (yych <= '\\') { gotoCase = 205; continue; };
if (yych <= ']') { gotoCase = 141; continue; };
{ gotoCase = 203; continue; };
}
}
case 160:
yyaccept = 2;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'E') {
if (yych <= '/') {
if (yych == '.') { gotoCase = 189; continue; };
} else {
if (yych <= '7') { gotoCase = 198; continue; };
if (yych >= 'E') { gotoCase = 188; continue; };
}
} else {
if (yych <= 'd') {
if (yych == 'X') { gotoCase = 200; continue; };
} else {
if (yych <= 'e') { gotoCase = 188; continue; };
if (yych == 'x') { gotoCase = 200; continue; };
}
}
case 161:
this.setLexCondition(this._lexConditions.DIV);
{ this.tokenType = "javascript-number"; return cursor; }
case 162:
yyaccept = 2;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 189; continue; };
if (yych <= '/') { gotoCase = 161; continue; };
{ gotoCase = 186; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 161; continue; };
{ gotoCase = 188; continue; };
} else {
if (yych == 'e') { gotoCase = 188; continue; };
{ gotoCase = 161; continue; };
}
}
case 163:
yych = this._charAt(++cursor);
if (yych <= ';') { gotoCase = 145; continue; };
if (yych <= '<') { gotoCase = 185; continue; };
if (yych <= '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 164:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 184; continue; };
{ gotoCase = 145; continue; };
case 165:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 145; continue; };
if (yych <= '=') { gotoCase = 169; continue; };
if (yych <= '>') { gotoCase = 182; continue; };
{ gotoCase = 145; continue; };
case 166:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == 'u') { gotoCase = 170; continue; };
{ gotoCase = 141; continue; };
case 167:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 168:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 169; continue; };
if (yych != '|') { gotoCase = 145; continue; };
case 169:
yych = this._charAt(++cursor);
{ gotoCase = 145; continue; };
case 170:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych <= '9') { gotoCase = 172; continue; };
} else {
if (yych <= 'F') { gotoCase = 172; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych <= 'f') { gotoCase = 172; continue; };
}
case 171:
cursor = YYMARKER;
if (yyaccept <= 1) {
if (yyaccept <= 0) {
{ gotoCase = 141; continue; };
} else {
{ gotoCase = 148; continue; };
}
} else {
if (yyaccept <= 2) {
{ gotoCase = 161; continue; };
} else {
{ gotoCase = 223; continue; };
}
}
case 172:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 173; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 173:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 174; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 174:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 175; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 175:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 176:
if (yych <= '[') {
if (yych <= '/') {
if (yych == '$') { gotoCase = 175; continue; };
{ gotoCase = 148; continue; };
} else {
if (yych <= '9') { gotoCase = 175; continue; };
if (yych <= '@') { gotoCase = 148; continue; };
if (yych <= 'Z') { gotoCase = 175; continue; };
{ gotoCase = 148; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '\\') { gotoCase = 177; continue; };
if (yych <= '^') { gotoCase = 148; continue; };
{ gotoCase = 175; continue; };
} else {
if (yych <= '`') { gotoCase = 148; continue; };
if (yych <= 'z') { gotoCase = 175; continue; };
if (yych <= String.fromCharCode(0x7F)) { gotoCase = 148; continue; };
{ gotoCase = 175; continue; };
}
}
case 177:
++cursor;
yych = this._charAt(cursor);
if (yych != 'u') { gotoCase = 171; continue; };
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 179; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 179:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 180; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 180:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 181; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 181:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych <= '9') { gotoCase = 175; continue; };
{ gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 175; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych <= 'f') { gotoCase = 175; continue; };
{ gotoCase = 171; continue; };
}
case 182:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 145; continue; };
if (yych <= '=') { gotoCase = 169; continue; };
if (yych >= '?') { gotoCase = 145; continue; };
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 184:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 185:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 186:
yyaccept = 2;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 189; continue; };
if (yych <= '/') { gotoCase = 161; continue; };
{ gotoCase = 186; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 161; continue; };
} else {
if (yych != 'e') { gotoCase = 161; continue; };
}
}
case 188:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych == '+') { gotoCase = 195; continue; };
{ gotoCase = 171; continue; };
} else {
if (yych <= '-') { gotoCase = 195; continue; };
if (yych <= '/') { gotoCase = 171; continue; };
if (yych <= '9') { gotoCase = 196; continue; };
{ gotoCase = 171; continue; };
}
case 189:
yyaccept = 2;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 161; continue; };
if (yych <= '9') { gotoCase = 189; continue; };
{ gotoCase = 161; continue; };
} else {
if (yych <= 'E') { gotoCase = 191; continue; };
if (yych != 'e') { gotoCase = 161; continue; };
}
case 191:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 171; continue; };
} else {
if (yych <= '-') { gotoCase = 192; continue; };
if (yych <= '/') { gotoCase = 171; continue; };
if (yych <= '9') { gotoCase = 193; continue; };
{ gotoCase = 171; continue; };
}
case 192:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
case 193:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 161; continue; };
if (yych <= '9') { gotoCase = 193; continue; };
{ gotoCase = 161; continue; };
case 195:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
case 196:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 161; continue; };
if (yych <= '9') { gotoCase = 196; continue; };
{ gotoCase = 161; continue; };
case 198:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 161; continue; };
if (yych <= '7') { gotoCase = 198; continue; };
{ gotoCase = 161; continue; };
case 200:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 201; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 201:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 161; continue; };
if (yych <= '9') { gotoCase = 201; continue; };
{ gotoCase = 161; continue; };
} else {
if (yych <= 'F') { gotoCase = 201; continue; };
if (yych <= '`') { gotoCase = 161; continue; };
if (yych <= 'f') { gotoCase = 201; continue; };
{ gotoCase = 161; continue; };
}
case 203:
++cursor;
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 203; continue; };
{ gotoCase = 171; continue; };
} else {
if (yych == '\r') { gotoCase = 171; continue; };
{ gotoCase = 203; continue; };
}
} else {
if (yych <= '[') {
if (yych <= '/') { gotoCase = 226; continue; };
if (yych <= 'Z') { gotoCase = 203; continue; };
{ gotoCase = 234; continue; };
} else {
if (yych <= '\\') { gotoCase = 233; continue; };
if (yych <= ']') { gotoCase = 171; continue; };
{ gotoCase = 203; continue; };
}
}
case 205:
yych = this._charAt(++cursor);
if (yych == '\n') { gotoCase = 171; continue; };
if (yych == '\r') { gotoCase = 171; continue; };
{ gotoCase = 203; continue; };
case 206:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 171; continue; };
{ gotoCase = 206; continue; };
} else {
if (yych <= '\r') { gotoCase = 171; continue; };
if (yych <= ')') { gotoCase = 206; continue; };
{ gotoCase = 171; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 171; continue; };
{ gotoCase = 206; continue; };
} else {
if (yych <= '\\') { gotoCase = 221; continue; };
if (yych <= ']') { gotoCase = 219; continue; };
{ gotoCase = 206; continue; };
}
}
case 208:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 215; continue; };
{ gotoCase = 208; continue; };
} else {
if (yych <= '\r') { gotoCase = 215; continue; };
if (yych == '*') { gotoCase = 213; continue; };
{ gotoCase = 208; continue; };
}
case 210:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 212; continue; };
if (yych != '\r') { gotoCase = 210; continue; };
case 212:
{ this.tokenType = "javascript-comment"; return cursor; }
case 213:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 213; continue; };
if (yych == '/') { gotoCase = 217; continue; };
{ gotoCase = 208; continue; };
case 215:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "javascript-comment"; return cursor; }
case 217:
++cursor;
{ this.tokenType = "javascript-comment"; return cursor; }
case 219:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 171; continue; };
{ gotoCase = 219; continue; };
} else {
if (yych <= '\r') { gotoCase = 171; continue; };
if (yych <= ')') { gotoCase = 219; continue; };
{ gotoCase = 203; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 226; continue; };
{ gotoCase = 219; continue; };
} else {
if (yych <= '[') { gotoCase = 224; continue; };
if (yych <= '\\') { gotoCase = 222; continue; };
{ gotoCase = 219; continue; };
}
}
case 221:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 171; continue; };
if (yych == '\r') { gotoCase = 171; continue; };
{ gotoCase = 206; continue; };
case 222:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 223; continue; };
if (yych != '\r') { gotoCase = 219; continue; };
case 223:
this.setLexCondition(this._lexConditions.REGEX);
{ this.tokenType = "javascript-regexp"; return cursor; }
case 224:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 171; continue; };
{ gotoCase = 224; continue; };
} else {
if (yych <= '\r') { gotoCase = 171; continue; };
if (yych <= ')') { gotoCase = 224; continue; };
{ gotoCase = 171; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 171; continue; };
{ gotoCase = 224; continue; };
} else {
if (yych <= '\\') { gotoCase = 231; continue; };
if (yych <= ']') { gotoCase = 229; continue; };
{ gotoCase = 224; continue; };
}
}
case 226:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'h') {
if (yych == 'g') { gotoCase = 226; continue; };
} else {
if (yych <= 'i') { gotoCase = 226; continue; };
if (yych == 'm') { gotoCase = 226; continue; };
}
{ this.tokenType = "javascript-regexp"; return cursor; }
case 229:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 171; continue; };
{ gotoCase = 229; continue; };
} else {
if (yych <= '\r') { gotoCase = 171; continue; };
if (yych <= ')') { gotoCase = 229; continue; };
{ gotoCase = 203; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 226; continue; };
{ gotoCase = 229; continue; };
} else {
if (yych <= '[') { gotoCase = 224; continue; };
if (yych <= '\\') { gotoCase = 232; continue; };
{ gotoCase = 229; continue; };
}
}
case 231:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 171; continue; };
if (yych == '\r') { gotoCase = 171; continue; };
{ gotoCase = 224; continue; };
case 232:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 223; continue; };
if (yych == '\r') { gotoCase = 223; continue; };
{ gotoCase = 229; continue; };
case 233:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 223; continue; };
if (yych == '\r') { gotoCase = 223; continue; };
{ gotoCase = 203; continue; };
case 234:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 171; continue; };
{ gotoCase = 234; continue; };
} else {
if (yych <= '\r') { gotoCase = 171; continue; };
if (yych <= ')') { gotoCase = 234; continue; };
{ gotoCase = 171; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 171; continue; };
{ gotoCase = 234; continue; };
} else {
if (yych <= '\\') { gotoCase = 238; continue; };
if (yych >= '^') { gotoCase = 234; continue; };
}
}
case 236:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 171; continue; };
{ gotoCase = 236; continue; };
} else {
if (yych <= '\r') { gotoCase = 171; continue; };
if (yych <= ')') { gotoCase = 236; continue; };
{ gotoCase = 203; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 226; continue; };
{ gotoCase = 236; continue; };
} else {
if (yych <= '[') { gotoCase = 234; continue; };
if (yych <= '\\') { gotoCase = 239; continue; };
{ gotoCase = 236; continue; };
}
}
case 238:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 171; continue; };
if (yych == '\r') { gotoCase = 171; continue; };
{ gotoCase = 234; continue; };
case 239:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 223; continue; };
if (yych == '\r') { gotoCase = 223; continue; };
{ gotoCase = 236; continue; };
case 240:
yyaccept = 2;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 161; continue; };
if (yych <= '9') { gotoCase = 240; continue; };
{ gotoCase = 161; continue; };
} else {
if (yych <= 'E') { gotoCase = 242; continue; };
if (yych != 'e') { gotoCase = 161; continue; };
}
case 242:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 171; continue; };
} else {
if (yych <= '-') { gotoCase = 243; continue; };
if (yych <= '/') { gotoCase = 171; continue; };
if (yych <= '9') { gotoCase = 244; continue; };
{ gotoCase = 171; continue; };
}
case 243:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
case 244:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 161; continue; };
if (yych <= '9') { gotoCase = 244; continue; };
{ gotoCase = 161; continue; };
case 246:
++cursor;
yych = this._charAt(cursor);
case 247:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 171; continue; };
if (yych <= '\f') { gotoCase = 246; continue; };
{ gotoCase = 171; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 246; continue; };
{ gotoCase = 249; continue; };
} else {
if (yych != '\\') { gotoCase = 246; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 171; continue; };
{ gotoCase = 252; continue; };
} else {
if (yych == '\r') { gotoCase = 252; continue; };
{ gotoCase = 171; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 246; continue; };
if (yych <= '&') { gotoCase = 171; continue; };
{ gotoCase = 246; continue; };
} else {
if (yych == '\\') { gotoCase = 246; continue; };
{ gotoCase = 171; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 246; continue; };
if (yych <= 'e') { gotoCase = 171; continue; };
{ gotoCase = 246; continue; };
} else {
if (yych == 'n') { gotoCase = 246; continue; };
{ gotoCase = 171; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 171; continue; };
{ gotoCase = 246; continue; };
} else {
if (yych <= 'u') { gotoCase = 251; continue; };
if (yych <= 'v') { gotoCase = 246; continue; };
{ gotoCase = 171; continue; };
}
}
}
case 249:
++cursor;
{ this.tokenType = "javascript-string"; return cursor; }
case 251:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych <= '9') { gotoCase = 254; continue; };
{ gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 254; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych <= 'f') { gotoCase = 254; continue; };
{ gotoCase = 171; continue; };
}
case 252:
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 254:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 255; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 255:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 256; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 256:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych <= '9') { gotoCase = 246; continue; };
{ gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 246; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych <= 'f') { gotoCase = 246; continue; };
{ gotoCase = 171; continue; };
}
case 257:
++cursor;
yych = this._charAt(cursor);
case 258:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 171; continue; };
if (yych <= '\f') { gotoCase = 257; continue; };
{ gotoCase = 171; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 257; continue; };
{ gotoCase = 249; continue; };
} else {
if (yych != '\\') { gotoCase = 257; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 171; continue; };
{ gotoCase = 261; continue; };
} else {
if (yych == '\r') { gotoCase = 261; continue; };
{ gotoCase = 171; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 257; continue; };
if (yych <= '&') { gotoCase = 171; continue; };
{ gotoCase = 257; continue; };
} else {
if (yych == '\\') { gotoCase = 257; continue; };
{ gotoCase = 171; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 257; continue; };
if (yych <= 'e') { gotoCase = 171; continue; };
{ gotoCase = 257; continue; };
} else {
if (yych == 'n') { gotoCase = 257; continue; };
{ gotoCase = 171; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 171; continue; };
{ gotoCase = 257; continue; };
} else {
if (yych <= 'u') { gotoCase = 260; continue; };
if (yych <= 'v') { gotoCase = 257; continue; };
{ gotoCase = 171; continue; };
}
}
}
case 260:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych <= '9') { gotoCase = 263; continue; };
{ gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 263; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych <= 'f') { gotoCase = 263; continue; };
{ gotoCase = 171; continue; };
}
case 261:
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 263:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 264; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 264:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych >= ':') { gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 265; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych >= 'g') { gotoCase = 171; continue; };
}
case 265:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 171; continue; };
if (yych <= '9') { gotoCase = 257; continue; };
{ gotoCase = 171; continue; };
} else {
if (yych <= 'F') { gotoCase = 257; continue; };
if (yych <= '`') { gotoCase = 171; continue; };
if (yych <= 'f') { gotoCase = 257; continue; };
{ gotoCase = 171; continue; };
}
case 266:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 169; continue; };
{ gotoCase = 145; continue; };
case 267:
++cursor;
yych = this._charAt(cursor);
case 268:
if (yych == ' ') { gotoCase = 267; continue; };
{ gotoCase = 143; continue; };

case this.case_REGEX:
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 272; continue; };
{ gotoCase = 273; continue; };
} else {
if (yych == '\r') { gotoCase = 273; continue; };
{ gotoCase = 272; continue; };
}
} else {
if (yych <= '[') {
if (yych <= '/') { gotoCase = 275; continue; };
if (yych <= 'Z') { gotoCase = 272; continue; };
{ gotoCase = 277; continue; };
} else {
if (yych <= '\\') { gotoCase = 278; continue; };
if (yych <= ']') { gotoCase = 273; continue; };
{ gotoCase = 272; continue; };
}
}
case 271:
{ this.tokenType = "javascript-regexp"; return cursor; }
case 272:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 280; continue; };
case 273:
++cursor;
case 274:
{ this.tokenType = null; return cursor; }
case 275:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 286; continue; };
case 276:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-regexp"; return cursor; }
case 277:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 274; continue; };
if (yych <= '\f') { gotoCase = 284; continue; };
{ gotoCase = 274; continue; };
} else {
if (yych <= '*') {
if (yych <= ')') { gotoCase = 284; continue; };
{ gotoCase = 274; continue; };
} else {
if (yych == '/') { gotoCase = 274; continue; };
{ gotoCase = 284; continue; };
}
}
case 278:
yych = this._charAt(++cursor);
if (yych == '\n') { gotoCase = 274; continue; };
if (yych == '\r') { gotoCase = 274; continue; };
case 279:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 280:
if (yych <= '.') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 279; continue; };
{ gotoCase = 271; continue; };
} else {
if (yych == '\r') { gotoCase = 271; continue; };
{ gotoCase = 279; continue; };
}
} else {
if (yych <= '[') {
if (yych <= '/') { gotoCase = 285; continue; };
if (yych <= 'Z') { gotoCase = 279; continue; };
{ gotoCase = 283; continue; };
} else {
if (yych <= '\\') { gotoCase = 281; continue; };
if (yych <= ']') { gotoCase = 271; continue; };
{ gotoCase = 279; continue; };
}
}
case 281:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 282; continue; };
if (yych != '\r') { gotoCase = 279; continue; };
case 282:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 271; continue; };
} else {
{ gotoCase = 274; continue; };
}
case 283:
++cursor;
yych = this._charAt(cursor);
case 284:
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 282; continue; };
{ gotoCase = 283; continue; };
} else {
if (yych <= '\r') { gotoCase = 282; continue; };
if (yych <= ')') { gotoCase = 283; continue; };
{ gotoCase = 282; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 282; continue; };
{ gotoCase = 283; continue; };
} else {
if (yych <= '\\') { gotoCase = 289; continue; };
if (yych <= ']') { gotoCase = 287; continue; };
{ gotoCase = 283; continue; };
}
}
case 285:
++cursor;
yych = this._charAt(cursor);
case 286:
if (yych <= 'h') {
if (yych == 'g') { gotoCase = 285; continue; };
{ gotoCase = 276; continue; };
} else {
if (yych <= 'i') { gotoCase = 285; continue; };
if (yych == 'm') { gotoCase = 285; continue; };
{ gotoCase = 276; continue; };
}
case 287:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 271; continue; };
{ gotoCase = 287; continue; };
} else {
if (yych <= '\r') { gotoCase = 271; continue; };
if (yych <= ')') { gotoCase = 287; continue; };
{ gotoCase = 279; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 285; continue; };
{ gotoCase = 287; continue; };
} else {
if (yych <= '[') { gotoCase = 283; continue; };
if (yych <= '\\') { gotoCase = 290; continue; };
{ gotoCase = 287; continue; };
}
}
case 289:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 282; continue; };
if (yych == '\r') { gotoCase = 282; continue; };
{ gotoCase = 283; continue; };
case 290:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 282; continue; };
if (yych == '\r') { gotoCase = 282; continue; };
{ gotoCase = 287; continue; };

case this.case_SSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 295; continue; };
if (yych <= '\f') { gotoCase = 294; continue; };
{ gotoCase = 295; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 294; continue; };
{ gotoCase = 297; continue; };
} else {
if (yych == '\\') { gotoCase = 299; continue; };
{ gotoCase = 294; continue; };
}
}
case 293:
{ this.tokenType = "javascript-string"; return cursor; }
case 294:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 301; continue; };
case 295:
++cursor;
case 296:
{ this.tokenType = null; return cursor; }
case 297:
++cursor;
case 298:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-string"; return cursor; }
case 299:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 300; continue; };
if (yych <= '&') { gotoCase = 296; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 296; continue; };
} else {
if (yych != 'b') { gotoCase = 296; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 296; continue; };
} else {
if (yych <= 'n') { gotoCase = 300; continue; };
if (yych <= 'q') { gotoCase = 296; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 296; continue; };
} else {
if (yych <= 'u') { gotoCase = 302; continue; };
if (yych >= 'w') { gotoCase = 296; continue; };
}
}
}
case 300:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 301:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 293; continue; };
if (yych <= '\f') { gotoCase = 300; continue; };
{ gotoCase = 293; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 300; continue; };
{ gotoCase = 308; continue; };
} else {
if (yych == '\\') { gotoCase = 307; continue; };
{ gotoCase = 300; continue; };
}
}
case 302:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 303; continue; };
if (yych <= '9') { gotoCase = 304; continue; };
} else {
if (yych <= 'F') { gotoCase = 304; continue; };
if (yych <= '`') { gotoCase = 303; continue; };
if (yych <= 'f') { gotoCase = 304; continue; };
}
case 303:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 293; continue; };
} else {
{ gotoCase = 296; continue; };
}
case 304:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 303; continue; };
if (yych >= ':') { gotoCase = 303; continue; };
} else {
if (yych <= 'F') { gotoCase = 305; continue; };
if (yych <= '`') { gotoCase = 303; continue; };
if (yych >= 'g') { gotoCase = 303; continue; };
}
case 305:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 303; continue; };
if (yych >= ':') { gotoCase = 303; continue; };
} else {
if (yych <= 'F') { gotoCase = 306; continue; };
if (yych <= '`') { gotoCase = 303; continue; };
if (yych >= 'g') { gotoCase = 303; continue; };
}
case 306:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 303; continue; };
if (yych <= '9') { gotoCase = 300; continue; };
{ gotoCase = 303; continue; };
} else {
if (yych <= 'F') { gotoCase = 300; continue; };
if (yych <= '`') { gotoCase = 303; continue; };
if (yych <= 'f') { gotoCase = 300; continue; };
{ gotoCase = 303; continue; };
}
case 307:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 300; continue; };
if (yych <= '&') { gotoCase = 303; continue; };
{ gotoCase = 300; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 303; continue; };
{ gotoCase = 300; continue; };
} else {
if (yych == 'b') { gotoCase = 300; continue; };
{ gotoCase = 303; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 300; continue; };
{ gotoCase = 303; continue; };
} else {
if (yych <= 'n') { gotoCase = 300; continue; };
if (yych <= 'q') { gotoCase = 303; continue; };
{ gotoCase = 300; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 303; continue; };
{ gotoCase = 300; continue; };
} else {
if (yych <= 'u') { gotoCase = 302; continue; };
if (yych <= 'v') { gotoCase = 300; continue; };
{ gotoCase = 303; continue; };
}
}
}
case 308:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 298; continue; };
}

}
},

__proto__: WebInspector.SourceTokenizer.prototype
}






WebInspector.FileSystemModel = function()
{
WebInspector.Object.call(this);

this._fileSystemsForOrigin = {};

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);

FileSystemAgent.enable();

this._reset();
}

WebInspector.FileSystemModel.prototype = {
_reset: function()
{
for (var securityOrigin in this._fileSystemsForOrigin)
this._removeOrigin(securityOrigin);
var securityOrigins = WebInspector.resourceTreeModel.securityOrigins();
for (var i = 0; i < securityOrigins.length; ++i)
this._addOrigin(securityOrigins[i]);
},


_securityOriginAdded: function(event)
{
var securityOrigin =   (event.data);
this._addOrigin(securityOrigin);
},


_securityOriginRemoved: function(event)
{
var securityOrigin =   (event.data);
this._removeOrigin(securityOrigin);
},


_addOrigin: function(securityOrigin)
{
this._fileSystemsForOrigin[securityOrigin] = {};

var types = ["persistent", "temporary"];
for (var i = 0; i < types.length; ++i)
this._requestFileSystemRoot(securityOrigin, types[i], this._fileSystemRootReceived.bind(this, securityOrigin, types[i], this._fileSystemsForOrigin[securityOrigin]));
},


_removeOrigin: function(securityOrigin)
{
for (var type in this._fileSystemsForOrigin[securityOrigin]) {
var fileSystem = this._fileSystemsForOrigin[securityOrigin][type];
delete this._fileSystemsForOrigin[securityOrigin][type];
this._fileSystemRemoved(fileSystem);
}
delete this._fileSystemsForOrigin[securityOrigin];
},


_requestFileSystemRoot: function(origin, type, callback)
{

function innerCallback(error, errorCode, backendRootEntry)
{
if (error) {
callback(FileError.SECURITY_ERR);
return;
}

callback(errorCode, backendRootEntry);
}

FileSystemAgent.requestFileSystemRoot(origin, type, innerCallback.bind(this));
},


_fileSystemAdded: function(fileSystem)
{
this.dispatchEventToListeners(WebInspector.FileSystemModel.EventTypes.FileSystemAdded, fileSystem);
},


_fileSystemRemoved: function(fileSystem)
{
this.dispatchEventToListeners(WebInspector.FileSystemModel.EventTypes.FileSystemRemoved, fileSystem);
},

refreshFileSystemList: function()
{
this._reset();
},


_fileSystemRootReceived: function(origin, type, store, errorCode, backendRootEntry)
{
if (!errorCode && backendRootEntry && this._fileSystemsForOrigin[origin] === store) {
var fileSystem = new WebInspector.FileSystemModel.FileSystem(this, origin, type, backendRootEntry);
store[type] = fileSystem;
this._fileSystemAdded(fileSystem);
}
},


requestDirectoryContent: function(directory, callback)
{
this._requestDirectoryContent(directory.url, this._directoryContentReceived.bind(this, directory, callback));
},


_requestDirectoryContent: function(url, callback)
{

function innerCallback(error, errorCode, backendEntries)
{
if (error) {
callback(FileError.SECURITY_ERR);
return;
}

if (errorCode !== 0) {
callback(errorCode, null);
return;
}

callback(errorCode, backendEntries);
}

FileSystemAgent.requestDirectoryContent(url, innerCallback.bind(this));
},


_directoryContentReceived: function(parentDirectory, callback, errorCode, backendEntries)
{
var entries = [];
for (var i = 0; i < backendEntries.length; ++i) {
if (backendEntries[i].isDirectory)
entries.push(new WebInspector.FileSystemModel.Directory(this, parentDirectory.fileSystem, backendEntries[i]));
else
entries.push(new WebInspector.FileSystemModel.File(this, parentDirectory.fileSystem, backendEntries[i]));
}

callback(errorCode, entries);
},


requestMetadata: function(entry, callback)
{

function innerCallback(error, errorCode, metadata)
{
if (error) {
callback(FileError.SECURITY_ERR);
return;
}

callback(errorCode, metadata);
}

FileSystemAgent.requestMetadata(entry.url, innerCallback.bind(this));
},


requestFileContent: function(file, readAsText, start, end, charset, callback)
{
this._requestFileContent(file.url, readAsText, start, end, charset, callback);
},


_requestFileContent: function(url, readAsText, start, end, charset, callback)
{

function innerCallback(error, errorCode, content, charset)
{
if (error) {
if (callback)
callback(FileError.SECURITY_ERR);
return;
}

if (callback)
callback(errorCode, content, charset);
}

FileSystemAgent.requestFileContent(url, readAsText, start, end, charset, innerCallback.bind(this));
},

deleteEntry: function(entry, callback)
{
var fileSystemModel = this;
if (entry === entry.fileSystem.root)
this._deleteEntry(entry.url, hookFileSystemDeletion);
else
this._deleteEntry(entry.url, callback);

function hookFileSystemDeletion(errorCode)
{
callback(errorCode);
if (!errorCode)
fileSystemModel._removeFileSystem(entry.fileSystem);
}
},


_deleteEntry: function(url, callback)
{

function innerCallback(error, errorCode)
{
if (error) {
if (callback)
callback(FileError.SECURITY_ERR);
return;
}

if (callback)
callback(errorCode);
}

FileSystemAgent.deleteEntry(url, innerCallback.bind(this));
},


_removeFileSystem: function(fileSystem)
{
var origin = fileSystem.origin;
var type = fileSystem.type;
if (this._fileSystemsForOrigin[origin] && this._fileSystemsForOrigin[origin][type]) {
delete this._fileSystemsForOrigin[origin][type];
this._fileSystemRemoved(fileSystem);

if (Object.isEmpty(this._fileSystemsForOrigin[origin]))
delete this._fileSystemsForOrigin[origin];
}
},

__proto__: WebInspector.Object.prototype
}


WebInspector.FileSystemModel.EventTypes = {
FileSystemAdded: "FileSystemAdded",
FileSystemRemoved: "FileSystemRemoved"
}


WebInspector.FileSystemModel.FileSystem = function(fileSystemModel, origin, type, backendRootEntry)
{
this.origin = origin;
this.type = type;

this.root = new WebInspector.FileSystemModel.Directory(fileSystemModel, this, backendRootEntry);
}

WebInspector.FileSystemModel.FileSystem.prototype = {

get name()
{
return "filesystem:" + this.origin + "/" + this.type;
}
}


WebInspector.FileSystemModel.Entry = function(fileSystemModel, fileSystem, backendEntry)
{
this._fileSystemModel = fileSystemModel;
this._fileSystem = fileSystem;

this._url = backendEntry.url;
this._name = backendEntry.name;
this._isDirectory = backendEntry.isDirectory;
}


WebInspector.FileSystemModel.Entry.compare = function(x, y)
{
if (x.isDirectory != y.isDirectory)
return y.isDirectory ? 1 : -1;
return x.name.compareTo(y.name);
}

WebInspector.FileSystemModel.Entry.prototype = {

get fileSystemModel()
{
return this._fileSystemModel;
},


get fileSystem()
{
return this._fileSystem;
},


get url()
{
return this._url;
},


get name()
{
return this._name;
},


get isDirectory()
{
return this._isDirectory;
},


requestMetadata: function(callback)
{
this.fileSystemModel.requestMetadata(this, callback);
},


deleteEntry: function(callback)
{
this.fileSystemModel.deleteEntry(this, callback);
}
}


WebInspector.FileSystemModel.Directory = function(fileSystemModel, fileSystem, backendEntry)
{
WebInspector.FileSystemModel.Entry.call(this, fileSystemModel, fileSystem, backendEntry);
}

WebInspector.FileSystemModel.Directory.prototype = {

requestDirectoryContent: function(callback)
{
this.fileSystemModel.requestDirectoryContent(this, callback);
},

__proto__: WebInspector.FileSystemModel.Entry.prototype
}


WebInspector.FileSystemModel.File = function(fileSystemModel, fileSystem, backendEntry)
{
WebInspector.FileSystemModel.Entry.call(this, fileSystemModel, fileSystem, backendEntry);

this._mimeType = backendEntry.mimeType;
this._resourceType = WebInspector.resourceTypes[backendEntry.resourceType];
this._isTextFile = backendEntry.isTextFile;
}

WebInspector.FileSystemModel.File.prototype = {

get mimeType()
{
return this._mimeType;
},


get resourceType()
{
return this._resourceType;
},


get isTextFile()
{
return this._isTextFile;
},


requestFileContent: function(readAsText, start, end, charset, callback)
{
this.fileSystemModel.requestFileContent(this, readAsText, start, end, charset, callback);
},

__proto__: WebInspector.FileSystemModel.Entry.prototype
}






WebInspector.OutputStreamDelegate = function()
{
}

WebInspector.OutputStreamDelegate.prototype = {
onTransferStarted: function() { },

onTransferFinished: function() { },


onChunkTransferred: function(reader) { },


onError: function(reader, event) { },
}


WebInspector.OutputStream = function()
{
}

WebInspector.OutputStream.prototype = {

write: function(data, callback) { },

close: function() { }
}


WebInspector.ChunkedReader = function()
{
}

WebInspector.ChunkedReader.prototype = {

fileSize: function() { },


loadedSize: function() { },


fileName: function() { },

cancel: function() { }
}


WebInspector.ChunkedFileReader = function(file, chunkSize, delegate)
{
this._file = file;
this._fileSize = file.size;
this._loadedSize = 0;
this._chunkSize = chunkSize;
this._delegate = delegate;
this._isCanceled = false;
}

WebInspector.ChunkedFileReader.prototype = {

start: function(output)
{
this._output = output;

this._reader = new FileReader();
this._reader.onload = this._onChunkLoaded.bind(this);
this._reader.onerror = this._delegate.onError.bind(this._delegate, this);
this._delegate.onTransferStarted();
this._loadChunk();
},

cancel: function()
{
this._isCanceled = true;
},


loadedSize: function()
{
return this._loadedSize;
},


fileSize: function()
{
return this._fileSize;
},


fileName: function()
{
return this._file.name;
},


_onChunkLoaded: function(event)
{
if (this._isCanceled)
return;

if (event.target.readyState !== FileReader.DONE)
return;

var data = event.target.result;
this._loadedSize += data.length;

this._output.write(data);
if (this._isCanceled)
return;
this._delegate.onChunkTransferred(this);

if (this._loadedSize === this._fileSize) {
this._file = null;
this._reader = null;
this._output.close();
this._delegate.onTransferFinished();
return;
}

this._loadChunk();
},

_loadChunk: function()
{
var chunkStart = this._loadedSize;
var chunkEnd = Math.min(this._fileSize, chunkStart + this._chunkSize)
var nextPart = this._file.slice(chunkStart, chunkEnd);
this._reader.readAsText(nextPart);
}
}


WebInspector.ChunkedXHRReader = function(url, delegate)
{
this._url = url;
this._delegate = delegate;
this._fileSize = 0;
this._loadedSize = 0;
this._isCanceled = false;
}

WebInspector.ChunkedXHRReader.prototype = {

start: function(output)
{
this._output = output;

this._xhr = new XMLHttpRequest();
this._xhr.open("GET", this._url, true);
this._xhr.onload = this._onLoad.bind(this);
this._xhr.onprogress = this._onProgress.bind(this);
this._xhr.onerror = this._delegate.onError.bind(this._delegate, this);
this._xhr.send(null);

this._delegate.onTransferStarted();
},

cancel: function()
{
this._isCanceled = true;
this._xhr.abort();
},


loadedSize: function()
{
return this._loadedSize;
},


fileSize: function()
{
return this._fileSize;
},


fileName: function()
{
return this._url;
},


_onProgress: function(event)
{
if (this._isCanceled)
return;

if (event.lengthComputable)
this._fileSize = event.total;

var data = this._xhr.responseText.substring(this._loadedSize);
if (!data.length)
return;

this._loadedSize += data.length;
this._output.write(data);
if (this._isCanceled)
return;
this._delegate.onChunkTransferred(this);
},


_onLoad: function(event)
{
this._onProgress(event);

if (this._isCanceled)
return;

this._output.close();
this._delegate.onTransferFinished();
}
}


WebInspector.createFileSelectorElement = function(callback) {
var fileSelectorElement = document.createElement("input");
fileSelectorElement.type = "file";
fileSelectorElement.style.display = "none";
fileSelectorElement.setAttribute("tabindex", -1);
fileSelectorElement.onchange = onChange;
function onChange(event)
{
callback(fileSelectorElement.files[0]);
};
return fileSelectorElement;
}


WebInspector.findBalancedCurlyBrackets = function(source, startIndex, lastIndex) {
lastIndex = lastIndex || source.length;
startIndex = startIndex || 0;
var counter = 0;
var inString = false;

for (var index = startIndex; index < lastIndex; ++index) {
var character = source[index];
if (inString) {
if (character === "\\")
++index;
else if (character === "\"")
inString = false;
} else {
if (character === "\"")
inString = true;
else if (character === "{")
++counter;
else if (character === "}") {
if (--counter === 0)
return index + 1;
}
}
}
return -1;
}


WebInspector.FileOutputStream = function()
{
}

WebInspector.FileOutputStream.prototype = {

open: function(fileName, callback)
{
this._closed = false;
this._writeCallbacks = [];
this._fileName = fileName;
function callbackWrapper()
{
WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.SavedURL, callbackWrapper, this);
WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.AppendedToURL, this._onAppendDone, this);
callback(this);
}
WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.SavedURL, callbackWrapper, this);
WebInspector.fileManager.save(this._fileName, "", true);
},


write: function(data, callback)
{
this._writeCallbacks.push(callback);
WebInspector.fileManager.append(this._fileName, data);
},

close: function()
{
this._closed = true;
if (this._writeCallbacks.length)
return;
WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.AppendedToURL, this._onAppendDone, this);
WebInspector.fileManager.close(this._fileName);
},


_onAppendDone: function(event)
{
if (event.data !== this._fileName)
return;
if (!this._writeCallbacks.length) {
if (this._closed) {
WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.AppendedToURL, this._onAppendDone, this);
WebInspector.fileManager.close(this._fileName);
}
return;
}
var callback = this._writeCallbacks.shift();
if (callback)
callback(this);
}
}






WebInspector.DebuggerModel = function()
{
InspectorBackend.registerDebuggerDispatcher(new WebInspector.DebuggerDispatcher(this));

this._debuggerPausedDetails = null;

this._scripts = {};
this._scriptsBySourceURL = {};

this._canSetScriptSource = false;
this._breakpointsActive = true;

WebInspector.settings.pauseOnExceptionStateString = WebInspector.settings.createSetting("pauseOnExceptionStateString", WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions);
WebInspector.settings.pauseOnExceptionStateString.addChangeListener(this._pauseOnExceptionStateChanged, this);

this.enableDebugger();
}


WebInspector.DebuggerModel.PauseOnExceptionsState = {
DontPauseOnExceptions : "none",
PauseOnAllExceptions : "all",
PauseOnUncaughtExceptions: "uncaught"
};


WebInspector.DebuggerModel.Location = function(scriptId, lineNumber, columnNumber)
{
this.scriptId = scriptId;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
}

WebInspector.DebuggerModel.Events = {
DebuggerWasEnabled: "DebuggerWasEnabled",
DebuggerWasDisabled: "DebuggerWasDisabled",
DebuggerPaused: "DebuggerPaused",
DebuggerResumed: "DebuggerResumed",
ParsedScriptSource: "ParsedScriptSource",
FailedToParseScriptSource: "FailedToParseScriptSource",
BreakpointResolved: "BreakpointResolved",
GlobalObjectCleared: "GlobalObjectCleared",
CallFrameSelected: "CallFrameSelected",
ExecutionLineChanged: "ExecutionLineChanged",
ConsoleCommandEvaluatedInSelectedCallFrame: "ConsoleCommandEvaluatedInSelectedCallFrame",
BreakpointsActiveStateChanged: "BreakpointsActiveStateChanged"
}

WebInspector.DebuggerModel.BreakReason = {
DOM: "DOM",
EventListener: "EventListener",
XHR: "XHR",
Exception: "exception",
Assert: "assert",
CSPViolation: "CSPViolation"
}

WebInspector.DebuggerModel.prototype = {

debuggerEnabled: function()
{
return !!this._debuggerEnabled;
},

enableDebugger: function()
{
if (this._debuggerEnabled)
return;

function callback(error, result)
{
this._canSetScriptSource = result;
}
DebuggerAgent.canSetScriptSource(callback.bind(this));
DebuggerAgent.enable(this._debuggerWasEnabled.bind(this));
},

disableDebugger: function()
{
if (!this._debuggerEnabled)
return;

DebuggerAgent.disable(this._debuggerWasDisabled.bind(this));
},


canSetScriptSource: function()
{
return this._canSetScriptSource;
},

_debuggerWasEnabled: function()
{
this._debuggerEnabled = true;
this._pauseOnExceptionStateChanged();
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasEnabled);
},

_pauseOnExceptionStateChanged: function()
{
DebuggerAgent.setPauseOnExceptions(WebInspector.settings.pauseOnExceptionStateString.get());
},

_debuggerWasDisabled: function()
{
this._debuggerEnabled = false;
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasDisabled);
},


continueToLocation: function(rawLocation)
{
DebuggerAgent.continueToLocation(rawLocation);
},


setBreakpointByScriptLocation: function(rawLocation, condition, callback)
{
var script = this.scriptForId(rawLocation.scriptId);
if (script.sourceURL)
this.setBreakpointByURL(script.sourceURL, rawLocation.lineNumber, rawLocation.columnNumber, condition, callback);
else
this.setBreakpointBySourceId(rawLocation, condition, callback);
},


setBreakpointByURL: function(url, lineNumber, columnNumber, condition, callback)
{

var minColumnNumber = 0;
var scripts = this._scriptsBySourceURL[url] || [];
for (var i = 0, l = scripts.length; i < l; ++i) {
var script = scripts[i];
if (lineNumber === script.lineOffset)
minColumnNumber = minColumnNumber ? Math.min(minColumnNumber, script.columnOffset) : script.columnOffset;
}
columnNumber = Math.max(columnNumber, minColumnNumber);


function didSetBreakpoint(error, breakpointId, locations)
{
if (callback) {
var rawLocations =   (locations);
callback(error ? null : breakpointId, rawLocations);
}
}
DebuggerAgent.setBreakpointByUrl(lineNumber, url, undefined, columnNumber, condition, didSetBreakpoint.bind(this));
WebInspector.userMetrics.ScriptsBreakpointSet.record();
},


setBreakpointBySourceId: function(rawLocation, condition, callback)
{

function didSetBreakpoint(error, breakpointId, actualLocation)
{
if (callback) {
var rawLocation =   (actualLocation);
callback(error ? null : breakpointId, [rawLocation]);
}
}
DebuggerAgent.setBreakpoint(rawLocation, condition, didSetBreakpoint.bind(this));
WebInspector.userMetrics.ScriptsBreakpointSet.record();
},


removeBreakpoint: function(breakpointId, callback)
{
DebuggerAgent.removeBreakpoint(breakpointId, callback);
},


_breakpointResolved: function(breakpointId, location)
{
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, {breakpointId: breakpointId, location: location});
},

_globalObjectCleared: function()
{
this._setDebuggerPausedDetails(null);
this._reset();
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.GlobalObjectCleared);
},

_reset: function()
{
this._scripts = {};
this._scriptsBySourceURL = {};
},


get scripts()
{
return this._scripts;
},


scriptForId: function(scriptId)
{
return this._scripts[scriptId] || null;
},


setScriptSource: function(scriptId, newSource, callback)
{
this._scripts[scriptId].editSource(newSource, this._didEditScriptSource.bind(this, scriptId, newSource, callback));
},


_didEditScriptSource: function(scriptId, newSource, callback, error, callFrames)
{
callback(error);
if (!error && callFrames && callFrames.length)
this._pausedScript(callFrames, this._debuggerPausedDetails.reason, this._debuggerPausedDetails.auxData);
},


get callFrames()
{
return this._debuggerPausedDetails ? this._debuggerPausedDetails.callFrames : null;
},


debuggerPausedDetails: function()
{
return this._debuggerPausedDetails;
},


_setDebuggerPausedDetails: function(debuggerPausedDetails)
{
if (this._debuggerPausedDetails)
this._debuggerPausedDetails.dispose();
this._debuggerPausedDetails = debuggerPausedDetails;
if (this._debuggerPausedDetails)
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPausedDetails);
if (debuggerPausedDetails) {
this.setSelectedCallFrame(debuggerPausedDetails.callFrames[0]);
DebuggerAgent.setOverlayMessage(WebInspector.UIString("Paused in debugger"));
} else {
this.setSelectedCallFrame(null);
DebuggerAgent.setOverlayMessage();
}
},


_pausedScript: function(callFrames, reason, auxData)
{
this._setDebuggerPausedDetails(new WebInspector.DebuggerPausedDetails(this, callFrames, reason, auxData));
},

_resumedScript: function()
{
this._setDebuggerPausedDetails(null);
if (this._executionLineLiveLocation)
this._executionLineLiveLocation.dispose();
this._executionLineLiveLocation = null;
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed);
},


_parsedScriptSource: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL, hasSourceURL)
{
var script = new WebInspector.Script(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL, hasSourceURL);
if (!script.isAnonymousScript() && !script.isInlineScript()) {
var existingScripts = this._scriptsBySourceURL[script.sourceURL] || [];
for (var i = 0; i < existingScripts.length; ++i) {
if (existingScripts[i].isInlineScript()) {
script.setIsDynamicScript(true); 
break;
}
}
}
this._registerScript(script);
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, script);
},


_registerScript: function(script)
{
this._scripts[script.scriptId] = script;
if (script.sourceURL) {
var scripts = this._scriptsBySourceURL[script.sourceURL];
if (!scripts) {
scripts = [];
this._scriptsBySourceURL[script.sourceURL] = scripts;
}
scripts.push(script);
}
},


createRawLocation: function(script, lineNumber, columnNumber)
{
if (script.sourceURL)
return this.createRawLocationByURL(script.sourceURL, lineNumber, columnNumber)
return new WebInspector.DebuggerModel.Location(script.scriptId, lineNumber, columnNumber);
},


createRawLocationByURL: function(sourceURL, lineNumber, columnNumber)
{
var closestScript = null;
var scripts = this._scriptsBySourceURL[sourceURL] || [];
for (var i = 0, l = scripts.length; i < l; ++i) {
var script = scripts[i];
if (!closestScript)
closestScript = script;
if (script.lineOffset > lineNumber || (script.lineOffset === lineNumber && script.columnOffset > columnNumber))
continue;
if (script.endLine < lineNumber || (script.endLine === lineNumber && script.endColumn <= columnNumber))
continue;
closestScript = script;
break;
}
return closestScript ? new WebInspector.DebuggerModel.Location(closestScript.scriptId, lineNumber, columnNumber) : null;
},


isPaused: function()
{
return !!this.debuggerPausedDetails();
},


setSelectedCallFrame: function(callFrame)
{
if (this._executionLineLiveLocation)
this._executionLineLiveLocation.dispose();
delete this._executionLineLiveLocation;

this._selectedCallFrame = callFrame;
if (!this._selectedCallFrame)
return;

this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.CallFrameSelected, callFrame);

function updateExecutionLine(uiLocation)
{
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ExecutionLineChanged, uiLocation);
}
this._executionLineLiveLocation = callFrame.script.createLiveLocation(callFrame.location, updateExecutionLine.bind(this));
},


selectedCallFrame: function()
{
return this._selectedCallFrame;
},


evaluateOnSelectedCallFrame: function(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback)
{

function didEvaluate(result, wasThrown)
{
if (returnByValue)
callback(null, !!wasThrown, wasThrown ? null : result);
else
callback(WebInspector.RemoteObject.fromPayload(result), !!wasThrown);

if (objectGroup === "console")
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame);
}

this.selectedCallFrame().evaluate(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, didEvaluate.bind(this));
},


getSelectedCallFrameVariables: function(callback)
{
var result = { this: true };

var selectedCallFrame = this._selectedCallFrame;
if (!selectedCallFrame)
callback(result);

var pendingRequests = 0;

function propertiesCollected(properties)
{
for (var i = 0; properties && i < properties.length; ++i)
result[properties[i].name] = true;
if (--pendingRequests == 0)
callback(result);
}

for (var i = 0; i < selectedCallFrame.scopeChain.length; ++i) {
var scope = selectedCallFrame.scopeChain[i];
var object = WebInspector.RemoteObject.fromPayload(scope.object);
pendingRequests++;
object.getAllProperties(propertiesCollected);
}
},


setBreakpointsActive: function(active)
{
if (this._breakpointsActive === active)
return;
this._breakpointsActive = active;
DebuggerAgent.setBreakpointsActive(active);
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, active);
},


breakpointsActive: function()
{
return this._breakpointsActive;
},


createLiveLocation: function(rawLocation, updateDelegate)
{
var script = this._scripts[rawLocation.scriptId];
return script.createLiveLocation(rawLocation, updateDelegate);
},


rawLocationToUILocation: function(rawLocation)
{
var script = this._scripts[rawLocation.scriptId];
if (!script)
return null;
return script.rawLocationToUILocation(rawLocation.lineNumber, rawLocation.columnNumber);
},


callStackModified: function(newCallFrames, details)
{

if (details && details["stack_update_needs_step_in"])
DebuggerAgent.stepInto();
else {
if (newCallFrames && newCallFrames.length)
this._pausedScript(newCallFrames, this._debuggerPausedDetails.reason, this._debuggerPausedDetails.auxData);

}
},

__proto__: WebInspector.Object.prototype
}

WebInspector.DebuggerEventTypes = {
JavaScriptPause: 0,
JavaScriptBreakpoint: 1,
NativeBreakpoint: 2
};


WebInspector.DebuggerDispatcher = function(debuggerModel)
{
this._debuggerModel = debuggerModel;
}

WebInspector.DebuggerDispatcher.prototype = {

paused: function(callFrames, reason, auxData)
{
this._debuggerModel._pausedScript(callFrames, reason, auxData);
},

resumed: function()
{
this._debuggerModel._resumedScript();
},

globalObjectCleared: function()
{
this._debuggerModel._globalObjectCleared();
},


scriptParsed: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL, hasSourceURL)
{
this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, !!isContentScript, sourceMapURL, hasSourceURL);
},


scriptFailedToParse: function(sourceURL, source, startingLine, errorLine, errorMessage)
{
},


breakpointResolved: function(breakpointId, location)
{
this._debuggerModel._breakpointResolved(breakpointId, location);
}
}


WebInspector.DebuggerModel.CallFrame = function(script, payload)
{
this._script = script;
this._payload = payload;
this._locations = [];
}

WebInspector.DebuggerModel.CallFrame.prototype = {

get script()
{
return this._script;
},


get type()
{
return this._payload.type;
},


get id()
{
return this._payload.callFrameId;
},


get scopeChain()
{
return this._payload.scopeChain;
},


get this()
{
return this._payload.this;
},


get functionName()
{
return this._payload.functionName;
},


get location()
{
var rawLocation =   (this._payload.location);
return rawLocation;
},


evaluate: function(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback)
{

function didEvaluateOnCallFrame(error, result, wasThrown)
{
if (error) {
console.error(error);
callback(null, false);
return;
}
callback(result, wasThrown);
}
DebuggerAgent.evaluateOnCallFrame(this._payload.callFrameId, code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, didEvaluateOnCallFrame.bind(this));
},


restart: function(callback)
{

function protocolCallback(error, callFrames, details)
{
if (!error)
WebInspector.debuggerModel.callStackModified(callFrames, details);
if (callback)
callback(error);
}
DebuggerAgent.restartFrame(this._payload.callFrameId, protocolCallback);
},


createLiveLocation: function(updateDelegate)
{
var location = this._script.createLiveLocation(this.location, updateDelegate);
this._locations.push(location);
return location;
},

dispose: function(updateDelegate)
{
for (var i = 0; i < this._locations.length; ++i)
this._locations[i].dispose();
this._locations = [];
}
}


WebInspector.DebuggerPausedDetails = function(model, callFrames, reason, auxData)
{
this.callFrames = [];
for (var i = 0; i < callFrames.length; ++i) {
var callFrame = callFrames[i];
var script = model.scriptForId(callFrame.location.scriptId);
if (script)
this.callFrames.push(new WebInspector.DebuggerModel.CallFrame(script, callFrame));
}
this.reason = reason;
this.auxData = auxData;
}

WebInspector.DebuggerPausedDetails.prototype = {
dispose: function()
{
for (var i = 0; i < this.callFrames.length; ++i) {
var callFrame = this.callFrames[i];
callFrame.dispose();
}
}
}


WebInspector.debuggerModel = null;






WebInspector.SourceMap = function(sourceMappingURL, payload)
{
if (!WebInspector.SourceMap.prototype._base64Map) {
const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
WebInspector.SourceMap.prototype._base64Map = {};
for (var i = 0; i < base64Digits.length; ++i)
WebInspector.SourceMap.prototype._base64Map[base64Digits.charAt(i)] = i;
}

this._sourceMappingURL = sourceMappingURL;
this._reverseMappingsBySourceURL = {};
this._mappings = [];
this._sources = {};
this._sourceContentByURL = {};
this._parseMappingPayload(payload);
}


WebInspector.SourceMap.load = function(sourceMapURL, compiledURL)
{
try {

var response = InspectorFrontendHost.loadResourceSynchronously(sourceMapURL);
if (!response)
return null;
if (response.slice(0, 3) === ")]}")
response = response.substring(response.indexOf('\n'));
var payload =   (JSON.parse(response));
var baseURL = sourceMapURL.startsWith("data:") ? compiledURL : sourceMapURL;
return new WebInspector.SourceMap(baseURL, payload);
} catch(e) {
console.error(e.message);
return null;
}
}

WebInspector.SourceMap.prototype = {

sources: function()
{
return Object.keys(this._sources);
},


sourceContent: function(sourceURL)
{
return this._sourceContentByURL[sourceURL];
},


_parseMappingPayload: function(mappingPayload)
{
if (mappingPayload.sections)
this._parseSections(mappingPayload.sections);
else
this._parseMap(mappingPayload, 0, 0);
},


_parseSections: function(sections)
{
for (var i = 0; i < sections.length; ++i) {
var section = sections[i];
this._parseMap(section.map, section.offset.line, section.offset.column);
}
},


findEntry: function(lineNumber, columnNumber)
{
var first = 0;
var count = this._mappings.length;
while (count > 1) {
var step = count >> 1;
var middle = first + step;
var mapping = this._mappings[middle];
if (lineNumber < mapping[0] || (lineNumber === mapping[0] && columnNumber < mapping[1]))
count = step;
else {
first = middle;
count -= step;
}
}
var entry = this._mappings[first];
if (!first && entry && (lineNumber < entry[0] || (lineNumber === entry[0] && columnNumber < entry[1])))
return null;
return entry;
},


findEntryReversed: function(sourceURL, lineNumber)
{
var mappings = this._reverseMappingsBySourceURL[sourceURL];
for ( ; lineNumber < mappings.length; ++lineNumber) {
var mapping = mappings[lineNumber];
if (mapping)
return mapping;
}
return this._mappings[0];
},


_parseMap: function(map, lineNumber, columnNumber)
{
var sourceIndex = 0;
var sourceLineNumber = 0;
var sourceColumnNumber = 0;
var nameIndex = 0;

var sources = [];
var originalToCanonicalURLMap = {};
for (var i = 0; i < map.sources.length; ++i) {
var originalSourceURL = map.sources[i];
var sourceRoot = map.sourceRoot || "";
if (sourceRoot && !sourceRoot.endsWith("/"))
sourceRoot += "/";
var href = sourceRoot + originalSourceURL;
var url = WebInspector.ParsedURL.completeURL(this._sourceMappingURL, href) || href;
originalToCanonicalURLMap[originalSourceURL] = url;
sources.push(url);
this._sources[url] = true;

if (map.sourcesContent && map.sourcesContent[i])
this._sourceContentByURL[url] = map.sourcesContent[i];
}

var stringCharIterator = new WebInspector.SourceMap.StringCharIterator(map.mappings);
var sourceURL = sources[sourceIndex];

while (true) {
if (stringCharIterator.peek() === ",")
stringCharIterator.next();
else {
while (stringCharIterator.peek() === ";") {
lineNumber += 1;
columnNumber = 0;
stringCharIterator.next();
}
if (!stringCharIterator.hasNext())
break;
}

columnNumber += this._decodeVLQ(stringCharIterator);
if (this._isSeparator(stringCharIterator.peek())) {
this._mappings.push([lineNumber, columnNumber]);
continue;
}

var sourceIndexDelta = this._decodeVLQ(stringCharIterator);
if (sourceIndexDelta) {
sourceIndex += sourceIndexDelta;
sourceURL = sources[sourceIndex];
}
sourceLineNumber += this._decodeVLQ(stringCharIterator);
sourceColumnNumber += this._decodeVLQ(stringCharIterator);
if (!this._isSeparator(stringCharIterator.peek()))
nameIndex += this._decodeVLQ(stringCharIterator);

this._mappings.push([lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber]);
}

for (var i = 0; i < this._mappings.length; ++i) {
var mapping = this._mappings[i];
var url = mapping[2];
if (!url)
continue;
if (!this._reverseMappingsBySourceURL[url])
this._reverseMappingsBySourceURL[url] = [];
var reverseMappings = this._reverseMappingsBySourceURL[url];
var sourceLine = mapping[3];
if (!reverseMappings[sourceLine])
reverseMappings[sourceLine] = [mapping[0], mapping[1]];
}
},


_isSeparator: function(char)
{
return char === "," || char === ";";
},


_decodeVLQ: function(stringCharIterator)
{

var result = 0;
var shift = 0;
do {
var digit = this._base64Map[stringCharIterator.next()];
result += (digit & this._VLQ_BASE_MASK) << shift;
shift += this._VLQ_BASE_SHIFT;
} while (digit & this._VLQ_CONTINUATION_MASK);


var negative = result & 1;
result >>= 1;
return negative ? -result : result;
},

_VLQ_BASE_SHIFT: 5,
_VLQ_BASE_MASK: (1 << 5) - 1,
_VLQ_CONTINUATION_MASK: 1 << 5
}


WebInspector.SourceMap.StringCharIterator = function(string)
{
this._string = string;
this._position = 0;
}

WebInspector.SourceMap.StringCharIterator.prototype = {

next: function()
{
return this._string.charAt(this._position++);
},


peek: function()
{
return this._string.charAt(this._position);
},


hasNext: function()
{
return this._position < this._string.length;
}
}






WebInspector.SourceMapping = function()
{
}

WebInspector.SourceMapping.prototype = {

rawLocationToUILocation: function(rawLocation) { },


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber) { },


isIdentity: function() { }
}


WebInspector.ScriptSourceMapping = function()
{
}

WebInspector.ScriptSourceMapping.prototype = {

addScript: function(script) { }
}





WebInspector.Script = function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL, hasSourceURL)
{
this.scriptId = scriptId;
this.sourceURL = sourceURL;
this.lineOffset = startLine;
this.columnOffset = startColumn;
this.endLine = endLine;
this.endColumn = endColumn;
this.isContentScript = isContentScript;
this.sourceMapURL = sourceMapURL;
this.hasSourceURL = hasSourceURL;
this._locations = new Set();
this._sourceMappings = [];
}

WebInspector.Script.Events = {
ScriptEdited: "ScriptEdited",
}

WebInspector.Script.snippetSourceURLPrefix = "snippets:///";

WebInspector.Script.prototype = {

contentURL: function()
{
return this.sourceURL;
},


contentType: function()
{
return WebInspector.resourceTypes.Script;
},


requestContent: function(callback)
{
if (this._source) {
callback(this._source, false, "text/javascript");
return;
}


function didGetScriptSource(error, source)
{
this._source = error ? "" : source;
callback(this._source, false, "text/javascript");
}
if (this.scriptId) {

DebuggerAgent.getScriptSource(this.scriptId, didGetScriptSource.bind(this));
} else
callback("", false, "text/javascript");
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{

function innerCallback(error, searchMatches)
{
if (error)
console.error(error);
var result = [];
for (var i = 0; i < searchMatches.length; ++i) {
var searchMatch = new WebInspector.ContentProvider.SearchMatch(searchMatches[i].lineNumber, searchMatches[i].lineContent);
result.push(searchMatch);
}
callback(result || []);
}

if (this.scriptId) {

DebuggerAgent.searchInContent(this.scriptId, query, caseSensitive, isRegex, innerCallback.bind(this));
} else
callback([]);
},


editSource: function(newSource, callback)
{

function didEditScriptSource(error, callFrames, debugData)
{

if (!error)
this._source = newSource;
callback(error, callFrames);
if (!error)
this.dispatchEventToListeners(WebInspector.Script.Events.ScriptEdited, newSource);
}
if (this.scriptId) {

DebuggerAgent.setScriptSource(this.scriptId, newSource, undefined, didEditScriptSource.bind(this));
} else
callback("Script failed to parse");
},


isInlineScript: function()
{
var startsAtZero = !this.lineOffset && !this.columnOffset;
return !!this.sourceURL && !startsAtZero;
},


isAnonymousScript: function()
{
return !this.sourceURL;
},


setIsDynamicScript: function(isDynamicScript)
{
this._isDynamicScript = isDynamicScript;
},


isDynamicScript: function()
{
return !!this._isDynamicScript;
},


isSnippet: function()
{
return this.sourceURL && this.sourceURL.startsWith(WebInspector.Script.snippetSourceURLPrefix);
},


rawLocationToUILocation: function(lineNumber, columnNumber)
{
var uiLocation;
var rawLocation = new WebInspector.DebuggerModel.Location(this.scriptId, lineNumber, columnNumber || 0);
for (var i = this._sourceMappings.length - 1; !uiLocation && i >= 0; --i)
uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation);
console.assert(uiLocation, "Script raw location can not be mapped to any ui location.");
return uiLocation.uiSourceCode.overrideLocation(uiLocation);
},


pushSourceMapping: function(sourceMapping)
{
this._sourceMappings.push(sourceMapping);
this.updateLocations();
},

popSourceMapping: function()
{
this._sourceMappings.pop();
this.updateLocations();
},

updateLocations: function()
{
var items = this._locations.items();
for (var i = 0; i < items.length; ++i)
items[i].update();
},


createLiveLocation: function(rawLocation, updateDelegate)
{
console.assert(rawLocation.scriptId === this.scriptId);
var location = new WebInspector.Script.Location(this, rawLocation, updateDelegate);
this._locations.add(location);
location.update();
return location;
},

__proto__: WebInspector.Object.prototype
}


WebInspector.Script.Location = function(script, rawLocation, updateDelegate)
{
WebInspector.LiveLocation.call(this, rawLocation, updateDelegate);
this._script = script;
}

WebInspector.Script.Location.prototype = {

uiLocation: function()
{
var debuggerModelLocation =   (this.rawLocation());
return this._script.rawLocationToUILocation(debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber);
},

dispose: function()
{
WebInspector.LiveLocation.prototype.dispose.call(this);
this._script._locations.remove(this);
},

__proto__: WebInspector.LiveLocation.prototype
}






WebInspector.LinkifierFormatter = function()
{
}

WebInspector.LinkifierFormatter.prototype = {

formatLiveAnchor: function(anchor, uiLocation) { }
}


WebInspector.Linkifier = function(formatter)
{
this._formatter = formatter || new WebInspector.Linkifier.DefaultFormatter(WebInspector.Linkifier.MaxLengthForDisplayedURLs);
this._liveLocations = [];
}

WebInspector.Linkifier.prototype = {

linkifyLocation: function(sourceURL, lineNumber, columnNumber, classes)
{
var rawLocation = WebInspector.debuggerModel.createRawLocationByURL(sourceURL, lineNumber, columnNumber || 0);
if (!rawLocation)
return WebInspector.linkifyResourceAsNode(sourceURL, lineNumber, classes);
return this.linkifyRawLocation(rawLocation, classes);
},


linkifyRawLocation: function(rawLocation, classes)
{
var script = WebInspector.debuggerModel.scriptForId(rawLocation.scriptId);
if (!script)
return null;
var anchor = WebInspector.linkifyURLAsNode("", "", classes, false);
var liveLocation = script.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor));
this._liveLocations.push(liveLocation);
return anchor;
},


linkifyCSSRuleLocation: function(rule)
{
var anchor = WebInspector.linkifyURLAsNode("", "", "", false);
var liveLocation = WebInspector.cssModel.createLiveLocation(rule, this._updateAnchor.bind(this, anchor));
if (!liveLocation)
return null;
this._liveLocations.push(liveLocation);
return anchor;
},

reset: function()
{
for (var i = 0; i < this._liveLocations.length; ++i)
this._liveLocations[i].dispose();
this._liveLocations = [];
},


_updateAnchor: function(anchor, uiLocation)
{
anchor.preferredPanel = "scripts";
anchor.href = sanitizeHref(uiLocation.uiSourceCode.originURL());
anchor.uiSourceCode = uiLocation.uiSourceCode;
anchor.lineNumber = uiLocation.lineNumber;
this._formatter.formatLiveAnchor(anchor, uiLocation);
}
}


WebInspector.Linkifier.DefaultFormatter = function(maxLength)
{
this._maxLength = maxLength;
}

WebInspector.Linkifier.DefaultFormatter.prototype = {

formatLiveAnchor: function(anchor, uiLocation)
{
var text = uiLocation.linkText();
if (this._maxLength)
text = text.trimMiddle(this._maxLength);
anchor.textContent = text;

var titleText = uiLocation.uiSourceCode.originURL();
if (typeof uiLocation.lineNumber === "number")
titleText += ":" + (uiLocation.lineNumber + 1);
anchor.title = titleText;
},

__proto__: WebInspector.LinkifierFormatter.prototype
}


WebInspector.Linkifier.DefaultCSSFormatter = function()
{
WebInspector.Linkifier.DefaultFormatter.call(this);
}

WebInspector.Linkifier.DefaultCSSFormatter.prototype = {

formatLiveAnchor: function(anchor, uiLocation)
{
WebInspector.Linkifier.DefaultFormatter.prototype.formatLiveAnchor.call(this, anchor, uiLocation);
anchor.classList.add("webkit-html-resource-link");
anchor.setAttribute("data-uncopyable", anchor.textContent);
anchor.textContent = "";
},
__proto__: WebInspector.Linkifier.DefaultFormatter.prototype
}


WebInspector.Linkifier.MaxLengthForDisplayedURLs = 150;






WebInspector.DebuggerScriptMapping = function(workspace, networkWorkspaceProvider)
{
this._defaultMapping = new WebInspector.DefaultScriptMapping(workspace);
this._resourceMapping = new WebInspector.ResourceScriptMapping(workspace);
this._compilerMapping = new WebInspector.CompilerScriptMapping(workspace, networkWorkspaceProvider);
this._snippetMapping = WebInspector.scriptSnippetModel.scriptMapping;

WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
}

WebInspector.DebuggerScriptMapping.prototype = {

_parsedScriptSource: function(event)
{
var script =   (event.data);
this._defaultMapping.addScript(script);

if (script.isSnippet()) {
this._snippetMapping.addScript(script);
return;
}

this._resourceMapping.addScript(script);

if (WebInspector.settings.sourceMapsEnabled.get())
this._compilerMapping.addScript(script);
}
}






WebInspector.PresentationConsoleMessageHelper = function(uiSourceCodeProvider)
{

this._pendingConsoleMessages = {};
this._presentationConsoleMessages = [];
this._uiSourceCodeProvider = uiSourceCodeProvider;

WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);

WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
}

WebInspector.PresentationConsoleMessageHelper.prototype = {

_consoleMessageAdded: function(event)
{
var message =   (event.data);
if (!message.url || !message.isErrorOrWarning())
return;

var rawLocation = message.location();
if (rawLocation)
this._addConsoleMessageToScript(message, rawLocation);
else
this._addPendingConsoleMessage(message);
},


_addConsoleMessageToScript: function(message, rawLocation)
{
this._presentationConsoleMessages.push(new WebInspector.PresentationConsoleMessage(message, rawLocation));
},


_addPendingConsoleMessage: function(message)
{
if (!message.url)
return;
if (!this._pendingConsoleMessages[message.url])
this._pendingConsoleMessages[message.url] = [];
this._pendingConsoleMessages[message.url].push(message);
},


_parsedScriptSource: function(event)
{
var script =   (event.data);

var messages = this._pendingConsoleMessages[script.sourceURL];
if (!messages)
return;

var pendingMessages = [];
for (var i = 0; i < messages.length; i++) {
var message = messages[i];
var rawLocation =   (message.location());
if (script.scriptId === rawLocation.scriptId)
this._addConsoleMessageToScript(message, rawLocation);
else
pendingMessages.push(message);
}

if (pendingMessages.length)
this._pendingConsoleMessages[script.sourceURL] = pendingMessages;
else
delete this._pendingConsoleMessages[script.sourceURL];
},

_consoleCleared: function()
{
this._pendingConsoleMessages = {};
for (var i = 0; i < this._presentationConsoleMessages.length; ++i)
this._presentationConsoleMessages[i].dispose();
this._presentationConsoleMessages = [];
var uiSourceCodes = this._uiSourceCodeProvider.uiSourceCodes();
for (var i = 0; i < uiSourceCodes.length; ++i)
uiSourceCodes[i].consoleMessagesCleared();
},

_debuggerReset: function()
{
this._pendingConsoleMessages = {};
this._presentationConsoleMessages = [];
}
}


WebInspector.PresentationConsoleMessage = function(message, rawLocation)
{
this.originalMessage = message;
this._liveLocation = WebInspector.debuggerModel.createLiveLocation(rawLocation, this._updateLocation.bind(this));
}

WebInspector.PresentationConsoleMessage.prototype = {

_updateLocation: function(uiLocation)
{
if (this._uiLocation)
this._uiLocation.uiSourceCode.consoleMessageRemoved(this);
this._uiLocation = uiLocation;
this._uiLocation.uiSourceCode.consoleMessageAdded(this);
},

get lineNumber()
{
return this._uiLocation.lineNumber;
},

dispose: function()
{
this._liveLocation.dispose();
}
}






WebInspector.FileSystemProjectDelegate = function(isolatedFileSystem, workspace)
{
this._fileSystem = isolatedFileSystem;
this._workspace = workspace;
}

WebInspector.FileSystemProjectDelegate._scriptExtensions = ["js", "java", "cc", "cpp", "h", "cs", "py", "php"].keySet();
WebInspector.FileSystemProjectDelegate._styleSheetExtensions = ["css", "scss", "sass"].keySet();

WebInspector.FileSystemProjectDelegate.projectId = function(fileSystemPath)
{
return "filesystem:" + fileSystemPath;
}

WebInspector.FileSystemProjectDelegate.prototype = {

id: function()
{
return WebInspector.FileSystemProjectDelegate.projectId(this._fileSystem.path());
},


type: function()
{
return WebInspector.projectTypes.FileSystem;
},


fileSystemPath: function()
{
return this._fileSystem.path();
},


displayName: function()
{
return this._fileSystem.path().substr(this._fileSystem.path().lastIndexOf("/") + 1);
},


_filePathForPath: function(path)
{
return "/" + path.join("/");
},


requestFileContent: function(path, callback)
{
var filePath = this._filePathForPath(path);
this._fileSystem.requestFileContent(filePath, innerCallback.bind(this));


function innerCallback(content)
{
var contentType = this._contentTypeForPath(path);
callback(content, false, contentType.canonicalMimeType());
}
},


canSetFileContent: function()
{
return true;
},


setFileContent: function(path, newContent, callback)
{
var filePath = this._filePathForPath(path);
this._fileSystem.setFileContent(filePath, newContent, callback.bind(this, ""));
},


searchInFileContent: function(path, query, caseSensitive, isRegex, callback)
{
var filePath = this._filePathForPath(path);
this._fileSystem.requestFileContent(filePath, contentCallback.bind(this));


function contentCallback(content)
{
var result = [];
if (content !== null)
result = WebInspector.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex);
callback(result);
}
},


_contentTypeForPath: function(path)
{
var fileName = path[path.length - 1];
var extensionIndex = fileName.lastIndexOf(".");
var extension = "";
if (extensionIndex !== -1)
extension = fileName.substring(extensionIndex + 1).toLowerCase();
var contentType = WebInspector.resourceTypes.Other;
if (WebInspector.FileSystemProjectDelegate._scriptExtensions[extension])
return WebInspector.resourceTypes.Script;
if (WebInspector.FileSystemProjectDelegate._styleSheetExtensions[extension])
return WebInspector.resourceTypes.Stylesheet;
if (extension === "html" || extension === "htm")
return WebInspector.resourceTypes.Document;
return WebInspector.resourceTypes.Other;
},

populate: function()
{
this._fileSystem.requestFilesRecursive("", fileLoaded.bind(this));

function fileLoaded(filePath)
{
var path = filePath.split("/");
path.shift();
console.assert(path.length);
var fullPath = this._fileSystem.path() + filePath;
var url = this._workspace.urlForPath(fullPath);
var contentType = this._contentTypeForPath(path);
var fileDescriptor = new WebInspector.FileDescriptor(path, "file://" + fullPath, url, contentType, true);
this._addFile(fileDescriptor);
}
},


_addFile: function(fileDescriptor)
{
this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileAdded, fileDescriptor);
},


_removeFile: function(path)
{
this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileRemoved, path);
},

reset: function()
{
this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.Reset, null);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.fileSystemProjectDelegate = null;


WebInspector.FileSystemWorkspaceProvider = function(isolatedFileSystemManager, workspace)
{
this._isolatedFileSystemManager = isolatedFileSystemManager;
this._workspace = workspace;
this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, this._fileSystemAdded, this);
this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, this._fileSystemRemoved, this);
this._simpleProjectDelegates = {};
}

WebInspector.FileSystemWorkspaceProvider.prototype = {

_fileSystemAdded: function(event)
{
var fileSystem =   (event.data);
var projectId = WebInspector.FileSystemProjectDelegate.projectId(fileSystem.path());
var projectDelegate = new WebInspector.FileSystemProjectDelegate(fileSystem, this._workspace)
this._simpleProjectDelegates[projectDelegate.id()] = projectDelegate;
console.assert(!this._workspace.project(projectDelegate.id()));
this._workspace.addProject(projectDelegate);
projectDelegate.populate();
},


_fileSystemRemoved: function(event)
{
var fileSystem =   (event.data);
var projectId = WebInspector.FileSystemProjectDelegate.projectId(fileSystem.path());
this._workspace.removeProject(projectId);
delete this._simpleProjectDelegates[projectId];
},


fileSystemPath: function(uiSourceCode)
{
var projectDelegate = this._simpleProjectDelegates[uiSourceCode.project().id()];
return projectDelegate.fileSystemPath();
}
}


WebInspector.fileSystemWorkspaceProvider = null;






WebInspector.FileSystemMapping = function() { }

WebInspector.FileSystemMapping.prototype = {

fileSystemPaths: function() { },


fileSystemPathForPrefix: function(prefix) { }
}


WebInspector.FileSystemMappingImpl = function()
{
WebInspector.Object.call(this);
this._fileSystemMappingSetting = WebInspector.settings.createSetting("fileSystemMapping", {});

this._fileSystemPaths = {};
this._loadFromSettings();
}

WebInspector.FileSystemMappingImpl.prototype = {
_loadFromSettings: function()
{
var savedMapping = this._fileSystemMappingSetting.get();
this._fileSystemPaths = savedMapping ?   (savedMapping.registeredFileSystemPaths) || {} : {};
},

_saveToSettings: function()
{
var savedMapping = {};
savedMapping.registeredFileSystemPaths = this._fileSystemPaths;
this._fileSystemMappingSetting.set(savedMapping);
},



addFileSystemMapping: function(fileSystemPath)
{
if (this._fileSystemPaths[fileSystemPath])
return;

this._fileSystemPaths[fileSystemPath] = true;
this._saveToSettings();
delete this._cachedFileSystemPaths;
},


removeFileSystemMapping: function(fileSystemPath)
{
if (!this._fileSystemPaths[fileSystemPath])
return;
delete this._fileSystemPaths[fileSystemPath];
this._saveToSettings();
delete this._cachedFileSystemPaths;
},


fileSystemPaths: function()
{
return Object.keys(this._fileSystemPaths);
},


fileSystemPathForPrefix: function(prefix)
{
this._cachedFileSystemPaths = this._cachedFileSystemPaths || {};
if (this._cachedFileSystemPaths.hasOwnProperty(prefix))
return this._cachedFileSystemPaths[prefix];
var result = null;
for (var fileSystemPath in this._fileSystemPaths) {
if (prefix.startsWith(fileSystemPath + "/")) {
result = fileSystemPath;
break;
}
}
this._cachedFileSystemPaths[prefix] = result;
return result;
},

__proto__: WebInspector.Object.prototype
}






WebInspector.IsolatedFileSystem = function(manager, path, name, rootURL)
{
this._manager = manager;
this._path = path;
this._name = name;
this._rootURL = rootURL;
}

WebInspector.IsolatedFileSystem.errorMessage = function(error)
{
var msg;
switch (error.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = "QUOTA_EXCEEDED_ERR";
break;
case FileError.NOT_FOUND_ERR:
msg = "NOT_FOUND_ERR";
break;
case FileError.SECURITY_ERR:
msg = "SECURITY_ERR";
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = "INVALID_MODIFICATION_ERR";
break;
case FileError.INVALID_STATE_ERR:
msg = "INVALID_STATE_ERR";
break;
default:
msg = "Unknown Error";
break;
};

return "File system error: " + msg;
}

WebInspector.IsolatedFileSystem.prototype = {

path: function()
{
return this._path;
},


name: function()
{
return this._name;
},


rootURL: function()
{
return this._rootURL;
},


_requestFileSystem: function(callback)
{
this._manager.requestDOMFileSystem(this._path, callback);
},


requestFilesRecursive: function(path, callback)
{
this._requestFileSystem(fileSystemLoaded.bind(this));

var domFileSystem;

function fileSystemLoaded(fs)
{
domFileSystem = fs;
this._requestEntries(domFileSystem, path, innerCallback.bind(this));
}


function innerCallback(entries)
{
for (var i = 0; i < entries.length; ++i) {
var entry = entries[i];
if (!entry.isDirectory)
callback(entry.fullPath);
else
this._requestEntries(domFileSystem, entry.fullPath, innerCallback.bind(this));
}
}
},


requestFileContent: function(path, callback)
{
this._requestFileSystem(fileSystemLoaded.bind(this));


function fileSystemLoaded(domFileSystem)
{
domFileSystem.root.getFile(path, null, fileEntryLoaded, errorHandler);
}


function fileEntryLoaded(entry)
{
entry.file(fileLoaded, errorHandler);
}


function fileLoaded(file)
{
var reader = new FileReader();
reader.onloadend = readerLoadEnd;
reader.readAsText(file);
}


function readerLoadEnd()
{
callback(  (this.result));
}

function errorHandler(error)
{
if (error.code === FileError.NOT_FOUND_ERR) {
callback(null);
return;
}

var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when getting content for file '" + (this._path + "/" + path) + "'");
callback(null);
}
},


setFileContent: function(path, content, callback)
{
this._requestFileSystem(fileSystemLoaded);


function fileSystemLoaded(domFileSystem)
{
domFileSystem.root.getFile(path, { create: true }, fileEntryLoaded, errorHandler);
}


function fileEntryLoaded(entry)
{
entry.createWriter(fileWriterCreated, errorHandler);
}


function fileWriterCreated(fileWriter)
{
fileWriter.onerror = errorHandler;
fileWriter.onwriteend = fileTruncated;
fileWriter.truncate(0);

function fileTruncated()
{
fileWriter.onwriteend = writerEnd;
var blob = new Blob([content], { type: "text/plain" });
fileWriter.write(blob);
}
}

function writerEnd()
{
callback();
}

function errorHandler(error)
{
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when setting content for file '" + (this._path + "/" + path) + "'");
callback();
}
},


_readDirectory: function(dirEntry, callback)
{
var dirReader = dirEntry.createReader();
var entries = [];

function innerCallback(results)
{
if (!results.length)
callback(entries.sort());
else {
entries = entries.concat(toArray(results));
dirReader.readEntries(innerCallback, errorHandler);
}
}

function toArray(list)
{
return Array.prototype.slice.call(list || [], 0);
}    

dirReader.readEntries(innerCallback, errorHandler);

function errorHandler(error)
{
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when reading directory '" + dirEntry.fullPath + "'");
callback([]);
}
},


_requestEntries: function(domFileSystem, path, callback)
{
domFileSystem.root.getDirectory(path, null, innerCallback.bind(this), errorHandler);

function innerCallback(dirEntry)
{
this._readDirectory(dirEntry, callback)
}

function errorHandler(error)
{
var errorMessage = WebInspector.IsolatedFileSystem.errorMessage(error);
console.error(errorMessage + " when requesting entry '" + path + "'");
callback([]);
}
}
}






WebInspector.IsolatedFileSystemManager = function()
{

this._fileSystems = {};

this._pendingFileSystemRequests = {};
this._fileSystemMapping = new WebInspector.FileSystemMappingImpl();

if (this.supportsFileSystems())
this._requestFileSystems();
}


WebInspector.IsolatedFileSystemManager.FileSystem;

WebInspector.IsolatedFileSystemManager.Events = {
FileSystemAdded: "FileSystemAdded",
FileSystemRemoved: "FileSystemRemoved"
}

WebInspector.IsolatedFileSystemManager.prototype = {

mapping: function()
{
return this._fileSystemMapping;
},


supportsFileSystems: function()
{
return InspectorFrontendHost.supportsFileSystems();
},

_requestFileSystems: function()
{
console.assert(!this._loaded);
InspectorFrontendHost.requestFileSystems();
},


addFileSystem: function(callback)
{
this._selectFileSystemPathCallback = callback;
InspectorFrontendHost.addFileSystem();
},


removeFileSystem: function(fileSystemPath, callback)
{
this._removeFileSystemCallback = callback;
InspectorFrontendHost.removeFileSystem(fileSystemPath);
},


_fileSystemsLoaded: function(fileSystems)
{
for (var i = 0; i < fileSystems.length; ++i)
this._innerAddFileSystem(fileSystems[i]);
this._loaded = true;
this._processPendingFileSystemRequests();
},


_innerAddFileSystem: function(fileSystem)
{
var fileSystemPath = fileSystem.fileSystemPath;
this._fileSystemMapping.addFileSystemMapping(fileSystemPath);
var isolatedFileSystem = new WebInspector.IsolatedFileSystem(this, fileSystemPath, fileSystem.fileSystemName, fileSystem.rootURL);
this._fileSystems[fileSystemPath] = isolatedFileSystem;
this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, isolatedFileSystem);
},


_fileSystemPaths: function()
{
return Object.keys(this._fileSystems);
},

_processPendingFileSystemRequests: function()
{
for (var fileSystemPath in this._pendingFileSystemRequests) {
var callbacks = this._pendingFileSystemRequests[fileSystemPath];
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._isolatedFileSystem(fileSystemPath));
}
delete this._pendingFileSystemRequests;
},


_fileSystemAdded: function(errorMessage, fileSystem)
{
var fileSystemPath;
if (errorMessage)
WebInspector.showErrorMessage(errorMessage)
else if (fileSystem) {
this._innerAddFileSystem(fileSystem);
fileSystemPath = fileSystem.fileSystemPath;
}

if (this._selectFileSystemPathCallback) {
this._selectFileSystemPathCallback(fileSystemPath);
delete this._selectFileSystemPathCallback;
}
},


_fileSystemRemoved: function(fileSystemPath)
{
this._fileSystemMapping.removeFileSystemMapping(fileSystemPath);
var isolatedFileSystem = this._fileSystems[fileSystemPath];
delete this._fileSystems[fileSystemPath];
if (this._removeFileSystemCallback) {
this._removeFileSystemCallback(fileSystemPath);
delete this._removeFileSystemCallback;
}
this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, isolatedFileSystem);
},


_isolatedFileSystem: function(fileSystemPath)
{
var fileSystem = this._fileSystems[fileSystemPath];
if (!fileSystem)
return null;
if (!InspectorFrontendHost.isolatedFileSystem)
return null;
return InspectorFrontendHost.isolatedFileSystem(fileSystem.name(), fileSystem.rootURL());
},


requestDOMFileSystem: function(fileSystemPath, callback)
{
if (!this._loaded) {
if (!this._pendingFileSystemRequests[fileSystemPath])
this._pendingFileSystemRequests[fileSystemPath] = this._pendingFileSystemRequests[fileSystemPath] || [];
this._pendingFileSystemRequests[fileSystemPath].push(callback);
return;
}
callback(this._isolatedFileSystem(fileSystemPath));
},

__proto__: WebInspector.Object.prototype
}


WebInspector.isolatedFileSystemManager = null;


WebInspector.IsolatedFileSystemDispatcher = function(IsolatedFileSystemManager)
{
this._IsolatedFileSystemManager = IsolatedFileSystemManager;
}

WebInspector.IsolatedFileSystemDispatcher.prototype = {

fileSystemsLoaded: function(fileSystems)
{
this._IsolatedFileSystemManager._fileSystemsLoaded(fileSystems);
},


fileSystemRemoved: function(fileSystemPath)
{
this._IsolatedFileSystemManager._fileSystemRemoved(fileSystemPath);
},


fileSystemAdded: function(errorMessage, fileSystem)
{
this._IsolatedFileSystemManager._fileSystemAdded(errorMessage, fileSystem);
}
}


WebInspector.isolatedFileSystemDispatcher = null;






WebInspector.FileMapping = function()
{
this._mappingEntriesSetting = WebInspector.settings.createSetting("fileMappingEntries", []);

this._entries = [];
this._loadFromSettings();
}

WebInspector.FileMapping.prototype = {

mappingEntryForURL: function(url)
{
for (var i = 0; i < this._entries.length; ++i) {
var entry = this._entries[i];
if (url.startsWith(entry.urlPrefix))
return entry;
}
return null;
},


mappingEntryForPath: function(path)
{
for (var i = 0; i < this._entries.length; ++i) {
var entry = this._entries[i];
if (path.startsWith(entry.pathPrefix))
return entry;
}
return null;
},


mappingEntries: function()
{
return this._entries.slice();
},


setMappingEntries: function(mappingEntries)
{
this._entries = mappingEntries;
this._mappingEntriesSetting.set(mappingEntries);
},

_loadFromSettings: function()
{
var savedEntries = this._mappingEntriesSetting.get();
this._entries = [];
for (var i = 0; i < savedEntries.length; ++i) {
var entry = new WebInspector.FileMapping.Entry(savedEntries[i].urlPrefix, savedEntries[i].pathPrefix);
this._entries.push(entry);
}
},

__proto__: WebInspector.Object.prototype
}


WebInspector.FileMapping.Entry = function(urlPrefix, pathPrefix)
{
this.urlPrefix = urlPrefix;
this.pathPrefix = pathPrefix;
}


WebInspector.fileMapping = null;






WebInspector.WorkspaceController = function(workspace)
{
this._workspace = workspace;
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
}

WebInspector.WorkspaceController.prototype = {

_inspectedURLChanged: function(event)
{
WebInspector.Revision.filterOutStaleRevisions();
}
}


WebInspector.FileDescriptor = function(path, originURL, url, contentType, isEditable, isContentScript)
{
this.path = path;
this.originURL = originURL;
this.url = url;
this.contentType = contentType;
this.isEditable = isEditable;
this.isContentScript = isContentScript || false;
}


WebInspector.ProjectDelegate = function() { }

WebInspector.ProjectDelegate.Events = {
FileAdded: "FileAdded",
FileRemoved: "FileRemoved",
Reset: "Reset",
}

WebInspector.ProjectDelegate.prototype = {

id: function() { },


type: function() { },


displayName: function() { }, 


requestFileContent: function(path, callback) { },


canSetFileContent: function() { },


setFileContent: function(path, newContent, callback) { },


searchInFileContent: function(path, query, caseSensitive, isRegex, callback) { }
}


WebInspector.workspaceController = null;


WebInspector.Project = function(workspace, projectDelegate)
{

this._uiSourceCodes = {};
this._workspace = workspace;
this._projectDelegate = projectDelegate;
this._projectDelegate.addEventListener(WebInspector.ProjectDelegate.Events.FileAdded, this._fileAdded, this);
this._projectDelegate.addEventListener(WebInspector.ProjectDelegate.Events.FileRemoved, this._fileRemoved, this);
this._projectDelegate.addEventListener(WebInspector.ProjectDelegate.Events.Reset, this._reset, this);
}

WebInspector.Project.prototype = {

id: function()
{
return this._projectDelegate.id();
},


type: function()
{
return this._projectDelegate.type(); 
},


displayName: function() 
{
return this._projectDelegate.displayName(); 
},


isServiceProject: function()
{
return this._projectDelegate.type() === WebInspector.projectTypes.Debugger || this._projectDelegate.type() === WebInspector.projectTypes.LiveEdit;
},

_fileAdded: function(event)
{
var fileDescriptor =   (event.data);
var uiSourceCode = this.uiSourceCode(fileDescriptor.path);
if (uiSourceCode) {

return;
}

uiSourceCode = new WebInspector.UISourceCode(this, fileDescriptor.path, fileDescriptor.originURL, fileDescriptor.url, fileDescriptor.contentType, fileDescriptor.isEditable); 
uiSourceCode.isContentScript = fileDescriptor.isContentScript;
this._uiSourceCodes[uiSourceCode.path().join("/")] = uiSourceCode;
this._workspace.dispatchEventToListeners(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, uiSourceCode);
},

_fileRemoved: function(event)
{
var path =   (event.data);
var uiSourceCode = this.uiSourceCode(path);
if (!uiSourceCode)
return;
delete this._uiSourceCodes[uiSourceCode.path().join("/")];
this._workspace.dispatchEventToListeners(WebInspector.UISourceCodeProvider.Events.UISourceCodeRemoved, uiSourceCode);
},

_reset: function()
{
this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectWillReset, this);
this._uiSourceCodes = {};
},


uiSourceCode: function(path)
{
return this._uiSourceCodes[path.join("/")] || null;
},


uiSourceCodeForOriginURL: function(originURL)
{
for (var path in this._uiSourceCodes) {
var uiSourceCode = this._uiSourceCodes[path];
if (uiSourceCode.originURL() === originURL)
return uiSourceCode;
}
return null;
},


uiSourceCodes: function()
{
return Object.values(this._uiSourceCodes);
},


requestFileContent: function(uiSourceCode, callback)
{
this._projectDelegate.requestFileContent(uiSourceCode.path(), callback);
},


canSetFileContent: function()
{
return this._projectDelegate.canSetFileContent();
},


setFileContent: function(uiSourceCode, newContent, callback)
{
this._projectDelegate.setFileContent(uiSourceCode.path(), newContent, callback);
this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeContentCommitted, { uiSourceCode: uiSourceCode, content: newContent });
},


searchInFileContent: function(uiSourceCode, query, caseSensitive, isRegex, callback)
{
this._projectDelegate.searchInFileContent(uiSourceCode.path(), query, caseSensitive, isRegex, callback);
},

dispose: function()
{
this._projectDelegate.reset();
}
}

WebInspector.projectTypes = {
Debugger: "debugger",
LiveEdit: "liveedit",
Network: "network",
Snippets: "snippets",
FileSystem: "filesystem"
}


WebInspector.Workspace = function(fileMapping, fileSystemMapping)
{
this._fileMapping = fileMapping;
this._fileSystemMapping = fileSystemMapping;

this._projects = {};
}

WebInspector.Workspace.Events = {
UISourceCodeContentCommitted: "UISourceCodeContentCommitted",
ProjectWillReset: "ProjectWillReset"
}

WebInspector.Workspace.prototype = {

uiSourceCode: function(projectId, path)
{
var project = this._projects[projectId];
return project ? project.uiSourceCode(path) : null;
},


uiSourceCodeForOriginURL: function(originURL)
{
var networkProjects = this.projectsForType(WebInspector.projectTypes.Network)
for (var i = 0; i < networkProjects.length; ++i) {
var project = networkProjects[i];
var uiSourceCode = project.uiSourceCodeForOriginURL(originURL);
if (uiSourceCode)
return uiSourceCode;
}
return null;
},


uiSourceCodesForProjectType: function(type)
{
var result = [];
for (var projectName in this._projects) {
var project = this._projects[projectName];
if (project.type() === type)
result = result.concat(project.uiSourceCodes());
}
return result;
},


addProject: function(projectDelegate)
{
var projectId = projectDelegate.id();
this._projects[projectId] = new WebInspector.Project(this, projectDelegate);
return this._projects[projectId];
},


removeProject: function(projectId)
{
var project = this._projects[projectId];
if (!project)
return;
project.dispose();
delete this._projects[projectId];
},


project: function(projectId)
{
return this._projects[projectId];
},


projects: function()
{
return Object.values(this._projects);
},


projectsForType: function(type)
{
function filterByType(project)
{
return project.type() === type;
}
return this.projects().filter(filterByType);
},


uiSourceCodes: function()
{
var result = [];
for (var projectId in this._projects) {
var project = this._projects[projectId];
result = result.concat(project.uiSourceCodes());
}
return result;
},


hasMappingForURL: function(url)
{
var entry = this._fileMapping.mappingEntryForURL(url);
if (!entry)
return false;
return !!this._fileSystemPathForEntry(entry);
},


_fileSystemPathForEntry: function(entry)
{
return this._fileSystemMapping.fileSystemPathForPrefix(entry.pathPrefix);
},

uiSourceCodeForURL: function(url)
{
var entry = this._fileMapping.mappingEntryForURL(url);
var fileSystemPath = entry ? this._fileSystemPathForEntry(entry) : null;
if (!fileSystemPath) {
var splittedURL = WebInspector.ParsedURL.splitURL(url);
var projectId = WebInspector.SimpleProjectDelegate.projectId(splittedURL[0], WebInspector.projectTypes.Network);
var path = WebInspector.SimpleWorkspaceProvider.pathForSplittedURL(splittedURL);
var project = this.project(projectId);
return project ? project.uiSourceCode(path) : null;
}

var projectId = WebInspector.FileSystemProjectDelegate.projectId(fileSystemPath);
var pathPrefix = entry.pathPrefix.substr(fileSystemPath.length + 1);
var path = pathPrefix + url.substr(entry.urlPrefix.length);
var project = this.project(projectId);
return project ? project.uiSourceCode(path.split("/")) : null;
},


urlForPath: function(path)
{
var entry = this._fileMapping.mappingEntryForPath(path);
if (!entry)
return "";
return entry.urlPrefix + path.substring(entry.pathPrefix.length);
},


addMapping: function(networkUISourceCode, uiSourceCode, fileSystemWorkspaceProvider)
{
var url = networkUISourceCode.url;
var path = uiSourceCode.path();
var suffix = "";
for (var i = path.length - 1; i >= 0; --i) {
var nextSuffix = "/" + path[i] + suffix;
if (!url.endsWith(nextSuffix))
break;
suffix = nextSuffix;
}
var fileSystemPath = fileSystemWorkspaceProvider.fileSystemPath(uiSourceCode);
var filePath = "/" + path.join("/");
var pathPrefix = fileSystemPath + filePath.substr(0, filePath.length - suffix.length) + "/";
var urlPrefix = url.substr(0, url.length - suffix.length) + "/";

var entries = this._fileMapping.mappingEntries();
var entry = new WebInspector.FileMapping.Entry(urlPrefix, pathPrefix);
entries.push(entry);
this._fileMapping.setMappingEntries(entries);
WebInspector.suggestReload();
},


removeMapping: function(uiSourceCode)
{
var entry = this._fileMapping.mappingEntryForURL(uiSourceCode.url);
var entries = this._fileMapping.mappingEntries();
entries.remove(entry);
this._fileMapping.setMappingEntries(entries);
WebInspector.suggestReload();
},

__proto__: WebInspector.Object.prototype
}


WebInspector.workspace = null;






WebInspector.ContentProviderBasedProjectDelegate = function(type)
{
this._type = type;

this._contentProviders = {};
}

WebInspector.ContentProviderBasedProjectDelegate.prototype = {

id: function()
{

return "";
},


type: function()
{
return this._type;
},


displayName: function()
{

return "";
},


requestFileContent: function(path, callback)
{
var contentProvider = this._contentProviders[path.join("/")];
contentProvider.requestContent(callback);
},


canSetFileContent: function()
{
return false;
},


setFileContent: function(path, newContent, callback)
{
callback(null);
},


searchInFileContent: function(path, query, caseSensitive, isRegex, callback)
{
var contentProvider = this._contentProviders[path.join("/")];
contentProvider.searchInContent(query, caseSensitive, isRegex, callback);
},


addContentProvider: function(path, url, contentProvider, isEditable, isContentScript)
{
var fileDescriptor = new WebInspector.FileDescriptor(path, url, url, contentProvider.contentType(), isEditable, isContentScript);
this._contentProviders[path.join("/")] = contentProvider;
this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileAdded, fileDescriptor);
return path;
},


removeFile: function(path)
{
delete this._contentProviders[path.join("/")];
this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileRemoved, path);
},


contentProviders: function()
{
return this._contentProviders;
},

reset: function()
{
this._contentProviders = {};
this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.Reset, null);
},

__proto__: WebInspector.Object.prototype
}






WebInspector.SimpleProjectDelegate = function(name, type)
{
WebInspector.ContentProviderBasedProjectDelegate.call(this, type);
this._name = name;
this._lastUniqueSuffix = 0;
}

WebInspector.SimpleProjectDelegate.projectId = function(name, type)
{
var typePrefix = type !== WebInspector.projectTypes.Network ? (type + ":") : "";
return typePrefix + name;
}

WebInspector.SimpleProjectDelegate.prototype = {

id: function()
{
return WebInspector.SimpleProjectDelegate.projectId(this._name, this.type());
},


displayName: function()
{
if (typeof this._displayName !== "undefined")
return this._displayName;
if (!this._name) {
this._displayName = this.type() !== WebInspector.projectTypes.Snippets ? WebInspector.UIString("(no domain)") : "";
return this._displayName;
}
var parsedURL = new WebInspector.ParsedURL(this._name);
if (parsedURL.isValid) {
this._displayName = parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "");
if (!this._displayName)
this._displayName = this._name;
}
else
this._displayName = this._name;
return this._displayName;
},


addFile: function(path, forceUniquePath, url, contentProvider, isEditable, isContentScript)
{
if (forceUniquePath)
this._ensureUniquePath(path);
return this.addContentProvider(path, url, contentProvider, isEditable, isContentScript);
},


_ensureUniquePath: function(path)
{
var uniquePath = path.join("/");
var suffix = "";
var contentProviders = this.contentProviders();
while (contentProviders[uniquePath]) {
suffix = " (" + (++this._lastUniqueSuffix) + ")";
uniquePath = path + suffix;
}
path[path.length - 1] += suffix;
},

__proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype
}


WebInspector.SimpleWorkspaceProvider = function(workspace, type)
{
this._workspace = workspace;
this._type = type;
this._simpleProjectDelegates = {};
}


WebInspector.SimpleWorkspaceProvider.pathForSplittedURL = function(splittedURL)
{
var result = splittedURL.slice();
result.shift();
return result;
}

WebInspector.SimpleWorkspaceProvider.prototype = {

_projectDelegate: function(projectName)
{
if (this._simpleProjectDelegates[projectName])
return this._simpleProjectDelegates[projectName];
var simpleProjectDelegate = new WebInspector.SimpleProjectDelegate(projectName, this._type);
this._simpleProjectDelegates[projectName] = simpleProjectDelegate;
this._workspace.addProject(simpleProjectDelegate);
return simpleProjectDelegate;
},


addFileForURL: function(url, contentProvider, isEditable, isContentScript)
{
return this._innerAddFileForURL(url, contentProvider, isEditable, false, isContentScript);
},


addUniqueFileForURL: function(url, contentProvider, isEditable, isContentScript)
{
return this._innerAddFileForURL(url, contentProvider, isEditable, true, isContentScript);
},


_innerAddFileForURL: function(url, contentProvider, isEditable, forceUnique, isContentScript)
{
var splittedURL = WebInspector.ParsedURL.splitURL(url);
var projectName = splittedURL[0];
var path = WebInspector.SimpleWorkspaceProvider.pathForSplittedURL(splittedURL);
return this._innerAddFile(projectName, path, url, contentProvider, isEditable, forceUnique, isContentScript);
},


addFileByName: function(projectName, name, contentProvider, isEditable, isContentScript)
{
return this._innerAddFile("", [name], name, contentProvider, isEditable, false, isContentScript);
},


_innerAddFile: function(projectName, path, url, contentProvider, isEditable, forceUnique, isContentScript)
{
var projectDelegate = this._projectDelegate(projectName);
path = projectDelegate.addFile(path, forceUnique, url, contentProvider, isEditable, isContentScript);
return this._workspace.uiSourceCode(projectDelegate.id(), path);
},


removeFileByName: function(projectName, name)
{
var projectDelegate = this._projectDelegate(projectName);
projectDelegate.removeFile([name]);
},

reset: function()
{
for (var projectName in this._simpleProjectDelegates)
this._simpleProjectDelegates[projectName].reset();
this._simpleProjectDelegates = {};
},

__proto__: WebInspector.Object.prototype
}






WebInspector.BreakpointManager = function(breakpointStorage, debuggerModel, workspace)
{
this._storage = new WebInspector.BreakpointManager.Storage(this, breakpointStorage);
this._debuggerModel = debuggerModel;
this._workspace = workspace;

this._breakpoints = new Map();
this._breakpointForDebuggerId = {};
this._breakpointsForUISourceCode = new Map();
this._sourceFilesWithRestoredBreakpoints = {};

this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset, this);
this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
}

WebInspector.BreakpointManager.Events = {
BreakpointAdded: "breakpoint-added",
BreakpointRemoved: "breakpoint-removed"
}

WebInspector.BreakpointManager.sourceFileId = function(uiSourceCode)
{
if (!uiSourceCode.url)
return "";
var deobfuscatedPrefix = uiSourceCode.formatted() ? "deobfuscated:" : "";
return deobfuscatedPrefix + uiSourceCode.uri();
}

WebInspector.BreakpointManager.prototype = {

_restoreBreakpoints: function(uiSourceCode)
{
var sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode);
if (!sourceFileId || this._sourceFilesWithRestoredBreakpoints[sourceFileId])
return;
this._sourceFilesWithRestoredBreakpoints[sourceFileId] = true;


for (var debuggerId in this._breakpointForDebuggerId) {
var breakpoint = this._breakpointForDebuggerId[debuggerId];
if (breakpoint._sourceFileId !== sourceFileId)
continue;
breakpoint.remove(true);
}
this._storage._restoreBreakpoints(uiSourceCode);
},


_uiSourceCodeAdded: function(event)
{
var uiSourceCode =   (event.data);
this._restoreBreakpoints(uiSourceCode);
if (uiSourceCode.contentType() === WebInspector.resourceTypes.Script || uiSourceCode.contentType() === WebInspector.resourceTypes.Document) {
uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged, this._uiSourceCodeMappingChanged, this);
uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.FormattedChanged, this._uiSourceCodeFormatted, this);
}
},


_uiSourceCodeFormatted: function(event)
{
var uiSourceCode =   (event.target);
this._restoreBreakpoints(uiSourceCode);
},


_resetBreakpoints: function(uiSourceCode)
{
var sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode);
var breakpoints = this._breakpoints.keys();
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
if (breakpoint._sourceFileId !== sourceFileId)
return;
if (breakpoint.enabled()) {
breakpoint._removeFromDebugger();
breakpoint._setInDebugger();
}
}
},


_uiSourceCodeMappingChanged: function(event)
{
var identityHasChanged =   (event.data.identityHasChanged);
if (!identityHasChanged)
return;
var uiSourceCode =   (event.target);
this._resetBreakpoints(uiSourceCode);
},


setBreakpoint: function(uiSourceCode, lineNumber, condition, enabled)
{
this._debuggerModel.setBreakpointsActive(true);
return this._innerSetBreakpoint(uiSourceCode, lineNumber, condition, enabled);
},


_innerSetBreakpoint: function(uiSourceCode, lineNumber, condition, enabled)
{
var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber);
if (breakpoint) {
breakpoint._updateBreakpoint(condition, enabled);
return breakpoint;
}
breakpoint = new WebInspector.BreakpointManager.Breakpoint(this, uiSourceCode, lineNumber, condition, enabled);
this._breakpoints.put(breakpoint);
return breakpoint;
},


findBreakpoint: function(uiSourceCode, lineNumber)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
var lineBreakpoints = breakpoints ? breakpoints[lineNumber] : null;
return lineBreakpoints ? lineBreakpoints[0] : null;
},


breakpointsForUISourceCode: function(uiSourceCode)
{
var result = [];
var breakpoints =  (this._breakpoints.keys());
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
var uiLocation = breakpoint._primaryUILocation;
if (uiLocation.uiSourceCode === uiSourceCode)
result.push(breakpoint);
}
return result;
},


allBreakpoints: function()
{
var result = [];
var breakpoints =  (this._breakpoints.keys());
return breakpoints;
},


breakpointLocationsForUISourceCode: function(uiSourceCode)
{
var result = [];
var breakpoints =  (this._breakpoints.keys());
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
var uiLocations = Object.values(breakpoint._uiLocations);
for (var j = 0; j < uiLocations.length; ++j) {
var uiLocation = uiLocations[j];
if (uiLocation.uiSourceCode === uiSourceCode)
result.push({breakpoint: breakpoint, uiLocation: uiLocations[j]});
}
}
return result;
},


allBreakpointLocations: function()
{
var result = [];
var breakpoints =  (this._breakpoints.keys());
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
var uiLocations = Object.values(breakpoint._uiLocations);
for (var j = 0; j < uiLocations.length; ++j)
result.push({breakpoint: breakpoint, uiLocation: uiLocations[j]});
}
return result;
},


toggleAllBreakpoints: function(toggleState)
{
var breakpoints =  (this._breakpoints.keys());
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
if (breakpoint.enabled() != toggleState)
breakpoint.setEnabled(toggleState);
}
},

removeAllBreakpoints: function()
{
var breakpoints =  (this._breakpoints.keys());
for (var i = 0; i < breakpoints.length; ++i)
breakpoints[i].remove();
},

reset: function()
{

this._storage._muted = true;
this.removeAllBreakpoints();
delete this._storage._muted;


for (var debuggerId in this._breakpointForDebuggerId)
this._debuggerModel.removeBreakpoint(debuggerId);
this._breakpointForDebuggerId = {};
this._sourceFilesWithRestoredBreakpoints = {};
},

_projectWillReset: function(event)
{
var project =   (event.data);
var uiSourceCodes = project.uiSourceCodes();
for (var i = 0; i < uiSourceCodes.length; ++i) {
var uiSourceCode = uiSourceCodes[i];
var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode) || [];
for (var lineNumber in breakpoints) {
var lineBreakpoints = breakpoints[lineNumber];
for (var j = 0; j < lineBreakpoints.length; ++j) {
var breakpoint = lineBreakpoints[j];
breakpoint._resetLocations();
}
}
this._breakpointsForUISourceCode.remove(uiSourceCode);

breakpoints = this.breakpointsForUISourceCode(uiSourceCode);
for (var j = 0; j < breakpoints.length; ++j) { 
var breakpoint = breakpoints[j];
this._breakpoints.remove(breakpoint);
}

var sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode);
delete this._sourceFilesWithRestoredBreakpoints[sourceFileId];
}
},

_breakpointResolved: function(event)
{
var breakpointId =   (event.data.breakpointId);
var location =   (event.data.location);
var breakpoint = this._breakpointForDebuggerId[breakpointId];
if (!breakpoint)
return;
if (!this._breakpoints.contains(breakpoint))
this._breakpoints.put(breakpoint);
breakpoint._addResolvedLocation(location);
},


_removeBreakpoint: function(breakpoint, removeFromStorage)
{
console.assert(!breakpoint._debuggerId)
this._breakpoints.remove(breakpoint);
if (removeFromStorage)
this._storage._removeBreakpoint(breakpoint);
},


_uiLocationAdded: function(breakpoint, uiLocation)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
if (!breakpoints) {
breakpoints = {};
this._breakpointsForUISourceCode.put(uiLocation.uiSourceCode, breakpoints);
}

var lineBreakpoints = breakpoints[uiLocation.lineNumber];
if (!lineBreakpoints) {
lineBreakpoints = [];
breakpoints[uiLocation.lineNumber] = lineBreakpoints;
}

lineBreakpoints.push(breakpoint);
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation});
},


_uiLocationRemoved: function(breakpoint, uiLocation)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
if (!breakpoints)
return;

var lineBreakpoints = breakpoints[uiLocation.lineNumber];
if (!lineBreakpoints)
return;

lineBreakpoints.remove(breakpoint);
if (!lineBreakpoints.length)
delete breakpoints[uiLocation.lineNumber];
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation});
},

__proto__: WebInspector.Object.prototype
}


WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, uiSourceCode, lineNumber, condition, enabled)
{
this._breakpointManager = breakpointManager;
this._primaryUILocation = new WebInspector.UILocation(uiSourceCode, lineNumber, 0);
this._sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode);

this._liveLocations = [];

this._uiLocations = {};


this._condition;
this._enabled;
this._updateBreakpoint(condition, enabled);
}

WebInspector.BreakpointManager.Breakpoint.prototype = {

primaryUILocation: function()
{
return this._primaryUILocation;
},


_addResolvedLocation: function(location)
{
this._liveLocations.push(this._breakpointManager._debuggerModel.createLiveLocation(location, this._locationUpdated.bind(this, location)));
},


_locationUpdated: function(location, uiLocation)
{
var stringifiedLocation = location.scriptId + ":" + location.lineNumber + ":" + location.columnNumber;
var oldUILocation =   (this._uiLocations[stringifiedLocation]);
if (oldUILocation)
this._breakpointManager._uiLocationRemoved(this, oldUILocation);
if (this._uiLocations[""]) {
delete this._uiLocations[""];
this._breakpointManager._uiLocationRemoved(this, this._primaryUILocation);
}
this._uiLocations[stringifiedLocation] = uiLocation;
this._breakpointManager._uiLocationAdded(this, uiLocation);
},


enabled: function()
{
return this._enabled;
},


setEnabled: function(enabled)
{
this._updateBreakpoint(this._condition, enabled);
},


condition: function()
{
return this._condition;
},


setCondition: function(condition)
{
this._updateBreakpoint(condition, this._enabled);
},


_updateBreakpoint: function(condition, enabled)
{
if (this._enabled === enabled && this._condition === condition)
return;

if (this._enabled)
this._removeFromDebugger();

this._enabled = enabled;
this._condition = condition;
this._breakpointManager._storage._updateBreakpoint(this);

var scriptFile = this._primaryUILocation.uiSourceCode.scriptFile();
if (this._enabled && !(scriptFile && scriptFile.hasDivergedFromVM())) {
this._setInDebugger();
return;
}

this._fakeBreakpointAtPrimaryLocation();
},


remove: function(keepInStorage)
{
var removeFromStorage = !keepInStorage;
this._resetLocations();
this._removeFromDebugger();
this._breakpointManager._removeBreakpoint(this, removeFromStorage);
},

_setInDebugger: function()
{
console.assert(!this._debuggerId);
var rawLocation = this._primaryUILocation.uiLocationToRawLocation();
var debuggerModelLocation =   (rawLocation);
if (debuggerModelLocation)
this._breakpointManager._debuggerModel.setBreakpointByScriptLocation(debuggerModelLocation, this._condition, didSetBreakpoint.bind(this));
else
this._breakpointManager._debuggerModel.setBreakpointByURL(this._primaryUILocation.uiSourceCode.url, this._primaryUILocation.lineNumber, 0, this._condition, didSetBreakpoint.bind(this));


function didSetBreakpoint(breakpointId, locations)
{
if (!breakpointId) {
this._resetLocations();
this._breakpointManager._removeBreakpoint(this, false);
return;
}

this._debuggerId = breakpointId;
this._breakpointManager._breakpointForDebuggerId[breakpointId] = this;

if (!locations.length) {
this._fakeBreakpointAtPrimaryLocation();
return;
}

this._resetLocations();
for (var i = 0; i < locations.length; ++i) {
var script = this._breakpointManager._debuggerModel.scriptForId(locations[i].scriptId);
var uiLocation = script.rawLocationToUILocation(locations[i].lineNumber, locations[i].columnNumber);
if (this._breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber)) {

this.remove();
return;
}
}

for (var i = 0; i < locations.length; ++i)
this._addResolvedLocation(locations[i]);
}
},

_removeFromDebugger: function()
{
if (this._debuggerId) {
this._breakpointManager._debuggerModel.removeBreakpoint(this._debuggerId);
delete this._breakpointManager._breakpointForDebuggerId[this._debuggerId];
delete this._debuggerId;
}
},

_resetLocations: function()
{
for (var stringifiedLocation in this._uiLocations)
this._breakpointManager._uiLocationRemoved(this, this._uiLocations[stringifiedLocation]);

for (var i = 0; i < this._liveLocations.length; ++i)
this._liveLocations[i].dispose();
this._liveLocations = [];

this._uiLocations = {};
},


_breakpointStorageId: function()
{
if (!this._sourceFileId)
return "";
return this._sourceFileId + ":" + this._primaryUILocation.lineNumber;
},

_fakeBreakpointAtPrimaryLocation: function()
{
this._resetLocations();
this._uiLocations[""] = this._primaryUILocation;
this._breakpointManager._uiLocationAdded(this, this._primaryUILocation);
}
}


WebInspector.BreakpointManager.Storage = function(breakpointManager, setting)
{
this._breakpointManager = breakpointManager;
this._setting = setting;
var breakpoints = this._setting.get();

this._breakpoints = {};
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint =   (breakpoints[i]);
this._breakpoints[breakpoint.sourceFileId + ":" + breakpoint.lineNumber] = breakpoint;
}
}

WebInspector.BreakpointManager.Storage.prototype = {

_restoreBreakpoints: function(uiSourceCode)
{
this._muted = true;
var sourceFileId = WebInspector.BreakpointManager.sourceFileId(uiSourceCode);
for (var id in this._breakpoints) {
var breakpoint = this._breakpoints[id];
if (breakpoint.sourceFileId === sourceFileId)
this._breakpointManager._innerSetBreakpoint(uiSourceCode, breakpoint.lineNumber, breakpoint.condition, breakpoint.enabled);
}
delete this._muted;
},


_updateBreakpoint: function(breakpoint)
{
if (this._muted || !breakpoint._breakpointStorageId())
return;
this._breakpoints[breakpoint._breakpointStorageId()] = new WebInspector.BreakpointManager.Storage.Item(breakpoint);
this._save();
},


_removeBreakpoint: function(breakpoint)
{
if (this._muted)
return;
delete this._breakpoints[breakpoint._breakpointStorageId()];
this._save();
},

_save: function()
{
var breakpointsArray = [];
for (var id in this._breakpoints)
breakpointsArray.push(this._breakpoints[id]);
this._setting.set(breakpointsArray);
}
}


WebInspector.BreakpointManager.Storage.Item = function(breakpoint)
{
var primaryUILocation = breakpoint.primaryUILocation();
this.sourceFileId = breakpoint._sourceFileId;
this.lineNumber = primaryUILocation.lineNumber;
this.condition = breakpoint.condition();
this.enabled = breakpoint.enabled();
}


WebInspector.breakpointManager = null;






WebInspector.ConcatenatedScriptsContentProvider = function(scripts)
{
this._mimeType = "text/html";
this._scripts = scripts;
}

WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag = "<script>";
WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag = "</script>";

WebInspector.ConcatenatedScriptsContentProvider.prototype = {

_sortedScripts: function()
{
if (this._sortedScriptsArray)
return this._sortedScriptsArray;

this._sortedScriptsArray = [];

var scripts = this._scripts.slice();
scripts.sort(function(x, y) { return x.lineOffset - y.lineOffset || x.columnOffset - y.columnOffset; });

var scriptOpenTagLength = WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag.length;
var scriptCloseTagLength = WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag.length;

this._sortedScriptsArray.push(scripts[0]);
for (var i = 1; i < scripts.length; ++i) {
var previousScript = this._sortedScriptsArray[this._sortedScriptsArray.length - 1];

var lineNumber = previousScript.endLine;
var columnNumber = previousScript.endColumn + scriptCloseTagLength + scriptOpenTagLength;

if (lineNumber < scripts[i].lineOffset || (lineNumber === scripts[i].lineOffset && columnNumber <= scripts[i].columnOffset))
this._sortedScriptsArray.push(scripts[i]);
}
return this._sortedScriptsArray;
},


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


contentType: function()
{
return WebInspector.resourceTypes.Document;
},


requestContent: function(callback)
{
var scripts = this._sortedScripts();
var sources = [];
function didRequestSource(content, contentEncoded, mimeType)
{
sources.push(content);
if (sources.length == scripts.length)
callback(this._concatenateScriptsContent(scripts, sources), false, this._mimeType);
}
for (var i = 0; i < scripts.length; ++i)
scripts[i].requestContent(didRequestSource.bind(this));
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
var results = {};
var scripts = this._sortedScripts();
var scriptsLeft = scripts.length;

function maybeCallback()
{
if (scriptsLeft)
return;

var result = [];
for (var i = 0; i < scripts.length; ++i)
result = result.concat(results[scripts[i].scriptId]);
callback(result);
}


function searchCallback(script, searchMatches)
{
results[script.scriptId] = [];
for (var i = 0; i < searchMatches.length; ++i) {
var searchMatch = new WebInspector.ContentProvider.SearchMatch(searchMatches[i].lineNumber + script.lineOffset, searchMatches[i].lineContent);
results[script.scriptId].push(searchMatch);
}
scriptsLeft--;
maybeCallback.call(this);
}

maybeCallback();
for (var i = 0; i < scripts.length; ++i)
scripts[i].searchInContent(query, caseSensitive, isRegex, searchCallback.bind(this, scripts[i]));
},


_concatenateScriptsContent: function(scripts, sources)
{
var content = "";
var lineNumber = 0;
var columnNumber = 0;

var scriptOpenTag = WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag;
var scriptCloseTag = WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag;
for (var i = 0; i < scripts.length; ++i) {

for (var newLinesCount = scripts[i].lineOffset - lineNumber; newLinesCount > 0; --newLinesCount) {
columnNumber = 0;
content += "\n";
}
for (var spacesCount = scripts[i].columnOffset - columnNumber - scriptOpenTag.length; spacesCount > 0; --spacesCount)
content += " ";


content += scriptOpenTag;
content += sources[i];
content += scriptCloseTag;
lineNumber = scripts[i].endLine;
columnNumber = scripts[i].endColumn + scriptCloseTag.length;
}

return content;
},

__proto__: WebInspector.ContentProvider.prototype
}


WebInspector.CompilerSourceMappingContentProvider = function(sourceURL)
{
this._sourceURL = sourceURL;
}

WebInspector.CompilerSourceMappingContentProvider.prototype = {

contentURL: function()
{
return this._sourceURL;
},


contentType: function()
{
return WebInspector.resourceTypes.Script;
},


requestContent: function(callback)
{
var sourceCode = "";
try {

sourceCode = InspectorFrontendHost.loadResourceSynchronously(this._sourceURL);
} catch(e) {
console.error(e.message);
}
callback(sourceCode, false, "text/javascript");
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
callback([]);
},

__proto__: WebInspector.ContentProvider.prototype
}


WebInspector.StaticContentProvider = function(contentType, content, mimeType)
{
this._content = content;
this._contentType = contentType;
this._mimeType = mimeType;
}

WebInspector.StaticContentProvider.prototype = {

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


contentType: function()
{
return this._contentType;
},


requestContent: function(callback)
{
callback(this._content, false, this._mimeType || this._contentType.canonicalMimeType());
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
function performSearch()
{
callback(WebInspector.ContentProvider.performSearchInContent(this._content, query, caseSensitive, isRegex));
}


window.setTimeout(performSearch.bind(this), 0);
},

__proto__: WebInspector.ContentProvider.prototype
}






WebInspector.DefaultScriptMapping = function(workspace)
{
this._projectDelegate = new WebInspector.DebuggerProjectDelegate();
this._workspace = workspace;
this._workspace.addProject(this._projectDelegate);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
this._debuggerReset();
}

WebInspector.DefaultScriptMapping.prototype = {

rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation =   (rawLocation);
var script = WebInspector.debuggerModel.scriptForId(debuggerModelLocation.scriptId);
var uiSourceCode = this._uiSourceCodeForScriptId[script.scriptId];
var lineNumber = debuggerModelLocation.lineNumber;
var columnNumber = debuggerModelLocation.columnNumber || 0;
return new WebInspector.UILocation(uiSourceCode, lineNumber, columnNumber);
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var scriptId = this._scriptIdForUISourceCode.get(uiSourceCode);
var script = WebInspector.debuggerModel.scriptForId(scriptId);
return WebInspector.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
},


isIdentity: function()
{
return true;
},


addScript: function(script)
{
var path = this._projectDelegate.addScript(script);
var uiSourceCode = this._workspace.uiSourceCode(this._projectDelegate.id(), path);
this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
this._scriptIdForUISourceCode.put(uiSourceCode, script.scriptId);
uiSourceCode.setSourceMapping(this);
script.pushSourceMapping(this);
script.addEventListener(WebInspector.Script.Events.ScriptEdited, this._scriptEdited.bind(this, script.scriptId));
return uiSourceCode;
},


_scriptEdited: function(scriptId, event)
{
var content =  (event.data);
this._uiSourceCodeForScriptId[scriptId].addRevision(content);
},

_debuggerReset: function()
{

this._uiSourceCodeForScriptId = {};
this._scriptIdForUISourceCode = new Map();
this._projectDelegate.reset();
}
}


WebInspector.DebuggerProjectDelegate = function()
{
WebInspector.ContentProviderBasedProjectDelegate.call(this, WebInspector.projectTypes.Debugger);
}

WebInspector.DebuggerProjectDelegate.prototype = {

id: function()
{
return "debugger:";
},


displayName: function()
{
return "debugger";
},


addScript: function(script)
{
var contentProvider = script.isInlineScript() ? new WebInspector.ConcatenatedScriptsContentProvider([script]) : script;
var splittedURL = WebInspector.ParsedURL.splitURL(script.sourceURL);
var name = splittedURL[splittedURL.length - 1];
name = "[VM] " + name + " (" + script.scriptId + ")";
return this.addContentProvider([name], script.sourceURL, contentProvider, false, script.isContentScript);
},

__proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype
}






WebInspector.ResourceScriptMapping = function(workspace)
{
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);

WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
this._initialize();
}

WebInspector.ResourceScriptMapping.prototype = {

rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation =   (rawLocation);
var script = WebInspector.debuggerModel.scriptForId(debuggerModelLocation.scriptId);
var uiSourceCode = this._workspaceUISourceCodeForScript(script);
if (!uiSourceCode)
return null;
var scriptFile = uiSourceCode.scriptFile();
if (scriptFile && ((scriptFile.hasDivergedFromVM() && !scriptFile.isMergingToVM()) || scriptFile.isDivergingFromVM()))
return null;
return new WebInspector.UILocation(uiSourceCode, debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0);
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var scripts = this._scriptsForUISourceCode(uiSourceCode);
console.assert(scripts.length);
return WebInspector.debuggerModel.createRawLocation(scripts[0], lineNumber, columnNumber);
},


isIdentity: function()
{
return true;
},


addScript: function(script)
{
if (script.isAnonymousScript() || script.isDynamicScript())
return;
script.pushSourceMapping(this);

var scriptsForSourceURL = script.isInlineScript() ? this._inlineScriptsForSourceURL : this._nonInlineScriptsForSourceURL;
scriptsForSourceURL[script.sourceURL] = scriptsForSourceURL[script.sourceURL] || [];
scriptsForSourceURL[script.sourceURL].push(script);

var uiSourceCode = this._workspaceUISourceCodeForScript(script);
if (!uiSourceCode)
return;

this._bindUISourceCodeToScripts(uiSourceCode, [script]);
},

_uiSourceCodeAddedToWorkspace: function(event)
{
var uiSourceCode =   (event.data);
if (!uiSourceCode.url)
return;

var scripts = this._scriptsForUISourceCode(uiSourceCode);
if (!scripts.length)
return;

this._bindUISourceCodeToScripts(uiSourceCode, scripts);
},


_hasMergedToVM: function(uiSourceCode)
{
var scripts = this._scriptsForUISourceCode(uiSourceCode);
if (!scripts.length)
return;
for (var i = 0; i < scripts.length; ++i)
scripts[i].updateLocations();
},


_hasDivergedFromVM: function(uiSourceCode)
{
var scripts = this._scriptsForUISourceCode(uiSourceCode);
if (!scripts.length)
return;
for (var i = 0; i < scripts.length; ++i)
scripts[i].updateLocations();
},


_workspaceUISourceCodeForScript: function(script)
{
if (script.isAnonymousScript() || script.isDynamicScript())
return null;

if (!script.isInlineScript() && this._inlineScriptsForSourceURL[script.sourceURL])
return null;
return this._workspace.uiSourceCodeForURL(script.sourceURL);
},


_scriptsForUISourceCode: function(uiSourceCode)
{
var isInlineScript;
switch (uiSourceCode.contentType()) {
case WebInspector.resourceTypes.Document:
isInlineScript = true;
break;
case WebInspector.resourceTypes.Script:
isInlineScript = false;
break;
default:
return [];
}
if (!uiSourceCode.url)
return [];
var scriptsForSourceURL = isInlineScript ? this._inlineScriptsForSourceURL : this._nonInlineScriptsForSourceURL;
return scriptsForSourceURL[uiSourceCode.url] || [];
},


_bindUISourceCodeToScripts: function(uiSourceCode, scripts)
{
console.assert(scripts.length);
var scriptFile = new WebInspector.ResourceScriptFile(this, uiSourceCode, scripts);
uiSourceCode.setScriptFile(scriptFile);
for (var i = 0; i < scripts.length; ++i)
scripts[i].updateLocations();
uiSourceCode.setSourceMapping(this);
},


_unbindUISourceCodeFromScripts: function(uiSourceCode, scripts)
{
console.assert(scripts.length);
var scriptFile =   (uiSourceCode.scriptFile());
scriptFile.dispose();
uiSourceCode.setScriptFile(null);
uiSourceCode.setSourceMapping(null);
},

_initialize: function()
{

this._inlineScriptsForSourceURL = {};

this._nonInlineScriptsForSourceURL = {};
},

_debuggerReset: function()
{

function unbindUISourceCodes(scriptsForSourceURL)
{
for (var sourceURL in scriptsForSourceURL) {
var scripts = scriptsForSourceURL[sourceURL];
if (!scripts.length)
continue;
var uiSourceCode = this._workspaceUISourceCodeForScript(scripts[0]);
if (!uiSourceCode)
continue;
this._unbindUISourceCodeFromScripts(uiSourceCode, scripts);
}
}

unbindUISourceCodes.call(this, this._inlineScriptsForSourceURL);
unbindUISourceCodes.call(this, this._nonInlineScriptsForSourceURL);
this._initialize();
},
}


WebInspector.ScriptFile = function()
{
}

WebInspector.ScriptFile.Events = {
DidMergeToVM: "DidMergeToVM",
DidDivergeFromVM: "DidDivergeFromVM",
}

WebInspector.ScriptFile.prototype = {

hasDivergedFromVM: function() { return false; },


isDivergingFromVM: function() { return false; },


isMergingToVM: function() { return false; },

checkMapping: function() { },
}


WebInspector.ResourceScriptFile = function(resourceScriptMapping, uiSourceCode, scripts)
{
console.assert(scripts.length);

WebInspector.ScriptFile.call(this);
this._resourceScriptMapping = resourceScriptMapping;
this._uiSourceCode = uiSourceCode;

if (this._uiSourceCode.contentType() === WebInspector.resourceTypes.Script)
this._script = scripts[0];

this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._update();
}

WebInspector.ResourceScriptFile.prototype = {
_workingCopyCommitted: function(event)
{

function innerCallback(error)
{
if (error) {
this._update();
WebInspector.showErrorMessage(error);
return;
}

this._scriptSource = source;
this._update();
}
if (!this._script)
return;
var source = this._uiSourceCode.workingCopy();
if (this._script.hasSourceURL && !this._sourceEndsWithSourceURL(source))
source += "\n //@ sourceURL=" + this._script.sourceURL;
WebInspector.debuggerModel.setScriptSource(this._script.scriptId, source, innerCallback.bind(this));
},


_isDiverged: function()
{
if (this._uiSourceCode.formatted())
return false;
if (this._uiSourceCode.isDirty())
return true;
if (!this._script)
return false;
if (typeof this._scriptSource === "undefined")
return false;
return !this._sourceMatchesScriptSource(this._uiSourceCode.workingCopy(), this._scriptSource);
},


_sourceMatchesScriptSource: function(source, scriptSource)
{
if (!scriptSource.startsWith(source))
return false;
var scriptSourceTail = scriptSource.substr(source.length).trim();
return !scriptSourceTail || !!scriptSourceTail.match(/^\/\/@\ssourceURL=\s*(\S*?)\s*$/m);
},


_sourceEndsWithSourceURL: function(source)
{
return !!source.match(/\/\/@\ssourceURL=\s*(\S*?)\s*$/m);
},


_workingCopyChanged: function(event)
{
this._update();
},

_update: function()
{
if (this._isDiverged() && !this._hasDivergedFromVM)
this._divergeFromVM();
else if (!this._isDiverged() && this._hasDivergedFromVM)
this._mergeToVM();
},

_divergeFromVM: function()
{
this._isDivergingFromVM = true;
this._resourceScriptMapping._hasDivergedFromVM(this._uiSourceCode);
delete this._isDivergingFromVM;
this._hasDivergedFromVM = true;
this.dispatchEventToListeners(WebInspector.ScriptFile.Events.DidDivergeFromVM, this._uiSourceCode);
},

_mergeToVM: function()
{
delete this._hasDivergedFromVM;
this._isMergingToVM = true;
this._resourceScriptMapping._hasMergedToVM(this._uiSourceCode);
delete this._isMergingToVM;
this.dispatchEventToListeners(WebInspector.ScriptFile.Events.DidMergeToVM, this._uiSourceCode);
},


hasDivergedFromVM: function()
{
return this._hasDivergedFromVM;
},


isDivergingFromVM: function()
{
return this._isDivergingFromVM;
},


isMergingToVM: function()
{
return this._isMergingToVM;
},

checkMapping: function()
{
if (!this._script)
return;
if (typeof this._scriptSource !== "undefined")
return;
this._script.requestContent(callback.bind(this));


function callback(source, encoded, contentType)
{
this._scriptSource = source;
this._update();
}
},

dispose: function()
{
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
},

__proto__: WebInspector.Object.prototype
}






WebInspector.CompilerScriptMapping = function(workspace, networkWorkspaceProvider)
{
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);
this._networkWorkspaceProvider = networkWorkspaceProvider;

this._sourceMapForSourceMapURL = {};

this._sourceMapForScriptId = {};
this._scriptForSourceMap = new Map();

this._sourceMapForURL = {};
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
}

WebInspector.CompilerScriptMapping.prototype = {

rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation =   (rawLocation);
var sourceMap = this._sourceMapForScriptId[debuggerModelLocation.scriptId];
var lineNumber = debuggerModelLocation.lineNumber;
var columnNumber = debuggerModelLocation.columnNumber || 0;
var entry = sourceMap.findEntry(lineNumber, columnNumber);
if (!entry || entry.length === 2)
return null;
var url = entry[2];
var uiSourceCode = this._workspace.uiSourceCodeForURL(url);
if (!uiSourceCode)
return null;
return new WebInspector.UILocation(uiSourceCode, entry[3], entry[4]);
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
if (!uiSourceCode.url)
return null;
var sourceMap = this._sourceMapForURL[uiSourceCode.url];
if (!sourceMap)
return null;
var entry = sourceMap.findEntryReversed(uiSourceCode.url, lineNumber);
return WebInspector.debuggerModel.createRawLocation(this._scriptForSourceMap.get(sourceMap), entry[0], entry[1]);
},


isIdentity: function()
{
return false;
},


addScript: function(script)
{
var sourceMap = this.loadSourceMapForScript(script);
if (!sourceMap)
return;

if (this._scriptForSourceMap.get(sourceMap)) {
this._sourceMapForScriptId[script.scriptId] = sourceMap;
script.pushSourceMapping(this);
return;
}

this._sourceMapForScriptId[script.scriptId] = sourceMap;
this._scriptForSourceMap.put(sourceMap, script);

var sourceURLs = sourceMap.sources();
for (var i = 0; i < sourceURLs.length; ++i) {
var sourceURL = sourceURLs[i];
if (this._sourceMapForURL[sourceURL])
continue;
this._sourceMapForURL[sourceURL] = sourceMap;
if (!this._workspace.hasMappingForURL(sourceURL) && !this._workspace.uiSourceCodeForURL(sourceURL)) {
var sourceContent = sourceMap.sourceContent(sourceURL);
var contentProvider;
if (sourceContent)
contentProvider = new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Script, sourceContent);
else
contentProvider = new WebInspector.CompilerSourceMappingContentProvider(sourceURL);
this._networkWorkspaceProvider.addFileForURL(sourceURL, contentProvider, true);
}
var uiSourceCode = this._workspace.uiSourceCodeForURL(sourceURL);
if (uiSourceCode) {
this._bindUISourceCode(uiSourceCode);
uiSourceCode.isContentScript = script.isContentScript;
}
}
script.pushSourceMapping(this);
},


_bindUISourceCode: function(uiSourceCode)
{
uiSourceCode.setSourceMapping(this);
},


_uiSourceCodeAddedToWorkspace: function(event)
{
var uiSourceCode =   (event.data);
if (!uiSourceCode.url || !this._sourceMapForURL[uiSourceCode.url])
return;
this._bindUISourceCode(uiSourceCode);
},


loadSourceMapForScript: function(script)
{


if (!script.sourceMapURL)
return null;
var scriptURL = WebInspector.ParsedURL.completeURL(WebInspector.inspectedPageURL, script.sourceURL);
if (!scriptURL)
return null;
var sourceMapURL = WebInspector.ParsedURL.completeURL(scriptURL, script.sourceMapURL);
if (!sourceMapURL)
return null;
var sourceMap = this._sourceMapForSourceMapURL[sourceMapURL];
if (sourceMap)
return sourceMap;

sourceMap = WebInspector.SourceMap.load(sourceMapURL, scriptURL);
if (!sourceMap)
return null;
this._sourceMapForSourceMapURL[sourceMapURL] = sourceMap;
return sourceMap;
},

_debuggerReset: function()
{
this._sourceMapForSourceMapURL = {};
this._sourceMapForScriptId = {};
this._scriptForSourceMap = new Map();
this._sourceMapForURL = {};
}
}






WebInspector.LiveEditSupport = function(workspace)
{
this._workspaceProvider = new WebInspector.SimpleWorkspaceProvider(workspace, WebInspector.projectTypes.LiveEdit);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
this._debuggerReset();
}

WebInspector.LiveEditSupport.prototype = {

uiSourceCodeForLiveEdit: function(uiSourceCode)
{
var rawLocation = uiSourceCode.uiLocationToRawLocation(0, 0);
var debuggerModelLocation =   (rawLocation);
var script = WebInspector.debuggerModel.scriptForId(debuggerModelLocation.scriptId);
var uiLocation = script.rawLocationToUILocation(0, 0);


if (uiLocation.uiSourceCode !== uiSourceCode)
return uiLocation.uiSourceCode;
if (this._uiSourceCodeForScriptId[script.scriptId])
return this._uiSourceCodeForScriptId[script.scriptId];

console.assert(!script.isInlineScript());
var liveEditUISourceCode = this._workspaceProvider.addUniqueFileForURL(script.sourceURL, script, true, script.isContentScript);

liveEditUISourceCode.setScriptFile(new WebInspector.LiveEditScriptFile(uiSourceCode, liveEditUISourceCode, script.scriptId));
this._uiSourceCodeForScriptId[script.scriptId] = liveEditUISourceCode;
this._scriptIdForUISourceCode.put(liveEditUISourceCode, script.scriptId);
return liveEditUISourceCode;
},

_debuggerReset: function()
{

this._uiSourceCodeForScriptId = {};
this._scriptIdForUISourceCode = new Map();
this._workspaceProvider.reset();
},
}


WebInspector.LiveEditScriptFile = function(uiSourceCode, liveEditUISourceCode, scriptId)
{
WebInspector.ScriptFile.call(this);
this._uiSourceCode = uiSourceCode;
this._liveEditUISourceCode = liveEditUISourceCode;
this._scriptId = scriptId;
this._liveEditUISourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
}

WebInspector.LiveEditScriptFile.prototype = {
_workingCopyCommitted: function(event)
{

function innerCallback(error)
{
if (error) {
WebInspector.showErrorMessage(error);
return;
}
}

var script = WebInspector.debuggerModel.scriptForId(this._scriptId);
WebInspector.debuggerModel.setScriptSource(script.scriptId, this._liveEditUISourceCode.workingCopy(), innerCallback.bind(this));
},


hasDivergedFromVM: function()
{
return true;
},


isDivergingFromVM: function()
{
return false;
},


isMergingToVM: function()
{
return false;
},

checkMapping: function()
{
},

__proto__: WebInspector.Object.prototype
}


WebInspector.liveEditSupport = null;






WebInspector.SASSSourceMapping = function(cssModel, workspace, networkWorkspaceProvider)
{
this._cssModel = cssModel;
this._workspace = workspace;
this._networkWorkspaceProvider = networkWorkspaceProvider;
this._sourceMapByURL = {};
this._sourceMapByStyleSheetURL = {};
this._cssURLsForSASSURL = {};
this._timeoutForURL = {};
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.SavedURL, this._fileSaveFinished, this);
this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetChanged, this);
this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeContentCommitted, this._uiSourceCodeContentCommitted, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._reset, this);
}

WebInspector.SASSSourceMapping.prototype = {
_populate: function()
{
function populateFrame(frame)
{
for (var i = 0; i < frame.childFrames.length; ++i)
populateFrame.call(this, frame.childFrames[i]);

var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this._resourceAdded({data:resources[i]});
}

populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
},


_styleSheetChanged: function(event)
{
var isAddingRevision = this._isAddingRevision;
delete this._isAddingRevision;

if (isAddingRevision)
return;
var url = this._cssModel.resourceBinding().resourceURLForStyleSheetId(event.data.styleSheetId);
if (!url)
return;
this._cssModel.setSourceMapping(url, null);
},


_fileSaveFinished: function(event)
{
var sassURL =   (event.data);
this._sassFileSaved(sassURL);
},


_sassFileSaved: function(sassURL)
{
function callback()
{
delete this._timeoutForURL[sassURL];
var cssURLs = this._cssURLsForSASSURL[sassURL];
if (!cssURLs)
return;
for (var i = 0; i < cssURLs.length; ++i)
this._reloadCSS(cssURLs[i]);
}

var timer = this._timeoutForURL[sassURL];
if (timer) {
clearTimeout(timer);
delete this._timeoutForURL[sassURL];
}
if (!WebInspector.settings.cssReloadEnabled.get() || !this._cssURLsForSASSURL[sassURL])
return;
var timeout = WebInspector.settings.cssReloadTimeout.get();
if (timeout && isFinite(timeout))
this._timeoutForURL[sassURL] = setTimeout(callback.bind(this), Number(timeout));
},

_reloadCSS: function(url)
{
var uiSourceCode = this._workspace.uiSourceCodeForURL(url);
if (!uiSourceCode)
return;
var newContent = InspectorFrontendHost.loadResourceSynchronously(url);
this._isAddingRevision = true;
uiSourceCode.addRevision(newContent);

this._loadAndProcessSourceMap(newContent, url, true);
},


_resourceAdded: function(event)
{
var resource =   (event.data);
if (resource.type !== WebInspector.resourceTypes.Stylesheet)
return;


function didRequestContent(content, contentEncoded, mimeType)
{
this._loadAndProcessSourceMap(content, resource.url);
}
resource.requestContent(didRequestContent.bind(this));
},


_loadAndProcessSourceMap: function(content, cssURL, forceRebind)
{
if (!content)
return;
var lines = content.split(/\r?\n/);
if (!lines.length)
return;

const sourceMapRegex = /^\/\*@ sourceMappingURL=([^\s]+)\s*\*\/$/;
var lastLine = lines[lines.length - 1];
var match = lastLine.match(sourceMapRegex);
if (!match)
return;

if (!forceRebind && this._sourceMapByStyleSheetURL[cssURL])
return;
var sourceMap = this.loadSourceMapForStyleSheet(match[1], cssURL, forceRebind);

if (!sourceMap)
return;
this._sourceMapByStyleSheetURL[cssURL] = sourceMap;
this._bindUISourceCode(cssURL, sourceMap);
},


_addCSSURLforSASSURL: function(cssURL, sassURL)
{
var cssURLs;
if (this._cssURLsForSASSURL.hasOwnProperty(sassURL))
cssURLs = this._cssURLsForSASSURL[sassURL];
else {
cssURLs = [];
this._cssURLsForSASSURL[sassURL] = cssURLs;
}
if (cssURLs.indexOf(cssURL) === -1)
cssURLs.push(cssURL);
},


loadSourceMapForStyleSheet: function(sourceMapURL, styleSheetURL, forceReload)
{
var completeStyleSheetURL = WebInspector.ParsedURL.completeURL(WebInspector.inspectedPageURL, styleSheetURL);
if (!completeStyleSheetURL)
return null;
var completeSourceMapURL = WebInspector.ParsedURL.completeURL(completeStyleSheetURL, sourceMapURL);
if (!completeSourceMapURL)
return null;
var sourceMap = this._sourceMapByURL[completeSourceMapURL];
if (sourceMap && !forceReload)
return sourceMap;
sourceMap = WebInspector.SourceMap.load(completeSourceMapURL, completeStyleSheetURL);
if (!sourceMap) {
delete this._sourceMapByURL[completeSourceMapURL];
return null;
}
this._sourceMapByURL[completeSourceMapURL] = sourceMap;
return sourceMap;
},


_bindUISourceCode: function(rawURL, sourceMap)
{
this._cssModel.setSourceMapping(rawURL, this);
var sources = sourceMap.sources();
for (var i = 0; i < sources.length; ++i) {
var url = sources[i];
if (!this._workspace.hasMappingForURL(url)) {
if (!this._workspace.uiSourceCodeForURL(url)) {
var content = InspectorFrontendHost.loadResourceSynchronously(url);
var contentProvider = new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Stylesheet, content, "text/x-scss");
var uiSourceCode = this._networkWorkspaceProvider.addFileForURL(url, contentProvider, true);
uiSourceCode.setSourceMapping(this);
this._addCSSURLforSASSURL(rawURL, url);
}
} else
this._addCSSURLforSASSURL(rawURL, url);
}
},


rawLocationToUILocation: function(rawLocation)
{
var location =   (rawLocation);
var entry;
var sourceMap = this._sourceMapByStyleSheetURL[location.url];
if (!sourceMap)
return null;
entry = sourceMap.findEntry(location.lineNumber, location.columnNumber);
if (!entry || entry.length === 2)
return null;
var uiSourceCode = this._workspace.uiSourceCodeForURL(entry[2]);
if (!uiSourceCode)
return null;
return new WebInspector.UILocation(uiSourceCode, entry[3], entry[4]);
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{

return new WebInspector.CSSLocation(uiSourceCode.url || "", lineNumber, columnNumber);
},


isIdentity: function()
{
return false;
},


_uiSourceCodeAdded: function(event)
{
var uiSourceCode =   (event.data);
var cssURLs = this._cssURLsForSASSURL[uiSourceCode.url];


for (var i = 0; cssURLs && i < cssURLs.length; ++i)
this._cssModel.setSourceMapping(cssURLs[i], this);
uiSourceCode.setSourceMapping(this);
},


_uiSourceCodeContentCommitted: function(event)
{
var uiSourceCode =   (event.data.uiSourceCode);
this._sassFileSaved(uiSourceCode.url);
},

_reset: function()
{
this._sourceMapByURL = {};
this._sourceMapByStyleSheetURL = {};
this._populate();
}
}






WebInspector.DOMNode = function(domAgent, doc, isInShadowTree, payload) {
this._domAgent = domAgent;
this.ownerDocument = doc;
this._isInShadowTree = isInShadowTree;

this.id = payload.nodeId;
domAgent._idToDOMNode[this.id] = this;
this._nodeType = payload.nodeType;
this._nodeName = payload.nodeName;
this._localName = payload.localName;
this._nodeValue = payload.nodeValue;

this._shadowRoots = [];

this._attributes = [];
this._attributesMap = {};
if (payload.attributes)
this._setAttributesPayload(payload.attributes);

this._userProperties = {};
this._descendantUserPropertyCounters = {};

this._childNodeCount = payload.childNodeCount;
this.children = null;

this.nextSibling = null;
this.previousSibling = null;
this.firstChild = null;
this.lastChild = null;
this.parentNode = null;

if (payload.shadowRoots && WebInspector.settings.showShadowDOM.get()) {
for (var i = 0; i < payload.shadowRoots.length; ++i) {
var root = payload.shadowRoots[i];
var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, true, root);
this._shadowRoots.push(node);
}
}

if (payload.templateContent)
this._templateContent = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, true, payload.templateContent);

if (payload.children)
this._setChildrenPayload(payload.children);

if (payload.contentDocument) {
this._contentDocument = new WebInspector.DOMDocument(domAgent, payload.contentDocument);
this.children = [this._contentDocument];
this._renumber();
}

if (this._nodeType === Node.ELEMENT_NODE) {

if (this.ownerDocument && !this.ownerDocument.documentElement && this._nodeName === "HTML")
this.ownerDocument.documentElement = this;
if (this.ownerDocument && !this.ownerDocument.body && this._nodeName === "BODY")
this.ownerDocument.body = this;
} 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.ATTRIBUTE_NODE) {
this.name = payload.name;
this.value = payload.value;
}
}


WebInspector.DOMNode.XPathStep = function(value, optimized)
{
this.value = value;
this.optimized = optimized;
}

WebInspector.DOMNode.XPathStep.prototype = {
toString: function()
{
return this.value;
}
}

WebInspector.DOMNode.prototype = {

hasAttributes: function()
{
return this._attributes.length > 0;
},


hasChildNodes: function()
{
return this._childNodeCount > 0 || !!this._shadowRoots.length || !!this._templateContent;
},


hasShadowRoots: function()
{
return !!this._shadowRoots.length;
},


nodeType: function()
{
return this._nodeType;
},


nodeName: function()
{
return this._nodeName;
},


isInShadowTree: function()
{
return this._isInShadowTree;
},


nodeNameInCorrectCase: function()
{
return this.isXMLNode() ? this.nodeName() : this.nodeName().toLowerCase();
},


setNodeName: function(name, callback)
{
DOMAgent.setNodeName(this.id, name, WebInspector.domAgent._markRevision(this, callback));
},


localName: function()
{
return this._localName;
},


nodeValue: function()
{
return this._nodeValue;
},


setNodeValue: function(value, callback)
{
DOMAgent.setNodeValue(this.id, value, WebInspector.domAgent._markRevision(this, callback));
},


getAttribute: function(name)
{
var attr = this._attributesMap[name];
return attr ? attr.value : undefined;
},


setAttribute: function(name, text, callback)
{
DOMAgent.setAttributesAsText(this.id, text, name, WebInspector.domAgent._markRevision(this, callback));
},


setAttributeValue: function(name, value, callback)
{
DOMAgent.setAttributeValue(this.id, name, value, WebInspector.domAgent._markRevision(this, callback));
},


attributes: function()
{
return this._attributes;
},


removeAttribute: function(name, callback)
{

function mycallback(error)
{
if (!error) {
delete this._attributesMap[name];
for (var i = 0;  i < this._attributes.length; ++i) {
if (this._attributes[i].name === name) {
this._attributes.splice(i, 1);
break;
}
}
}

WebInspector.domAgent._markRevision(this, callback)(error);
}
DOMAgent.removeAttribute(this.id, name, mycallback.bind(this));
},


getChildNodes: function(callback)
{
if (this.children) {
if (callback)
callback(this.children);
return;
}


function mycallback(error)
{
if (!error && callback)
callback(this.children);
}

DOMAgent.requestChildNodes(this.id, undefined, mycallback.bind(this));
},


getSubtree: function(depth, callback)
{

function mycallback(error)
{
if (callback)
callback(error ? null : this.children);                
}

DOMAgent.requestChildNodes(this.id, depth, mycallback.bind(this));
},


getOuterHTML: function(callback)
{
DOMAgent.getOuterHTML(this.id, callback);
},


setOuterHTML: function(html, callback)
{
DOMAgent.setOuterHTML(this.id, html, WebInspector.domAgent._markRevision(this, callback));
},


removeNode: function(callback)
{
DOMAgent.removeNode(this.id, WebInspector.domAgent._markRevision(this, callback));
},

copyNode: function()
{
function copy(error, text)
{
if (!error)
InspectorFrontendHost.copyText(text);
}
DOMAgent.getOuterHTML(this.id, copy);
},


copyXPath: function(optimized)
{
InspectorFrontendHost.copyText(this.xPath(optimized));
},


eventListeners: function(objectGroupId, callback)
{
DOMAgent.getEventListenersForNode(this.id, objectGroupId, 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(",");
},


appropriateSelectorFor: function(justSelector)
{
var lowerCaseName = this.localName() || this.nodeName().toLowerCase();

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

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

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

return lowerCaseName;
},


isAncestor: function(node)
{
if (!node)
return false;

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


isDescendant: function(descendant)
{
return descendant !== null && descendant.isAncestor(this);
},


_setAttributesPayload: function(attrs)
{
var attributesChanged = !this._attributes || attrs.length !== this._attributes.length * 2;
var oldAttributesMap = this._attributesMap || {};

this._attributes = [];
this._attributesMap = {};

for (var i = 0; i < attrs.length; i += 2) {
var name = attrs[i];
var value = attrs[i + 1];
this._addAttribute(name, value);

if (attributesChanged)
continue;

if (!oldAttributesMap[name] || oldAttributesMap[name].value !== value)
attributesChanged = true;
}
return attributesChanged;
},


_insertChild: function(prev, payload)
{
var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, this._isInShadowTree, payload);
if (!prev) {
if (!this.children) {

this.children = this._shadowRoots.slice();
if (this._templateContent)
this.children.push(this._templateContent);

this.children.push(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;
node._updateChildUserPropertyCountsOnRemoval(this);
this._renumber();
},


_setChildrenPayload: function(payloads)
{

if (this._contentDocument)
return;

this.children = this._shadowRoots.slice();
if (this._templateContent)
this.children.push(this._templateContent);

for (var i = 0; i < payloads.length; ++i) {
var payload = payloads[i];
var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, this._isInShadowTree, 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.previousSibling = 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);
},


_setAttribute: function(name, value)
{
var attr = this._attributesMap[name];
if (attr)
attr.value = value;
else
this._addAttribute(name, value);
},


_removeAttribute: function(name)
{
var attr = this._attributesMap[name];
if (attr) {
this._attributes.remove(attr);
delete this._attributesMap[name];
}
},


moveTo: function(targetNode, anchorNode, callback)
{
DOMAgent.moveTo(this.id, targetNode.id, anchorNode ? anchorNode.id : undefined, WebInspector.domAgent._markRevision(this, callback));
},


isXMLNode: function()
{
return !!this.ownerDocument && !!this.ownerDocument.xmlVersion;
},


xPath: function(optimized)
{
if (this._nodeType === Node.DOCUMENT_NODE)
return "/";

var steps = [];
var contextNode = this;
while (contextNode) {
var step = contextNode._xPathValue(optimized);
if (!step)
break; 
steps.push(step);
if (step.optimized)
break;
contextNode = contextNode.parentNode;
}

steps.reverse();
return (steps.length && steps[0].optimized ? "" : "/") + steps.join("/");
},


_xPathValue: function(optimized)
{
var ownValue;
var ownIndex = this._xPathIndex();
if (ownIndex === -1)
return null; 

switch (this._nodeType) {
case Node.ELEMENT_NODE:
if (optimized && this.getAttribute("id"))
return new WebInspector.DOMNode.XPathStep("//*[@id=\"" + this.getAttribute("id") + "\"]", true);
ownValue = this._localName;
break;
case Node.ATTRIBUTE_NODE:
ownValue = "@" + this._nodeName;
break;
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
ownValue = "text()";
break;
case Node.PROCESSING_INSTRUCTION_NODE:
ownValue = "processing-instruction()";
break;
case Node.COMMENT_NODE:
ownValue = "comment()";
break;
case Node.DOCUMENT_NODE:
ownValue = "";
break;
default:
ownValue = "";
break;
}

if (ownIndex > 0)
ownValue += "[" + ownIndex + "]";

return new WebInspector.DOMNode.XPathStep(ownValue, this._nodeType === Node.DOCUMENT_NODE);
},


_xPathIndex: function()
{

function areNodesSimilar(left, right)
{
if (left === right)
return true;

if (left._nodeType === Node.ELEMENT_NODE && right._nodeType === Node.ELEMENT_NODE)
return left._localName === right._localName;

if (left._nodeType === right._nodeType)
return true;


var leftType = left._nodeType === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : left._nodeType;
var rightType = right._nodeType === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : right._nodeType;
return leftType === rightType;
}

var siblings = this.parentNode ? this.parentNode.children : null;
if (!siblings)
return 0; 
var hasSameNamedElements;
for (var i = 0; i < siblings.length; ++i) {
if (areNodesSimilar(this, siblings[i]) && siblings[i] !== this) {
hasSameNamedElements = true;
break;
}
}
if (!hasSameNamedElements)
return 0;
var ownIndex = 1; 
for (var i = 0; i < siblings.length; ++i) {
if (areNodesSimilar(this, siblings[i])) {
if (siblings[i] === this)
return ownIndex;
++ownIndex;
}
}
return -1; 
},

_updateChildUserPropertyCountsOnRemoval: function(parentNode)
{
var result = {};
if (this._userProperties) {
for (var name in this._userProperties)
result[name] = (result[name] || 0) + 1;
}

if (this._descendantUserPropertyCounters) {
for (var name in this._descendantUserPropertyCounters) {
var counter = this._descendantUserPropertyCounters[name];
result[name] = (result[name] || 0) + counter;
}
}

for (var name in result)
parentNode._updateDescendantUserPropertyCount(name, -result[name]);
},

_updateDescendantUserPropertyCount: function(name, delta)
{
if (!this._descendantUserPropertyCounters.hasOwnProperty(name))
this._descendantUserPropertyCounters[name] = 0;
this._descendantUserPropertyCounters[name] += delta;
if (!this._descendantUserPropertyCounters[name])
delete this._descendantUserPropertyCounters[name];
if (this.parentNode)
this.parentNode._updateDescendantUserPropertyCount(name, delta);
},

setUserProperty: function(name, value)
{
if (value === null) {
this.removeUserProperty(name);
return;
}

if (this.parentNode && !this._userProperties.hasOwnProperty(name))
this.parentNode._updateDescendantUserPropertyCount(name, 1);

this._userProperties[name] = value;
},

removeUserProperty: function(name)
{
if (!this._userProperties.hasOwnProperty(name))
return;

delete this._userProperties[name];
if (this.parentNode)
this.parentNode._updateDescendantUserPropertyCount(name, -1);
},

getUserProperty: function(name)
{
return this._userProperties ? this._userProperties[name] : null;
},

descendantUserPropertyCount: function(name)
{
return this._descendantUserPropertyCounters && this._descendantUserPropertyCounters[name] ? this._descendantUserPropertyCounters[name] : 0;
},


resolveURL: function(url)
{
if (!url)
return url;
for (var frameOwnerCandidate = this; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
if (frameOwnerCandidate.baseURL)
return WebInspector.ParsedURL.completeURL(frameOwnerCandidate.baseURL, url);
}
return null;
}
}


WebInspector.DOMDocument = function(domAgent, payload)
{
WebInspector.DOMNode.call(this, domAgent, this, false, payload);
this.documentURL = payload.documentURL || "";
this.baseURL =   (payload.baseURL);
console.assert(this.baseURL);
this.xmlVersion = payload.xmlVersion;
this._listeners = {};
}

WebInspector.DOMDocument.prototype = {
__proto__: WebInspector.DOMNode.prototype
}


WebInspector.DOMAgent = function() {

this._idToDOMNode = {};
this._document = null;
this._attributeLoadNodeIds = {};
InspectorBackend.registerDOMDispatcher(new WebInspector.DOMDispatcher(this));
if (WebInspector.settings.emulateTouchEvents.get())
this._emulateTouchEventsChanged();
WebInspector.settings.emulateTouchEvents.addChangeListener(this._emulateTouchEventsChanged, this);
}

WebInspector.DOMAgent.Events = {
AttrModified: "AttrModified",
AttrRemoved: "AttrRemoved",
CharacterDataModified: "CharacterDataModified",
NodeInserted: "NodeInserted",
NodeRemoved: "NodeRemoved",
DocumentUpdated: "DocumentUpdated",
ChildNodeCountUpdated: "ChildNodeCountUpdated",
InspectElementRequested: "InspectElementRequested",
UndoRedoRequested: "UndoRedoRequested",
UndoRedoCompleted: "UndoRedoCompleted",
InspectNodeRequested: "InspectNodeRequested"
}

WebInspector.DOMAgent.prototype = {

requestDocument: function(callback)
{
if (this._document) {
if (callback)
callback(this._document);
return;
}

if (this._pendingDocumentRequestCallbacks) {
this._pendingDocumentRequestCallbacks.push(callback);
return;
}

this._pendingDocumentRequestCallbacks = [callback];


function onDocumentAvailable(error, root)
{
if (!error)
this._setDocument(root);

for (var i = 0; i < this._pendingDocumentRequestCallbacks.length; ++i) {
var callback = this._pendingDocumentRequestCallbacks[i];
if (callback)
callback(this._document);
}
delete this._pendingDocumentRequestCallbacks;
}

DOMAgent.getDocument(onDocumentAvailable.bind(this));
},


existingDocument: function()
{
return this._document;
},


pushNodeToFrontend: function(objectId, callback)
{
var callbackCast =  (callback);
this._dispatchWhenDocumentAvailable(DOMAgent.requestNode.bind(DOMAgent, objectId), callbackCast);
},


pushNodeByPathToFrontend: function(path, callback)
{
var callbackCast =  (callback);
this._dispatchWhenDocumentAvailable(DOMAgent.pushNodeByPathToFrontend.bind(DOMAgent, path), callbackCast);
},


pushNodeByBackendIdToFrontend: function(backendNodeId, callback)
{
var callbackCast =  (callback);
this._dispatchWhenDocumentAvailable(DOMAgent.pushNodeByBackendIdToFrontend.bind(DOMAgent, backendNodeId), callbackCast);
},


_wrapClientCallback: function(callback)
{
if (!callback)
return;

return function(error, result)
{

callback(error ? null : result);
}
},


_dispatchWhenDocumentAvailable: function(func, callback)
{
var callbackWrapper =  (this._wrapClientCallback(callback));

function onDocumentAvailable()
{
if (this._document)
func(callbackWrapper);
else {
if (callbackWrapper)
callbackWrapper("No document");
}
}
this.requestDocument(onDocumentAvailable.bind(this));
},


_attributeModified: function(nodeId, name, value)
{
var node = this._idToDOMNode[nodeId];
if (!node)
return;

node._setAttribute(name, value);
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrModified, { node: node, name: name });
},


_attributeRemoved: function(nodeId, name)
{
var node = this._idToDOMNode[nodeId];
if (!node)
return;
node._removeAttribute(name);
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrRemoved, { node: node, name: name });
},


_inlineStyleInvalidated: function(nodeIds)
{
for (var i = 0; i < nodeIds.length; ++i)
this._attributeLoadNodeIds[nodeIds[i]] = true;
if ("_loadNodeAttributesTimeout" in this)
return;
this._loadNodeAttributesTimeout = setTimeout(this._loadNodeAttributes.bind(this), 0);
},

_loadNodeAttributes: function()
{

function callback(nodeId, error, attributes)
{
if (error) {

return;
}
var node = this._idToDOMNode[nodeId];
if (node) {
if (node._setAttributesPayload(attributes))
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrModified, { node: node, name: "style" });
}
}

delete this._loadNodeAttributesTimeout;

for (var nodeId in this._attributeLoadNodeIds) {
var nodeIdAsNumber = parseInt(nodeId, 10);
DOMAgent.getAttributes(nodeIdAsNumber, callback.bind(this, nodeIdAsNumber));
}
this._attributeLoadNodeIds = {};
},


_characterDataModified: function(nodeId, newValue)
{
var node = this._idToDOMNode[nodeId];
node._nodeValue = newValue;
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.CharacterDataModified, node);
},


nodeForId: function(nodeId)
{
return this._idToDOMNode[nodeId];
},

_documentUpdated: function()
{
this._setDocument(null);
},


_setDocument: function(payload)
{
this._idToDOMNode = {};
if (payload && "nodeId" in payload)
this._document = new WebInspector.DOMDocument(this, payload);
else
this._document = null;
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.DocumentUpdated, this._document);
},


_setDetachedRoot: function(payload)
{
if (payload.nodeName === "#document")
new WebInspector.DOMDocument(this, payload);
else
new WebInspector.DOMNode(this, null, false, payload);
},


_setChildNodes: function(parentId, payloads)
{
if (!parentId && payloads.length) {
this._setDetachedRoot(payloads[0]);
return;
}

var parent = this._idToDOMNode[parentId];
parent._setChildrenPayload(payloads);
},


_childNodeCountUpdated: function(nodeId, newValue)
{
var node = this._idToDOMNode[nodeId];
node._childNodeCount = newValue;
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.ChildNodeCountUpdated, node);
},


_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;
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeInserted, node);
},


_childNodeRemoved: function(parentId, nodeId)
{
var parent = this._idToDOMNode[parentId];
var node = this._idToDOMNode[nodeId];
parent._removeChild(node);
this._unbind(node);
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node: node, parent: parent});
},


_shadowRootPopped: function(rootId)
{
},


_unbind: function(node)
{
delete this._idToDOMNode[node.id];
for (var i = 0; node.children && i < node.children.length; ++i)
this._unbind(node.children[i]);
},


inspectElement: function(nodeId)
{
var node = this._idToDOMNode[nodeId];
if (node)
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.InspectElementRequested, node);
},


_inspectNodeRequested: function(nodeId)
{
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.InspectNodeRequested, nodeId);
},


performSearch: function(query, searchCallback)
{
this.cancelSearch();


function callback(error, searchId, resultsCount)
{
this._searchId = searchId;
searchCallback(resultsCount);
}
DOMAgent.performSearch(query, callback.bind(this));
},


searchResult: function(index, callback)
{
if (this._searchId) {

function mycallback(error, nodeIds)
{
if (error) {
console.error(error);
callback(null);
return;
}
if (nodeIds.length != 1)
return;

callback(this._idToDOMNode[nodeIds[0]]);
}
DOMAgent.getSearchResults(this._searchId, index, index + 1, mycallback.bind(this));
} else
callback(null);
},

cancelSearch: function()
{
if (this._searchId) {
DOMAgent.discardSearchResults(this._searchId);
delete this._searchId;
}
},


querySelector: function(nodeId, selectors, callback)
{
var callbackCast =  (callback);
DOMAgent.querySelector(nodeId, selectors, this._wrapClientCallback(callbackCast));
},


querySelectorAll: function(nodeId, selectors, callback)
{
var callbackCast =  (callback);
DOMAgent.querySelectorAll(nodeId, selectors, this._wrapClientCallback(callbackCast));
},


highlightDOMNode: function(nodeId, mode, objectId)
{
if (this._hideDOMNodeHighlightTimeout) {
clearTimeout(this._hideDOMNodeHighlightTimeout);
delete this._hideDOMNodeHighlightTimeout;
}

if (objectId || nodeId)
DOMAgent.highlightNode(this._buildHighlightConfig(mode), objectId ? undefined : nodeId, objectId);
else
DOMAgent.hideHighlight();
},

hideDOMNodeHighlight: function()
{
this.highlightDOMNode(0);
},


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


setInspectModeEnabled: function(enabled, callback)
{
var callbackCast =   (callback);
this._dispatchWhenDocumentAvailable(DOMAgent.setInspectModeEnabled.bind(DOMAgent, enabled, this._buildHighlightConfig()), callbackCast);
},


_buildHighlightConfig: function(mode)
{
mode = mode || "all";
var highlightConfig = { showInfo: mode === "all", showRulers: WebInspector.settings.showMetricsRulers.get() };
if (mode === "all" || mode === "content")
highlightConfig.contentColor = WebInspector.Color.PageHighlight.Content.toProtocolRGBA();

if (mode === "all" || mode === "padding")
highlightConfig.paddingColor = WebInspector.Color.PageHighlight.Padding.toProtocolRGBA();

if (mode === "all" || mode === "border")
highlightConfig.borderColor = WebInspector.Color.PageHighlight.Border.toProtocolRGBA();

if (mode === "all" || mode === "margin")
highlightConfig.marginColor = WebInspector.Color.PageHighlight.Margin.toProtocolRGBA();

if (mode === "all")
highlightConfig.eventTargetColor = WebInspector.Color.PageHighlight.EventTarget.toProtocolRGBA();

return highlightConfig;
},


_markRevision: function(node, callback)
{
function wrapperFunction(error)
{
if (!error)
this.markUndoableState();

if (callback)
callback.apply(this, arguments);
}
return wrapperFunction.bind(this);
},

_emulateTouchEventsChanged: function()
{
const injectedFunction = function() {
const touchEvents = ["ontouchstart", "ontouchend", "ontouchmove", "ontouchcancel"];
var recepients = [window.__proto__, document.__proto__];
for (var i = 0; i < touchEvents.length; ++i) {
for (var j = 0; j < recepients.length; ++j) {
if (!(touchEvents[i] in recepients[j]))
Object.defineProperty(recepients[j], touchEvents[i], { value: null, writable: true, configurable: true, enumerable: true });
}
}
}

var emulationEnabled = WebInspector.settings.emulateTouchEvents.get();
if (emulationEnabled && !this._addTouchEventsScriptInjecting) {
this._addTouchEventsScriptInjecting = true;
PageAgent.addScriptToEvaluateOnLoad("(" + injectedFunction.toString() + ")()", scriptAddedCallback.bind(this));
} else {
if (typeof this._addTouchEventsScriptId !== "undefined") {
PageAgent.removeScriptToEvaluateOnLoad(this._addTouchEventsScriptId);
delete this._addTouchEventsScriptId;
}
}

function scriptAddedCallback(error, scriptId)
{
delete this._addTouchEventsScriptInjecting;
if (error)
return;
this._addTouchEventsScriptId = scriptId;
}

PageAgent.setTouchEmulationEnabled(emulationEnabled);
},

markUndoableState: function()
{
DOMAgent.markUndoableState();
},


undo: function(callback)
{
function mycallback(error)
{
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoCompleted);
callback(error);
}

this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoRequested);
DOMAgent.undo(callback);
},


redo: function(callback)
{
function mycallback(error)
{
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoCompleted);
callback(error);
}

this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoRequested);
DOMAgent.redo(callback);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.DOMDispatcher = function(domAgent)
{
this._domAgent = domAgent;
}

WebInspector.DOMDispatcher.prototype = {
documentUpdated: function()
{
this._domAgent._documentUpdated();
},


inspectNodeRequested: function(nodeId)
{
this._domAgent._inspectNodeRequested(nodeId);
},


attributeModified: function(nodeId, name, value)
{
this._domAgent._attributeModified(nodeId, name, value);
},


attributeRemoved: function(nodeId, name)
{
this._domAgent._attributeRemoved(nodeId, name);
},


inlineStyleInvalidated: function(nodeIds)
{
this._domAgent._inlineStyleInvalidated(nodeIds);
},


characterDataModified: function(nodeId, characterData)
{
this._domAgent._characterDataModified(nodeId, characterData);
},


setChildNodes: function(parentId, payloads)
{
this._domAgent._setChildNodes(parentId, payloads);
},


childNodeCountUpdated: function(nodeId, childNodeCount)
{
this._domAgent._childNodeCountUpdated(nodeId, childNodeCount);
},


childNodeInserted: function(parentNodeId, previousNodeId, payload)
{
this._domAgent._childNodeInserted(parentNodeId, previousNodeId, payload);
},


childNodeRemoved: function(parentNodeId, nodeId)
{
this._domAgent._childNodeRemoved(parentNodeId, nodeId);
},


shadowRootPushed: function(hostId, root)
{
this._domAgent._childNodeInserted(hostId, 0, root);
},


shadowRootPopped: function(hostId, rootId)
{
this._domAgent._childNodeRemoved(hostId, rootId);
}
}


WebInspector.domAgent = null;





WebInspector.evaluateForTestInFrontend = function(callId, script)
{
if (!InspectorFrontendHost.isUnderTest())
return;

function invokeMethod()
{
var message;
try {
script = script + "//@ sourceURL=evaluateInWebInspector" + callId + ".js";
var result = window.eval(script);
message = typeof result === "undefined" ? "\"<undefined>\"" : JSON.stringify(result);
} catch (e) {
message = e.toString();
}
RuntimeAgent.evaluate("didEvaluateForTestInFrontend(" + callId + ", " + message + ")", "test");
}
InspectorBackend.runAfterPendingDispatches(invokeMethod);
}






WebInspector.Dialog = function(relativeToElement, delegate)
{
this._delegate = delegate;
this._relativeToElement = relativeToElement;

this._glassPane = new WebInspector.GlassPane();

this._glassPane.element.tabIndex = 0;
this._glassPane.element.addEventListener("focus", this._onGlassPaneFocus.bind(this), false);

this._element = this._glassPane.element.createChild("div");
this._element.tabIndex = 0;
this._element.addEventListener("focus", this._onFocus.bind(this), false);
this._element.addEventListener("keydown", this._onKeyDown.bind(this), false);
this._closeKeys = [
WebInspector.KeyboardShortcut.Keys.Enter.code,
WebInspector.KeyboardShortcut.Keys.Esc.code,
];

delegate.show(this._element);

this._position();
this._windowResizeHandler = this._position.bind(this);
window.addEventListener("resize", this._windowResizeHandler, true);
this._delegate.focus();
}


WebInspector.Dialog.currentInstance = function()
{
return WebInspector.Dialog._instance;
}


WebInspector.Dialog.show = function(relativeToElement, delegate)
{
if (WebInspector.Dialog._instance)
return;
WebInspector.Dialog._instance = new WebInspector.Dialog(relativeToElement, delegate);
}

WebInspector.Dialog.hide = function()
{
if (!WebInspector.Dialog._instance)
return;
WebInspector.Dialog._instance._hide();
}

WebInspector.Dialog.prototype = {
_hide: function()
{
if (this._isHiding)
return;
this._isHiding = true;

this._delegate.willHide();

delete WebInspector.Dialog._instance;
this._glassPane.dispose();
window.removeEventListener("resize", this._windowResizeHandler, true);
},

_onGlassPaneFocus: function(event)
{
this._hide();
},

_onFocus: function(event)
{
this._delegate.focus();
},

_position: function()
{
this._delegate.position(this._element, this._relativeToElement);
},

_onKeyDown: function(event)
{
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Tab.code) {
event.preventDefault();
return;
}

if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code)
this._delegate.onEnter();

if (this._closeKeys.indexOf(event.keyCode) >= 0) {
this._hide();
event.consume(true);
}
}
};


WebInspector.DialogDelegate = function()
{
}

WebInspector.DialogDelegate.prototype = {

show: function(element)
{
element.appendChild(this.element);
this.element.addStyleClass("dialog-contents");
element.addStyleClass("dialog");    
},


position: function(element, relativeToElement)
{
var offset = relativeToElement.offsetRelativeToWindow(window);

var positionX = offset.x + (relativeToElement.offsetWidth - element.offsetWidth) / 2;
positionX = Number.constrain(positionX, 0, window.innerWidth - element.offsetWidth);

var positionY = offset.y + (relativeToElement.offsetHeight - element.offsetHeight) / 2;
positionY = Number.constrain(positionY, 0, window.innerHeight - element.offsetHeight);

element.style.left = positionX + "px";
element.style.top = positionY + "px";
},

focus: function() { },

onEnter: function() { },

willHide: function() { },

__proto__: WebInspector.Object.prototype
}







WebInspector.GoToLineDialog = function(view)
{
WebInspector.DialogDelegate.call(this);

this.element = document.createElement("div");
this.element.className = "go-to-line-dialog";

this.element.createChild("label").textContent = WebInspector.UIString("Go to line: ");

this._input = this.element.createChild("input");
this._input.setAttribute("type", "text");
this._input.setAttribute("size", 6);

this._goButton = this.element.createChild("button");
this._goButton.textContent = WebInspector.UIString("Go");
this._goButton.addEventListener("click", this._onGoClick.bind(this), false);

this._view = view;
}


WebInspector.GoToLineDialog.install = function(panel, viewGetter)
{
var goToLineShortcut = WebInspector.GoToLineDialog.createShortcut();
panel.registerShortcuts([goToLineShortcut], WebInspector.GoToLineDialog._show.bind(null, viewGetter));
}


WebInspector.GoToLineDialog._show = function(viewGetter, event)
{
var sourceView = viewGetter();
if (!sourceView || !sourceView.canHighlightLine())
return false;
WebInspector.Dialog.show(sourceView.element, new WebInspector.GoToLineDialog(sourceView));
return true;
}


WebInspector.GoToLineDialog.createShortcut = function()
{
var isMac = WebInspector.isMac();
var shortcut;
if (isMac)
return WebInspector.KeyboardShortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Meta);
return WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
}

WebInspector.GoToLineDialog.prototype = {
focus: function()
{
WebInspector.setCurrentFocusElement(this._input);
this._input.select();
},

_onGoClick: function()
{
this._applyLineNumber();
WebInspector.Dialog.hide();
},

_applyLineNumber: function()
{
var value = this._input.value;
var lineNumber = parseInt(value, 10) - 1;
if (!isNaN(lineNumber) && lineNumber >= 0)
this._view.highlightLine(lineNumber);
},

onEnter: function()
{
this._applyLineNumber();
},

__proto__: WebInspector.DialogDelegate.prototype
}






WebInspector.SidebarOverlay = function(view, widthSettingName, minimalWidth)
{
this.element = document.createElement("div");
this.element.className = "sidebar-overlay";

this._view = view;
this._widthSettingName = widthSettingName;
this._minimalWidth = minimalWidth;
this._savedWidth = minimalWidth || 300;

if (this._widthSettingName)
WebInspector.settings[this._widthSettingName] = WebInspector.settings.createSetting(this._widthSettingName, undefined);

this._resizerElement = document.createElement("div");
this._resizerElement.className = "sidebar-overlay-resizer";
this._installResizer(this._resizerElement);
}

WebInspector.SidebarOverlay.prototype = {

show: function(relativeToElement)
{
relativeToElement.appendChild(this.element);
relativeToElement.addStyleClass("sidebar-overlay-shown");
this._view.show(this.element);
this.element.appendChild(this._resizerElement);
if (this._resizerWidgetElement)
this.element.appendChild(this._resizerWidgetElement);
this.position(relativeToElement);
},


position: function(relativeToElement)
{
this._totalWidth = relativeToElement.offsetWidth;
this._setWidth(this._preferredWidth());
},

focus: function()
{
WebInspector.setCurrentFocusElement(this._view.element);
},

hide: function()
{
var element = this.element.parentElement;
if (!element)
return;

this._view.detach();
element.removeChild(this.element);
element.removeStyleClass("sidebar-overlay-shown");
this.element.removeChild(this._resizerElement);
if (this._resizerWidgetElement)
this.element.removeChild(this._resizerWidgetElement);
},


_setWidth: function(newWidth)
{
var width = Number.constrain(newWidth, this._minimalWidth, this._totalWidth);

if (this._width === width)
return;

this.element.style.width = width + "px";
this._resizerElement.style.left = (width - 3) + "px";
this._width = width;
this._view.doResize();
this._saveWidth();
},


_preferredWidth: function()
{
if (!this._widthSettingName)
return this._savedWidth;

return WebInspector.settings[this._widthSettingName].get() || this._savedWidth;
},

_saveWidth: function()
{
this._savedWidth = this._width;
if (!this._widthSettingName)
return;

WebInspector.settings[this._widthSettingName].set(this._width);
},


_startResizerDragging: function(event)
{
var width = this._width;
this._dragOffset = width - event.pageX;
return true;
},


_resizerDragging: function(event)
{
var width = event.pageX + this._dragOffset;
this._setWidth(width);
event.preventDefault();
},


_endResizerDragging: function(event)
{
delete this._dragOffset;
},


_installResizer: function(resizerElement)
{
WebInspector.installDragHandle(resizerElement, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "ew-resize");
},


set resizerWidgetElement(resizerWidgetElement)
{
this._resizerWidgetElement = resizerWidgetElement;
this._installResizer(resizerWidgetElement);
}
}






WebInspector.SettingsScreen = function(onHide)
{
WebInspector.HelpScreen.call(this);
this.element.id = "settings-screen";


this._onHide = onHide;

this._tabbedPane = new WebInspector.TabbedPane();
this._tabbedPane.element.addStyleClass("help-window-main");
var settingsLabelElement = document.createElement("div");
settingsLabelElement.className = "help-window-label";
settingsLabelElement.createTextChild(WebInspector.UIString("Settings"));
this._tabbedPane.element.insertBefore(settingsLabelElement, this._tabbedPane.element.firstChild);
this._tabbedPane.element.appendChild(this._createCloseButton());
this._tabbedPane.appendTab(WebInspector.SettingsScreen.Tabs.General, WebInspector.UIString("General"), new WebInspector.GenericSettingsTab());
if (!WebInspector.experimentsSettings.showOverridesInDrawer.isEnabled())
this._tabbedPane.appendTab(WebInspector.SettingsScreen.Tabs.Overrides, WebInspector.UIString("Overrides"), new WebInspector.OverridesSettingsTab());
this._tabbedPane.appendTab(WebInspector.SettingsScreen.Tabs.Workspace, WebInspector.UIString("Workspace"), new WebInspector.WorkspaceSettingsTab());
if (WebInspector.experimentsSettings.tethering.isEnabled())
this._tabbedPane.appendTab(WebInspector.SettingsScreen.Tabs.Tethering, WebInspector.UIString("Port forwarding"), new WebInspector.TetheringSettingsTab());
if (WebInspector.experimentsSettings.experimentsEnabled)
this._tabbedPane.appendTab(WebInspector.SettingsScreen.Tabs.Experiments, WebInspector.UIString("Experiments"), new WebInspector.ExperimentsSettingsTab());
this._tabbedPane.appendTab(WebInspector.SettingsScreen.Tabs.Shortcuts, WebInspector.UIString("Shortcuts"), WebInspector.shortcutsScreen.createShortcutsTabView());
this._tabbedPane.shrinkableTabs = false;
this._tabbedPane.verticalTabLayout = true;

this._lastSelectedTabSetting = WebInspector.settings.createSetting("lastSelectedSettingsTab", WebInspector.SettingsScreen.Tabs.General);
this.selectTab(this._lastSelectedTabSetting.get());
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
}

WebInspector.SettingsScreen.Tabs = {
General: "general",
Overrides: "overrides",
Workspace: "workspace",
Tethering: "tethering",
Experiments: "experiments",
Shortcuts: "shortcuts"
}

WebInspector.SettingsScreen.prototype = {

selectTab: function(tabId)
{
this._tabbedPane.selectTab(tabId);
},


_tabSelected: function(event)
{
this._lastSelectedTabSetting.set(this._tabbedPane.selectedTabId);
},


wasShown: function()
{
this._tabbedPane.show(this.element);
WebInspector.HelpScreen.prototype.wasShown.call(this);
},


isClosingKey: function(keyCode)
{
return [
WebInspector.KeyboardShortcut.Keys.Enter.code,
WebInspector.KeyboardShortcut.Keys.Esc.code,
].indexOf(keyCode) >= 0;
},


willHide: function()
{
this._onHide();
WebInspector.HelpScreen.prototype.willHide.call(this);
},

__proto__: WebInspector.HelpScreen.prototype
}


WebInspector.SettingsTab = function(name, id)
{
WebInspector.View.call(this);
this.element.className = "settings-tab-container";
if (id)
this.element.id = id;
var header = this.element.createChild("header");
header.createChild("h3").appendChild(document.createTextNode(name));
this.containerElement = this.element.createChild("div", "help-container-wrapper").createChild("div", "settings-tab help-content help-container");
}

WebInspector.SettingsTab.prototype = {

_appendSection: function(name)
{
var block = this.containerElement.createChild("div", "help-block");
if (name)
block.createChild("div", "help-section-title").textContent = name;
return block;
},


_createCheckboxSetting: function(name, setting, omitParagraphElement, inputElement)
{
var input = inputElement || document.createElement("input");
input.type = "checkbox";
input.name = name;
input.checked = setting.get();

function listener()
{
setting.set(input.checked);
}
input.addEventListener("click", listener, false);

var label = document.createElement("label");
label.appendChild(input);
label.appendChild(document.createTextNode(name));
if (omitParagraphElement)
return label;

var p = document.createElement("p");
p.appendChild(label);
return p;
},

_createSelectSetting: function(name, options, setting)
{
var fieldsetElement = document.createElement("fieldset");
fieldsetElement.createChild("label").textContent = name;

var select = document.createElement("select");
var settingValue = setting.get();

for (var i = 0; i < options.length; ++i) {
var option = options[i];
select.add(new Option(option[0], option[1]));
if (settingValue === option[1])
select.selectedIndex = i;
}

function changeListener(e)
{
setting.set(e.target.value);
}

select.addEventListener("change", changeListener, false);
fieldsetElement.appendChild(select);

var p = document.createElement("p");
p.appendChild(fieldsetElement);
return p;
},

_createRadioSetting: function(name, options, setting)
{
var pp = document.createElement("p");
var fieldsetElement = document.createElement("fieldset");
var legendElement = document.createElement("legend");
legendElement.textContent = name;
fieldsetElement.appendChild(legendElement);

function clickListener(e)
{
setting.set(e.target.value);
}

var settingValue = setting.get();
for (var i = 0; i < options.length; ++i) {
var p = document.createElement("p");
var label = document.createElement("label");
p.appendChild(label);

var input = document.createElement("input");
input.type = "radio";
input.name = setting.name;
input.value = options[i][0];
input.addEventListener("click", clickListener, false);
if (settingValue == input.value)
input.checked = true;

label.appendChild(input);
label.appendChild(document.createTextNode(options[i][1]));

fieldsetElement.appendChild(p);
}

pp.appendChild(fieldsetElement);
return pp;
},


_createInputSetting: function(label, setting, numeric, maxLength, width, validatorCallback)
{
var fieldset = document.createElement("fieldset");
var p = fieldset.createChild("p");
var labelElement = p.createChild("label");
labelElement.textContent = label + " ";
var inputElement = labelElement.createChild("input");
inputElement.value = setting.get();
inputElement.type = "text";
if (numeric)
inputElement.className = "numeric";
if (maxLength)
inputElement.maxLength = maxLength;
if (width)
inputElement.style.width = width;

function onBlur()
{
if (validatorCallback && !validatorCallback(inputElement.value)) {
inputElement.value = setting.get();
return;
}
setting.set(numeric ? Number(inputElement.value) : inputElement.value);
}
inputElement.addEventListener("blur", onBlur, false);
return fieldset;
},

_createCustomSetting: function(name, element)
{
var p = document.createElement("p");
var fieldsetElement = document.createElement("fieldset");
fieldsetElement.createChild("label").textContent = name;
fieldsetElement.appendChild(element);
p.appendChild(fieldsetElement);
return p;
},

__proto__: WebInspector.View.prototype
}


WebInspector.GenericSettingsTab = function()
{
WebInspector.SettingsTab.call(this, WebInspector.UIString("General"), "general-tab-content");

var p = this._appendSection();
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Disable cache (while DevTools is open)"), WebInspector.settings.cacheDisabled));
var disableJSElement = this._createCheckboxSetting(WebInspector.UIString("Disable JavaScript"), WebInspector.settings.javaScriptDisabled);
p.appendChild(disableJSElement);
WebInspector.settings.javaScriptDisabled.addChangeListener(this._javaScriptDisabledChanged, this);
this._disableJSCheckbox = disableJSElement.getElementsByTagName("input")[0];
this._updateScriptDisabledCheckbox();

p = this._appendSection(WebInspector.UIString("Appearance"));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show toolbar icons"), WebInspector.settings.showToolbarIcons));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Split panels vertically when docked to right"), WebInspector.settings.splitVerticallyWhenDockedToRight));

p = this._appendSection(WebInspector.UIString("Elements"));
p.appendChild(this._createRadioSetting(WebInspector.UIString("Color format"), [
[ WebInspector.Color.Format.Original, WebInspector.UIString("As authored") ],
[ WebInspector.Color.Format.HEX, "HEX: #DAC0DE" ],
[ WebInspector.Color.Format.RGB, "RGB: rgb(128, 255, 255)" ],
[ WebInspector.Color.Format.HSL, "HSL: hsl(300, 80%, 90%)" ] ], WebInspector.settings.colorFormat));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show user agent styles"), WebInspector.settings.showUserAgentStyles));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Word wrap"), WebInspector.settings.domWordWrap));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show Shadow DOM"), WebInspector.settings.showShadowDOM));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show rulers"), WebInspector.settings.showMetricsRulers));

p = this._appendSection(WebInspector.UIString("Rendering"));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show paint rectangles"), WebInspector.settings.showPaintRects));
WebInspector.settings.showPaintRects.addChangeListener(this._showPaintRectsChanged, this);

p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show composited layer borders"), WebInspector.settings.showDebugBorders));
WebInspector.settings.showDebugBorders.addChangeListener(this._showDebugBordersChanged, this);

if (Capabilities.canShowFPSCounter) {
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show FPS meter"), WebInspector.settings.showFPSCounter));
WebInspector.settings.showFPSCounter.addChangeListener(this._showFPSCounterChanged, this);
}
if (Capabilities.canContinuouslyPaint) {
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Enable continuous page repainting"), WebInspector.settings.continuousPainting));
WebInspector.settings.continuousPainting.addChangeListener(this._continuousPaintingChanged, this);
}

p = this._appendSection(WebInspector.UIString("Sources"));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Search in content scripts"), WebInspector.settings.searchInContentScripts));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Enable source maps"), WebInspector.settings.sourceMapsEnabled));
if (WebInspector.experimentsSettings.isEnabled("sass"))
p.appendChild(this._createCSSAutoReloadControls());
var indentationElement = this._createSelectSetting(WebInspector.UIString("Indentation"), [
[ WebInspector.UIString("2 spaces"), WebInspector.TextUtils.Indent.TwoSpaces ],
[ WebInspector.UIString("4 spaces"), WebInspector.TextUtils.Indent.FourSpaces ],
[ WebInspector.UIString("8 spaces"), WebInspector.TextUtils.Indent.EightSpaces ],
[ WebInspector.UIString("Tab character"), WebInspector.TextUtils.Indent.TabCharacter ]
], WebInspector.settings.textEditorIndent);
indentationElement.firstChild.className = "toplevel";
p.appendChild(indentationElement);
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Use CodeMirror editor"), WebInspector.settings.codemirror));

p = this._appendSection(WebInspector.UIString("Profiler"));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show objects' hidden properties"), WebInspector.settings.showHeapSnapshotObjectsHiddenProperties));
if (WebInspector.experimentsSettings.nativeMemorySnapshots.isEnabled())
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show uninstrumented native memory"), WebInspector.settings.showNativeSnapshotUninstrumentedSize));

p = this._appendSection(WebInspector.UIString("Timeline"));
var checkbox = this._createCheckboxSetting(WebInspector.UIString("Limit number of captured JS stack frames"), WebInspector.settings.timelineLimitStackFramesFlag);
p.appendChild(checkbox);
var fieldset = this._createInputSetting(WebInspector.UIString("Frames to capture"), WebInspector.settings.timelineStackFramesToCapture, true, 2, "2em");
fieldset.disabled = !WebInspector.settings.timelineLimitStackFramesFlag.get();
WebInspector.settings.timelineLimitStackFramesFlag.addChangeListener(this._timelineLimitStackFramesChanged.bind(this, fieldset));
checkbox.appendChild(fieldset);

p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show CPU activity on the ruler"), WebInspector.settings.showCpuOnTimelineRuler));

p = this._appendSection(WebInspector.UIString("Console"));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Log XMLHttpRequests"), WebInspector.settings.monitoringXHREnabled));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Preserve log upon navigation"), WebInspector.settings.preserveConsoleLog));

if (WebInspector.extensionServer.hasExtensions()) {
var handlerSelector = new WebInspector.HandlerSelector(WebInspector.openAnchorLocationRegistry);
p = this._appendSection(WebInspector.UIString("Extensions"));
p.appendChild(this._createCustomSetting(WebInspector.UIString("Open links in"), handlerSelector.element));
}

p = this._appendSection();
var panelShortcutTitle = WebInspector.UIString("Enable %s + 1-9 shortcut to switch panels", WebInspector.isMac() ? "Cmd" : "Ctrl");
p.appendChild(this._createCheckboxSetting(panelShortcutTitle, WebInspector.settings.shortcutPanelSwitch));
}

WebInspector.GenericSettingsTab.prototype = {
_showPaintRectsChanged: function()
{
PageAgent.setShowPaintRects(WebInspector.settings.showPaintRects.get());
},

_showDebugBordersChanged: function()
{
PageAgent.setShowDebugBorders(WebInspector.settings.showDebugBorders.get());
},

_showFPSCounterChanged: function()
{
PageAgent.setShowFPSCounter(WebInspector.settings.showFPSCounter.get());
},

_continuousPaintingChanged: function()
{
PageAgent.setContinuousPaintingEnabled(WebInspector.settings.continuousPainting.get());
},


_timelineLimitStackFramesChanged: function(fieldset)
{
fieldset.disabled = !WebInspector.settings.timelineLimitStackFramesFlag.get();
},

_updateScriptDisabledCheckbox: function()
{
function executionStatusCallback(error, status)
{
if (error || !status)
return;

switch (status) {
case "forbidden":
this._disableJSCheckbox.checked = true;
this._disableJSCheckbox.disabled = true;
break;
case "disabled":
this._disableJSCheckbox.checked = true;
break;
default:
this._disableJSCheckbox.checked = false;
break;
}
}

PageAgent.getScriptExecutionStatus(executionStatusCallback.bind(this));
},

_javaScriptDisabledChanged: function()
{

PageAgent.setScriptExecutionDisabled(WebInspector.settings.javaScriptDisabled.get(), this._updateScriptDisabledCheckbox.bind(this));
},

_createCSSAutoReloadControls: function()
{
var fragment = document.createDocumentFragment();
var labelElement = fragment.createChild("label");
var checkboxElement = labelElement.createChild("input");
checkboxElement.type = "checkbox";
checkboxElement.checked = WebInspector.settings.cssReloadEnabled.get();
checkboxElement.addEventListener("click", checkboxClicked, false);
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Auto-reload CSS upon Sass save")));

var fieldsetElement = this._createInputSetting(WebInspector.UIString("Timeout (ms)"), WebInspector.settings.cssReloadTimeout, true, 8, "60px", validateReloadTimeout);
fieldsetElement.disabled = !checkboxElement.checked;
fragment.appendChild(fieldsetElement);
return fragment;

function checkboxClicked()
{
var reloadEnabled = checkboxElement.checked;
WebInspector.settings.cssReloadEnabled.set(reloadEnabled);
fieldsetElement.disabled = !reloadEnabled;
}

function validateReloadTimeout(value)
{
return isFinite(value) && value > 0;
}
},

__proto__: WebInspector.SettingsTab.prototype
}


WebInspector.OverridesSettingsTab = function()
{
WebInspector.SettingsTab.call(this, WebInspector.UIString("Overrides"), "overrides-tab-content");
this._view = new WebInspector.OverridesView();
this.containerElement.parentElement.appendChild(this._view.containerElement);
this.containerElement.removeSelf();
this.containerElement = this._view.containerElement;
}

WebInspector.OverridesSettingsTab.prototype = {
__proto__: WebInspector.SettingsTab.prototype
}


WebInspector.WorkspaceSettingsTab = function()
{
WebInspector.SettingsTab.call(this, WebInspector.UIString("Workspace"), "workspace-tab-content");
this._reset();
}

WebInspector.WorkspaceSettingsTab.prototype = {
wasShown: function()
{
WebInspector.SettingsTab.prototype.wasShown.call(this);
this._reset();
},

_reset: function()
{
this.containerElement.removeChildren();
this._createFileSystemsEditor();
this._createFileMappingEditor();
},

_createFileSystemsEditor: function()
{
var p = this._appendSection(WebInspector.UIString("Folders"));
this._fileSystemsEditor = p.createChild("p", "file-systems-editor");

this._addFileSystemRowElement = this._fileSystemsEditor.createChild("div", "workspace-settings-row");
var addFileSystemButton = this._addFileSystemRowElement.createChild("input", "file-system-add-button");
addFileSystemButton.type = "button";
addFileSystemButton.value = WebInspector.UIString("Add folder");
addFileSystemButton.addEventListener("click", this._addFileSystemClicked.bind(this));

var fileSystemPaths = WebInspector.isolatedFileSystemManager.mapping().fileSystemPaths();
for (var i = 0; i < fileSystemPaths.length; ++i)
this._addFileSystemRow(fileSystemPaths[i]);

return this._fileSystemsEditor;
},


_createShowTextInput: function(className, value)
{
var inputElement = document.createElement("input");
inputElement.addStyleClass(className);
inputElement.type = "text";
inputElement.value = value;
inputElement.title = value;
inputElement.disabled = true;
return inputElement;
},


_createEditTextInput: function(className, placeHolder)
{
var inputElement = document.createElement("input");
inputElement.addStyleClass(className);
inputElement.type = "text";
inputElement.placeholder = placeHolder;
return inputElement;
},


_createRemoveButton: function(handler)
{
var removeButton = document.createElement("button");
removeButton.addStyleClass("button");
removeButton.addStyleClass("remove-button");
removeButton.value = WebInspector.UIString("Remove");
removeButton.addEventListener("click", handler, false);
return removeButton;
},


_createAddButton: function(handler)
{
var addButton = document.createElement("button");
addButton.addStyleClass("button");
addButton.addStyleClass("add-button");
addButton.value = WebInspector.UIString("Add");
addButton.addEventListener("click", handler, false);
return addButton;
},


_addFileSystemRow: function(fileSystemPath)
{
var fileSystemRow = document.createElement("div");
fileSystemRow.addStyleClass("workspace-settings-row");
fileSystemRow.addStyleClass("file-system-row");
this._fileSystemsEditor.insertBefore(fileSystemRow, this._addFileSystemRowElement);

fileSystemRow.appendChild(this._createShowTextInput("file-system-path", fileSystemPath));
var removeFileSystemButton = this._createRemoveButton(removeFileSystemClicked.bind(this));
fileSystemRow.appendChild(removeFileSystemButton);

function removeFileSystemClicked()
{
removeFileSystemButton.disabled = true;
WebInspector.isolatedFileSystemManager.removeFileSystem(fileSystemPath, fileSystemRemoved.bind(this));
}

function fileSystemRemoved()
{
this._fileSystemsEditor.removeChild(fileSystemRow);
removeFileSystemButton.disabled = false;
}
},

_addFileSystemClicked: function()
{
WebInspector.isolatedFileSystemManager.addFileSystem(this._fileSystemAdded.bind(this));
},


_fileSystemAdded: function(fileSystemPath)
{
if (fileSystemPath)
this._addFileSystemRow(fileSystemPath);
},

_createFileMappingEditor: function()
{
var p = this._appendSection(WebInspector.UIString("Mappings"));
this._fileMappingEditor = p.createChild("p", "file-mappings-editor");

this._addMappingRowElement = this._fileMappingEditor.createChild("div", "workspace-settings-row");

this._urlInputElement = this._createEditTextInput("file-mapping-url", WebInspector.UIString("URL prefix"));
this._addMappingRowElement.appendChild(this._urlInputElement);
this._pathInputElement = this._createEditTextInput("file-mapping-path", WebInspector.UIString("Folder path"));
this._addMappingRowElement.appendChild(this._pathInputElement);

this._addMappingRowElement.appendChild(this._createAddButton(this._addFileMappingClicked.bind(this)));

var mappingEntries = WebInspector.fileMapping.mappingEntries();
for (var i = 0; i < mappingEntries.length; ++i)
this._addMappingRow(mappingEntries[i]);

return this._fileMappingEditor;
},


_addMappingRow: function(mappingEntry)
{
var fileMappingRow = document.createElement("div");
fileMappingRow.addStyleClass("workspace-settings-row");
this._fileMappingEditor.insertBefore(fileMappingRow, this._addMappingRowElement);

fileMappingRow.appendChild(this._createShowTextInput("file-mapping-url", mappingEntry.urlPrefix));
fileMappingRow.appendChild(this._createShowTextInput("file-mapping-path", mappingEntry.pathPrefix));

fileMappingRow.appendChild(this._createRemoveButton(removeMappingClicked.bind(this)));

function removeMappingClicked()
{
var index = Array.prototype.slice.call(fileMappingRow.parentElement.childNodes).indexOf(fileMappingRow);
var mappingEntries = WebInspector.fileMapping.mappingEntries();
mappingEntries.splice(index, 1);
WebInspector.fileMapping.setMappingEntries(mappingEntries);
this._fileMappingEditor.removeChild(fileMappingRow);
}
},

_addFileMappingClicked: function()
{
var url = this._urlInputElement.value;
var path = this._pathInputElement.value;
if (!url || !path)
return;
var mappingEntries = WebInspector.fileMapping.mappingEntries();
if (url[url.length - 1] !== "/")
url += "/";
if (path[path.length - 1] !== "/")
path += "/";
var mappingEntry = new WebInspector.FileMapping.Entry(url, path);
mappingEntries.push(mappingEntry);
WebInspector.fileMapping.setMappingEntries(mappingEntries);
this._addMappingRow(mappingEntry);
this._urlInputElement.value = "";
this._pathInputElement.value = "";
},

__proto__: WebInspector.SettingsTab.prototype
}


WebInspector.TetheringSettingsTab = function()
{
WebInspector.SettingsTab.call(this, WebInspector.UIString("Port Forwarding"), "workspace-tab-content");
}

WebInspector.TetheringSettingsTab.prototype = {
wasShown: function()
{
if (this._paragraphElement)
return;

WebInspector.SettingsTab.prototype.wasShown.call(this);

var sectionElement = this._appendSection();
var labelElement = sectionElement.createChild("div");
labelElement.addStyleClass("tethering-help-info");
labelElement.textContent =
WebInspector.UIString("Creates a listen TCP port on your device that maps to a particular TCP port accessible from the host machine.");
labelElement.createChild("br");
labelElement.createChild("div", "tethering-help-title-left").textContent = WebInspector.UIString("Device port");
labelElement.createChild("div", "tethering-help-title-right").textContent = WebInspector.UIString("Target");

this._paragraphElement = sectionElement.createChild("div");
var mappingEntries = WebInspector.settings.portForwardings.get();
for (var i = 0; i < mappingEntries.length; ++i)
this._addMappingRow(mappingEntries[i].port, mappingEntries[i].location, false);
if (!mappingEntries.length)
this._addMappingRow("", "", true);
this._save();
},


_addMappingRow: function(port, location, focus)
{
var mappingRow = this._paragraphElement.createChild("div", "workspace-settings-row");
var portElement = mappingRow.createChild("input", "tethering-port-input");
portElement.type = "text";
portElement.value = port || "";
if (!port)
portElement.placeholder = "8080";
portElement.addEventListener("keydown", this._editTextInputKey.bind(this, true), true);
portElement.addEventListener("blur", this._save.bind(this), true);
portElement.addEventListener("input", this._validatePort.bind(this, portElement), true);

var locationElement = mappingRow.createChild("input");
locationElement.type = "text";
locationElement.value = location || "127.0.0.1:";
locationElement.addEventListener("keydown", this._editTextInputKey.bind(this, false), true);
locationElement.addEventListener("blur", this._save.bind(this), true);
locationElement.addEventListener("input", this._validateLocation.bind(this, locationElement), true);

var removeButton = mappingRow.createChild("button", "button remove-button");
removeButton.value = WebInspector.UIString("Remove");
removeButton.tabIndex = -1;
removeButton.addEventListener("click", removeMappingClicked.bind(this), false);

function removeMappingClicked()
{
mappingRow.removeSelf();
if (!this._paragraphElement.querySelector(".workspace-settings-row"))
this._addMappingRow();
this._save();
}
if (focus)
setTimeout(function() { portElement.focus(); }, 0); 
return mappingRow;
},

_save: function()
{
var portForwardings = [];
for (var rowElement = this._paragraphElement.firstChild.nextSibling; rowElement; rowElement = rowElement.nextSibling) {
var portElement = rowElement.firstChild;
var locationElement = portElement.nextSibling;
var port = this._validatePort(portElement);
var location = this._validateLocation(locationElement);
if (!port || !location)
continue;
portForwardings.push({ port : parseInt(port, 10), location : location });
}
WebInspector.settings.portForwardings.set(portForwardings);
},


_editTextInputKey: function(isPort, event)
{
if (!WebInspector.KeyboardShortcut.hasNoModifiers(  (event)))
return;

if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code ||
event.keyCode === WebInspector.KeyboardShortcut.Keys.Tab.code) {
if (isPort)
event.target.nextElementSibling.focus();
else {
if (event.target.parentElement.nextSibling)
event.target.parentElement.nextSibling.firstChild.focus();
else
this._addMappingRow("", "", true);
}
event.consume(true);
}
},


_validatePort: function(element, event)
{
var port = element.value;
if (isNaN(port) || port < 5000 || port > 10000) {
element.addStyleClass("workspace-settings-error");
return 0;
}
element.removeStyleClass("workspace-settings-error");
return parseInt(port, 10);
},


_validateLocation: function(element, event)
{
var location = element.value;
if (!/.*:\d+/.test(location)) {
element.addStyleClass("workspace-settings-error");
return "";
}
element.removeStyleClass("workspace-settings-error");
return location;
},

__proto__: WebInspector.SettingsTab.prototype
}


WebInspector.ExperimentsSettingsTab = function()
{
WebInspector.SettingsTab.call(this, WebInspector.UIString("Experiments"), "experiments-tab-content");

var experiments = WebInspector.experimentsSettings.experiments;
if (experiments.length) {
var experimentsSection = this._appendSection();
experimentsSection.appendChild(this._createExperimentsWarningSubsection());
for (var i = 0; i < experiments.length; ++i)
experimentsSection.appendChild(this._createExperimentCheckbox(experiments[i]));
}
}

WebInspector.ExperimentsSettingsTab.prototype = {

_createExperimentsWarningSubsection: function()
{
var subsection = document.createElement("div");
var warning = subsection.createChild("span", "settings-experiments-warning-subsection-warning");
warning.textContent = WebInspector.UIString("WARNING:");
subsection.appendChild(document.createTextNode(" "));
var message = subsection.createChild("span", "settings-experiments-warning-subsection-message");
message.textContent = WebInspector.UIString("These experiments could be dangerous and may require restart.");
return subsection;
},

_createExperimentCheckbox: function(experiment)
{
var input = document.createElement("input");
input.type = "checkbox";
input.name = experiment.name;
input.checked = experiment.isEnabled();
function listener()
{
experiment.setEnabled(input.checked);
}
input.addEventListener("click", listener, false);

var p = document.createElement("p");
var label = document.createElement("label");
label.appendChild(input);
label.appendChild(document.createTextNode(WebInspector.UIString(experiment.title)));
p.appendChild(label);
return p;
},

__proto__: WebInspector.SettingsTab.prototype
}


WebInspector.SettingsController = function()
{
this._statusBarButton = new WebInspector.StatusBarButton(WebInspector.UIString("Settings"), "settings-status-bar-item");
if (WebInspector.experimentsSettings.showOverridesInDrawer.isEnabled())
this._statusBarButton.element.addEventListener("mousedown", this._mouseDown.bind(this), false);
else
this._statusBarButton.element.addEventListener("mouseup", this._mouseUp.bind(this), false);


this._settingsScreen;
}

WebInspector.SettingsController.prototype =
{
get statusBarItem()
{
return this._statusBarButton.element;
},


_mouseDown: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Overrides"), showOverrides.bind(this));
contextMenu.appendItem(WebInspector.UIString("Settings"), showSettings.bind(this));

function showOverrides()
{
if (this._settingsScreenVisible)
this._hideSettingsScreen();
WebInspector.OverridesView.showInDrawer();
}

function showSettings()
{
if (!this._settingsScreenVisible)
this.showSettingsScreen();
}

contextMenu.showSoftMenu();
},


_mouseUp: function(event)
{
this.showSettingsScreen();
},

_onHideSettingsScreen: function()
{
delete this._settingsScreenVisible;
},


showSettingsScreen: function(tabId)
{
if (!this._settingsScreen)
this._settingsScreen = new WebInspector.SettingsScreen(this._onHideSettingsScreen.bind(this));

if (tabId)
this._settingsScreen.selectTab(tabId);

this._settingsScreen.showModal();
this._settingsScreenVisible = true;
},

_hideSettingsScreen: function()
{
if (this._settingsScreen)
this._settingsScreen.hide();
},

resize: function()
{
if (this._settingsScreen && this._settingsScreen.isShowing())
this._settingsScreen.doResize();
}
}






WebInspector.ShortcutsScreen = function()
{
this._sections =   ({});
}

WebInspector.ShortcutsScreen.prototype = {

section: function(name)
{
var section = this._sections[name];
if (!section)
this._sections[name] = section = new WebInspector.ShortcutsSection(name);
return section;
},


createShortcutsTabView: function()
{
var orderedSections = [];
for (var section in this._sections)
orderedSections.push(this._sections[section]);
function compareSections(a, b)
{
return a.order - b.order;
}
orderedSections.sort(compareSections);

var view = new WebInspector.View();

view.element.className = "settings-tab-container";
view.element.createChild("header").createChild("h3").appendChild(document.createTextNode(WebInspector.UIString("Shortcuts")));
var container = view.element.createChild("div", "help-container-wrapper").createChild("div");
container.className = "help-content help-container";
for (var i = 0; i < orderedSections.length; ++i)
orderedSections[i].renderSection(container);

return view;
}
}


WebInspector.shortcutsScreen = null;


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(keyElement, description)
{
this._lines.push({ key: keyElement, text: description })
},


renderSection: function(container)
{
var parent = container.createChild("div", "help-block");

var headLine = parent.createChild("div", "help-line");
headLine.createChild("div", "help-key-cell");
headLine.createChild("div", "help-section-title help-cell").textContent = this.name;

for (var i = 0; i < this._lines.length; ++i) {
var line = parent.createChild("div", "help-line");
var keyCell = line.createChild("div", "help-key-cell");
keyCell.appendChild(this._lines[i].key);
keyCell.appendChild(this._createSpan("help-key-delimiter", ":"));
line.createChild("div", "help-cell").textContent = this._lines[i].text;
}
},


_renderSequence: function(sequence, delimiter)
{
var delimiterSpan = this._createSpan("help-key-delimiter", delimiter);
return this._joinNodes(sequence.map(this._renderKey.bind(this)), delimiterSpan);
},


_renderKey: function(key)
{
var keyName = key.name;
var plus = this._createSpan("help-combine-keys", "+");
return this._joinNodes(keyName.split(" + ").map(this._createSpan.bind(this, "help-key monospace")), plus);
},


_createSpan: function(className, textContent)
{
var node = document.createElement("span");
node.className = className;
node.textContent = textContent;
return node;
},


_joinNodes: function(nodes, delimiter)
{
var result = document.createDocumentFragment();
for (var i = 0; i < nodes.length; ++i) {
if (i > 0)
result.appendChild(delimiter.cloneNode(true));
result.appendChild(nodes[i]);
}
return result;
}
}






WebInspector.OverridesView = function()
{
WebInspector.View.call(this);
this.registerRequiredCSS("helpScreen.css");
this.element.addStyleClass("fill");
this.element.addStyleClass("help-window-main");
this.element.addStyleClass("settings-tab-container");

var paneContent = this.element.createChild("div", "tabbed-pane-content");

function appendBlockTo(targetElement, contentElement)
{
var blockElement = targetElement.createChild("div", "help-block");
blockElement.appendChild(contentElement);
}

var headerTitle = paneContent.createChild("header").createChild("h3");
headerTitle.appendChild(document.createTextNode(WebInspector.UIString("Overrides")));

var container = paneContent.createChild("div", "help-container-wrapper").createChild("div", "settings-tab help-content help-container");
this.containerElement = container;
appendBlockTo(container, this._createUserAgentControl());
appendBlockTo(container, this._createDeviceMetricsControl());
appendBlockTo(container, this._createGeolocationOverrideControl());
appendBlockTo(container, this._createDeviceOrientationOverrideControl());
appendBlockTo(container, this._createCheckboxSetting(WebInspector.UIString("Emulate touch events"), WebInspector.settings.emulateTouchEvents));
appendBlockTo(container, this._createMediaEmulationElement());

this._statusElement = document.createElement("span");
this._statusElement.textContent = WebInspector.UIString("Overrides");
}

WebInspector.OverridesView.showInDrawer = function()
{
if (!WebInspector.OverridesView._view)
WebInspector.OverridesView._view = new WebInspector.OverridesView();
var view = WebInspector.OverridesView._view;
WebInspector.showViewInDrawer(view._statusElement, view);
}

WebInspector.OverridesView.prototype = {

_createCheckboxSetting: function(name, setting, omitParagraphElement, inputElement)
{
var input = inputElement || document.createElement("input");
input.type = "checkbox";
input.name = name;
input.checked = setting.get();

function listener()
{
setting.set(input.checked);
}
input.addEventListener("click", listener, false);

var label = document.createElement("label");
label.appendChild(input);
label.appendChild(document.createTextNode(name));
if (omitParagraphElement)
return label;

var p = document.createElement("p");
p.appendChild(label);
return p;
},

_createUserAgentControl: function()
{
var userAgent = WebInspector.settings.userAgent.get();

var p = document.createElement("p");
var labelElement = p.createChild("label");
var checkboxElement = labelElement.createChild("input");
checkboxElement.type = "checkbox";
checkboxElement.checked = false;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("User Agent")));
p.appendChild(this._createUserAgentSelectRowElement(checkboxElement));
return p;
},

_createUserAgentSelectRowElement: function(checkboxElement)
{
var userAgent = WebInspector.settings.userAgent.get();





const userAgents = [
["Internet Explorer 9", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"],
["Internet Explorer 8", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"],
["Internet Explorer 7", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"],

["Firefox 7 \u2014 Windows", "Mozilla/5.0 (Windows NT 6.1; Intel Mac OS X 10.6; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"],
["Firefox 7 \u2014 Mac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"],
["Firefox 4 \u2014 Windows", "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"],
["Firefox 4 \u2014 Mac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"],
["Firefox 14 \u2014 Android Mobile", "Mozilla/5.0 (Android; Mobile; rv:14.0) Gecko/14.0 Firefox/14.0"],
["Firefox 14 \u2014 Android Tablet", "Mozilla/5.0 (Android; Tablet; rv:14.0) Gecko/14.0 Firefox/14.0"],

["Chrome \u2014 Android Mobile", "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19"],
["Chrome \u2014 Android Tablet", "Mozilla/5.0 (Linux; Android 4.1.2; Nexus 7 Build/JZ054K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19"],

["iPhone \u2014 iOS 5", "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3", "640x960x1"],
["iPhone \u2014 iOS 4", "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5", "640x960x1"],
["iPad \u2014 iOS 5", "Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3", "1024x768x1"],
["iPad \u2014 iOS 4", "Mozilla/5.0 (iPad; CPU OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5", "1024x768x1"],

["Android 2.3 \u2014 Nexus S", "Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "480x800x1.1"],
["Android 4.0.2 \u2014 Galaxy Nexus", "Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "720x1280x1.1"],

["BlackBerry \u2014 PlayBook 2.1", "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+", "1024x600x1"],
["BlackBerry \u2014 9900", "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.187 Mobile Safari/534.11+", "640x480x1"],
["BlackBerry \u2014 BB10", "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.1+ (KHTML, like Gecko) Version/10.0.0.1337 Mobile Safari/537.1+", "768x1280x1"],

["MeeGo \u2014 Nokia N9", "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", "480x854x1"],

[WebInspector.UIString("Other..."), "Other"]
];

var fieldsetElement = document.createElement("fieldset");
this._selectElement = fieldsetElement.createChild("select");
this._otherUserAgentElement = fieldsetElement.createChild("input");
this._otherUserAgentElement.type = "text";
this._otherUserAgentElement.value = userAgent;
this._otherUserAgentElement.title = userAgent;
this._userAgentFieldsetElement = fieldsetElement;

var selectionRestored = false;
for (var i = 0; i < userAgents.length; ++i) {
var agent = userAgents[i];
var option = new Option(agent[0], agent[1]);
option._metrics = agent[2] ? agent[2] : "";
this._selectElement.add(option);
if (userAgent === agent[1]) {
this._selectElement.selectedIndex = i;
selectionRestored = true;
}
}

if (!selectionRestored) {
if (!userAgent)
this._selectElement.selectedIndex = 0;
else
this._selectElement.selectedIndex = userAgents.length - 1;
}

this._selectElement.addEventListener("change", this._selectionChanged.bind(this, true), false);

fieldsetElement.addEventListener("dblclick", textDoubleClicked.bind(this), false);
this._otherUserAgentElement.addEventListener("blur", textChanged.bind(this), false);

function textDoubleClicked()
{
this._selectElement.selectedIndex = userAgents.length - 1;
this._selectionChanged();
}

function textChanged()
{
WebInspector.settings.userAgent.set(this._otherUserAgentElement.value);
}

function checkboxClicked()
{
if (checkboxElement.checked) {
this._userAgentFieldsetElement.disabled = false;
this._selectionChanged();
} else {
this._userAgentFieldsetElement.disabled = true;
this._otherUserAgentElement.disabled = true;
}
WebInspector.userAgentSupport.toggleUserAgentOverride(checkboxElement.checked);
}
checkboxElement.addEventListener("click", checkboxClicked.bind(this), false);

checkboxClicked.call(this);
return fieldsetElement;
},


_selectionChanged: function(isUserGesture)
{
var value = this._selectElement.options[this._selectElement.selectedIndex].value;
if (value !== "Other") {
WebInspector.settings.userAgent.set(value);
this._otherUserAgentElement.value = value;
this._otherUserAgentElement.title = value;
this._otherUserAgentElement.disabled = true;
} else {
this._otherUserAgentElement.disabled = false;
this._otherUserAgentElement.focus();
}

if (isUserGesture) {
var metrics = this._selectElement.options[this._selectElement.selectedIndex]._metrics;
this._setDeviceMetricsOverride(WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(metrics), false, true);
}
},


_createInput: function(parentElement, id, defaultText, eventListener, numeric)
{
var element = parentElement.createChild("input");
element.id = id;
element.type = "text";
element.maxLength = 12;
element.style.width = "80px";
element.value = defaultText;
element.align = "right";
if (numeric)
element.className = "numeric";
element.addEventListener("blur", eventListener, false);
return element;
},

_createDeviceMetricsControl: function()
{
const metricsSetting = WebInspector.settings.deviceMetrics.get();
var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(metricsSetting);

const p = document.createElement("p");
const labelElement = p.createChild("label");
const checkboxElement = labelElement.createChild("input");
checkboxElement.id = "metrics-override-checkbox";
checkboxElement.type = "checkbox";
checkboxElement.checked = false;
checkboxElement.addEventListener("click", this._onMetricsCheckboxClicked.bind(this), false);
this._metricsCheckboxElement = checkboxElement;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Device metrics")));

const metricsSectionElement = this._createDeviceMetricsElement(metrics);
p.appendChild(metricsSectionElement);
this._metricsSectionElement = metricsSectionElement;
this._onMetricsCheckboxClicked();

return p;
},

_onMetricsCheckboxClicked: function()
{
var controlsDisabled = !this._metricsCheckboxElement.checked;
this._deviceMetricsFieldsetElement.disabled = controlsDisabled;

if (controlsDisabled) {
WebInspector.userAgentSupport.toggleDeviceMetricsOverride(false);
return;
}

var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput(this._widthOverrideElement.value, this._heightOverrideElement.value, this._fontScaleFactorOverrideElement.value);
if (metrics && metrics.isValid() && metrics.width && metrics.height) {
this._setDeviceMetricsOverride(metrics, false, false);
WebInspector.userAgentSupport.toggleDeviceMetricsOverride(true);
}
if (!this._widthOverrideElement.value)
this._widthOverrideElement.focus();
},

_applyDeviceMetricsUserInput: function()
{
this._setDeviceMetricsOverride(WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput(this._widthOverrideElement.value.trim(), this._heightOverrideElement.value.trim(), this._fontScaleFactorOverrideElement.value.trim()), true, false);
},


_setDeviceMetricsOverride: function(metrics, userInputModified, updateCheckbox)
{
function setValid(condition, element)
{
if (condition)
element.removeStyleClass("error-input");
else
element.addStyleClass("error-input");
}

setValid(metrics && metrics.isWidthValid(), this._widthOverrideElement);
setValid(metrics && metrics.isHeightValid(), this._heightOverrideElement);
setValid(metrics && metrics.isFontScaleFactorValid(), this._fontScaleFactorOverrideElement);

if (!metrics)
return;

if (!userInputModified) {
this._widthOverrideElement.value = metrics.widthToInput();
this._heightOverrideElement.value = metrics.heightToInput();
this._fontScaleFactorOverrideElement.value = metrics.fontScaleFactorToInput();
}

if (metrics.isValid()) {
var value = metrics.toSetting();
if (value !== WebInspector.settings.deviceMetrics.get())
WebInspector.settings.deviceMetrics.set(value);
}

if (this._metricsCheckboxElement && updateCheckbox) {
this._metricsCheckboxElement.checked = !!metrics.toSetting();
this._onMetricsCheckboxClicked();
}
},


_createDeviceMetricsElement: function(metrics)
{
var fieldsetElement = document.createElement("fieldset");
fieldsetElement.id = "metrics-override-section";
this._deviceMetricsFieldsetElement = fieldsetElement;

function swapDimensionsClicked(event)
{
var widthValue = this._widthOverrideElement.value;
this._widthOverrideElement.value = this._heightOverrideElement.value;
this._heightOverrideElement.value = widthValue;
this._applyDeviceMetricsUserInput();
}

var tableElement = fieldsetElement.createChild("table", "nowrap");

var rowElement = tableElement.createChild("tr");
var cellElement = rowElement.createChild("td");
cellElement.appendChild(document.createTextNode(WebInspector.UIString("Screen resolution:")));
cellElement = rowElement.createChild("td");
this._widthOverrideElement = this._createInput(cellElement, "metrics-override-width", String(metrics.width || screen.width), this._applyDeviceMetricsUserInput.bind(this), true);
cellElement.appendChild(document.createTextNode(" \u00D7 ")); 
this._heightOverrideElement = this._createInput(cellElement, "metrics-override-height", String(metrics.height || screen.height), this._applyDeviceMetricsUserInput.bind(this), true);
cellElement.appendChild(document.createTextNode(" \u2014 ")); 
this._swapDimensionsElement = cellElement.createChild("button");
this._swapDimensionsElement.appendChild(document.createTextNode(" \u21C4 ")); 
this._swapDimensionsElement.title = WebInspector.UIString("Swap dimensions");
this._swapDimensionsElement.addEventListener("click", swapDimensionsClicked.bind(this), false);

rowElement = tableElement.createChild("tr");
cellElement = rowElement.createChild("td");
cellElement.appendChild(document.createTextNode(WebInspector.UIString("Font scale factor:")));
cellElement = rowElement.createChild("td");
this._fontScaleFactorOverrideElement = this._createInput(cellElement, "metrics-override-font-scale", String(metrics.fontScaleFactor || 1), this._applyDeviceMetricsUserInput.bind(this), true);

rowElement = tableElement.createChild("tr");
cellElement = rowElement.createChild("td");
cellElement.colSpan = 2;
this._fitWindowCheckboxElement = document.createElement("input");
cellElement.appendChild(this._createCheckboxSetting(WebInspector.UIString("Fit in window"), WebInspector.settings.deviceFitWindow, true, this._fitWindowCheckboxElement));

return fieldsetElement;
},

_createGeolocationOverrideControl: function()
{
const geolocationSetting = WebInspector.settings.geolocationOverride.get();
var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseSetting(geolocationSetting);
var p = document.createElement("p");
var labelElement = p.createChild("label");
var checkboxElement = labelElement.createChild("input");
checkboxElement.id = "geolocation-override-checkbox";
checkboxElement.type = "checkbox";
checkboxElement.checked = false;
checkboxElement.addEventListener("click", this._onGeolocationOverrideCheckboxClicked.bind(this), false);
this._geolocationOverrideCheckboxElement = checkboxElement;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Override Geolocation")));

var geolocationSectionElement = this._createGeolocationOverrideElement(geolocation);
p.appendChild(geolocationSectionElement);
this._geolocationSectionElement = geolocationSectionElement;
this._onGeolocationOverrideCheckboxClicked();
return p;
},

_onGeolocationOverrideCheckboxClicked: function()
{
var controlsDisabled = !this._geolocationOverrideCheckboxElement.checked;
this._geolocationFieldsetElement.disabled = controlsDisabled;

if (controlsDisabled) {
WebInspector.userAgentSupport.toggleGeolocationPositionOverride(false);
return;
}

var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput(this._latitudeElement.value, this._longitudeElement.value, this._geolocationErrorElement.checked);
if (geolocation) {
this._setGeolocationPosition(geolocation, false, false);
WebInspector.userAgentSupport.toggleGeolocationPositionOverride(true);
}
if (!this._latitudeElement.value)
this._latitudeElement.focus();
},

_applyGeolocationUserInput: function()
{
this._setGeolocationPosition(WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput(this._latitudeElement.value.trim(), this._longitudeElement.value.trim(), this._geolocationErrorElement.checked), true, false);
},


_setGeolocationPosition: function(geolocation, userInputModified, updateCheckbox)
{
if (!geolocation)
return;

if (!userInputModified) {
this._latitudeElement.value = geolocation.latitude;
this._longitudeElement.value = geolocation.longitude;
}

var value = geolocation.toSetting();
WebInspector.settings.geolocationOverride.set(value);

if (this._geolocationOverrideCheckboxElement && updateCheckbox) {
this._geolocationOverrideCheckboxElement.checked = !!geolocation.toSetting();
this._onGeolocationOverrideCheckboxClicked();
}
},


_createGeolocationOverrideElement: function(geolocation)
{
var fieldsetElement = document.createElement("fieldset");
fieldsetElement.id = "geolocation-override-section";
this._geolocationFieldsetElement = fieldsetElement;

var tableElement = fieldsetElement.createChild("table");
var rowElement = tableElement.createChild("tr");
var cellElement = rowElement.createChild("td");
cellElement.appendChild(document.createTextNode(WebInspector.UIString("Geolocation Position") + ":"));
cellElement = rowElement.createChild("td");
cellElement.appendChild(document.createTextNode(WebInspector.UIString("Lat = ")));
this._latitudeElement = this._createInput(cellElement, "geolocation-override-latitude", String(geolocation.latitude), this._applyGeolocationUserInput.bind(this), true);
cellElement.appendChild(document.createTextNode(" , "));
cellElement.appendChild(document.createTextNode(WebInspector.UIString("Lon = ")));
this._longitudeElement = this._createInput(cellElement, "geolocation-override-longitude", String(geolocation.longitude), this._applyGeolocationUserInput.bind(this), true);
rowElement = tableElement.createChild("tr");
cellElement = rowElement.createChild("td");
cellElement.colSpan = 2;
var geolocationErrorLabelElement = document.createElement("label");
var geolocationErrorCheckboxElement = geolocationErrorLabelElement.createChild("input");
geolocationErrorCheckboxElement.id = "geolocation-error";
geolocationErrorCheckboxElement.type = "checkbox";
geolocationErrorCheckboxElement.checked = !geolocation || geolocation.error;
geolocationErrorCheckboxElement.addEventListener("click", this._applyGeolocationUserInput.bind(this), false);
geolocationErrorLabelElement.appendChild(document.createTextNode(WebInspector.UIString("Emulate position unavailable")));
this._geolocationErrorElement = geolocationErrorCheckboxElement;
cellElement.appendChild(geolocationErrorLabelElement);

return fieldsetElement;
},

_createDeviceOrientationOverrideControl: function()
{
const deviceOrientationSetting = WebInspector.settings.deviceOrientationOverride.get();
var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseSetting(deviceOrientationSetting);

var p = document.createElement("p");
var labelElement = p.createChild("label");
var checkboxElement = labelElement.createChild("input");
checkboxElement.id = "device-orientation-override-checkbox";
checkboxElement.type = "checkbox";
checkboxElement.checked = false;
checkboxElement.addEventListener("click", this._onDeviceOrientationOverrideCheckboxClicked.bind(this), false);
this._deviceOrientationOverrideCheckboxElement = checkboxElement;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Override Device Orientation")));

var deviceOrientationSectionElement = this._createDeviceOrientationOverrideElement(deviceOrientation);
p.appendChild(deviceOrientationSectionElement);
this._deviceOrientationSectionElement = deviceOrientationSectionElement;
this._onDeviceOrientationOverrideCheckboxClicked();
return p;
},

_onDeviceOrientationOverrideCheckboxClicked: function()
{
var controlsDisabled = !this._deviceOrientationOverrideCheckboxElement.checked;
this._deviceOrientationFieldsetElement.disabled = controlsDisabled;

if (controlsDisabled) {
WebInspector.userAgentSupport.toggleDeviceOrientationOverride(false);
return;
}

var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput(this._alphaElement.value, this._betaElement.value, this._gammaElement.value);
if (deviceOrientation) {
this._setDeviceOrientation(deviceOrientation, false, false);
WebInspector.userAgentSupport.toggleDeviceOrientationOverride(true);
}
if (!this._alphaElement.value)
this._alphaElement.focus();
},

_applyDeviceOrientationUserInput: function()
{
this._setDeviceOrientation(WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput(this._alphaElement.value.trim(), this._betaElement.value.trim(), this._gammaElement.value.trim()), true, false);
},


_setDeviceOrientation: function(deviceOrientation, userInputModified, updateCheckbox)
{
if (!deviceOrientation)
return;

if (!userInputModified) {
this._alphaElement.value = deviceOrientation.alpha;
this._betaElement.value = deviceOrientation.beta;
this._gammaElement.value = deviceOrientation.gamma;
}

var value = deviceOrientation.toSetting();
WebInspector.settings.deviceOrientationOverride.set(value);

if (this._deviceOrientationOverrideCheckboxElement && updateCheckbox) {
this._deviceOrientationOverrideCheckboxElement.checked = !!deviceOrientation.toSetting();
this._onDeviceOrientationOverrideCheckboxClicked();
}
},


_createDeviceOrientationOverrideElement: function(deviceOrientation)
{
var fieldsetElement = document.createElement("fieldset");
fieldsetElement.id = "device-orientation-override-section";
this._deviceOrientationFieldsetElement = fieldsetElement;

var tableElement = fieldsetElement.createChild("table");

var rowElement = tableElement.createChild("tr");
var cellElement = rowElement.createChild("td");
cellElement.appendChild(document.createTextNode("\u03B1: "));
this._alphaElement = this._createInput(cellElement, "device-orientation-override-alpha", String(deviceOrientation.alpha), this._applyDeviceOrientationUserInput.bind(this), true);
cellElement.appendChild(document.createTextNode(" \u03B2: "));
this._betaElement = this._createInput(cellElement, "device-orientation-override-beta", String(deviceOrientation.beta), this._applyDeviceOrientationUserInput.bind(this), true);
cellElement.appendChild(document.createTextNode(" \u03B3: "));
this._gammaElement = this._createInput(cellElement, "device-orientation-override-gamma", String(deviceOrientation.gamma), this._applyDeviceOrientationUserInput.bind(this), true);

return fieldsetElement;
},

_createMediaEmulationElement: function()
{
const p = document.createElement("p");
const labelElement = p.createChild("label");
const checkboxElement = labelElement.createChild("input");
checkboxElement.type = "checkbox";
checkboxElement.checked = false;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Emulate CSS media")));

var mediaSelectElement = p.createChild("select");
var mediaTypes = WebInspector.CSSStyleModel.MediaTypes;
var defaultMedia = WebInspector.settings.emulatedCSSMedia.get();
for (var i = 0; i < mediaTypes.length; ++i) {
var mediaType = mediaTypes[i];
if (mediaType === "all") {

continue;
}
var option = document.createElement("option");
option.text = mediaType;
option.value = mediaType;
mediaSelectElement.add(option);
if (mediaType === defaultMedia)
mediaSelectElement.selectedIndex = mediaSelectElement.options.length - 1;
}
mediaSelectElement.disabled = true;
var boundListener = this._emulateMediaChanged.bind(this, checkboxElement, mediaSelectElement);
checkboxElement.addEventListener("click", boundListener, false);
mediaSelectElement.addEventListener("change", boundListener, false);
return p;
},

_emulateMediaChanged: function(checkbox, select)
{
select.disabled = !checkbox.checked;
if (checkbox.checked) {
var media = select.options[select.selectedIndex].value;
WebInspector.settings.emulatedCSSMedia.set(media);
PageAgent.setEmulatedMedia(media);
} else
PageAgent.setEmulatedMedia("");
WebInspector.cssModel.mediaQueryResultChanged();
},

__proto__: WebInspector.View.prototype
}












WebInspector.HAREntry = function(request)
{
this._request = request;
}

WebInspector.HAREntry.prototype = {

build: function()
{
var entry =  {
startedDateTime: new Date(this._request.startTime * 1000),
time: WebInspector.HAREntry._toMilliseconds(this._request.duration),
request: this._buildRequest(),
response: this._buildResponse(),
cache: { }, 
timings: this._buildTimings()
};
var page = WebInspector.networkLog.pageLoadForRequest(this._request);
if (page)
entry.pageref = "page_" + page.id;
return entry;
},


_buildRequest: function()
{
var res = {
method: this._request.requestMethod,
url: this._buildRequestURL(this._request.url),
httpVersion: this._request.requestHttpVersion,
headers: this._request.requestHeaders,
queryString: this._buildParameters(this._request.queryParameters || []),
cookies: this._buildCookies(this._request.requestCookies || []),
headersSize: this._request.requestHeadersSize,
bodySize: this.requestBodySize
};
if (this._request.requestFormData)
res.postData = this._buildPostData();

return res;
},


_buildResponse: function()
{
return {
status: this._request.statusCode,
statusText: this._request.statusText,
httpVersion: this._request.responseHttpVersion,
headers: this._request.responseHeaders,
cookies: this._buildCookies(this._request.responseCookies || []),
content: this._buildContent(),
redirectURL: this._request.responseHeaderValue("Location") || "",
headersSize: this._request.responseHeadersSize,
bodySize: this.responseBodySize
};
},


_buildContent: function()
{
var content = {
size: this._request.resourceSize,
mimeType: this._request.mimeType,

};
var compression = this.responseCompression;
if (typeof compression === "number")
content.compression = compression;
return content;
},


_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._request.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._request.receiveDuration),
ssl: ssl
};
},


_buildPostData: function()
{
var res = {
mimeType: this._request.requestHeaderValue("Content-Type"),
text: this._request.requestFormData
};
if (this._request.formParameters)
res.params = this._buildParameters(this._request.formParameters);
return res;
},


_buildParameters: function(parameters)
{
return parameters.slice();
},


_buildRequestURL: function(url)
{
return url.split("#", 2)[0];
},


_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.expiresDate(new Date(this._request.startTime * 1000)),
httpOnly: cookie.httpOnly(),
secure: cookie.secure()
};
},


_interval: function(start, end)
{
var timing = this._request.timing;
if (!timing)
return -1;
var startTime = timing[start];
return typeof startTime !== "number" || startTime === -1 ? -1 : Math.round(timing[end] - startTime);
},


get requestBodySize()
{
return !this._request.requestFormData ? 0 : this._request.requestFormData.length;
},


get responseBodySize()
{
if (this._request.cached || this._request.statusCode === 304)
return 0;
return this._request.transferSize - this._request.responseHeadersSize
},


get responseCompression()
{
if (this._request.cached || this._request.statusCode === 304)
return;
return this._request.resourceSize - (this._request.transferSize - this._request.responseHeadersSize);
}
}


WebInspector.HAREntry._toMilliseconds = function(time)
{
return time === -1 ? -1 : Math.round(time * 1000);
}


WebInspector.HARLog = function(requests)
{
this._requests = requests;
}

WebInspector.HARLog.prototype = {

build: function()
{
return {
version: "1.2",
creator: this._creator(),
pages: this._buildPages(),
entries: this._requests.map(this._convertResource.bind(this))
}
},

_creator: function()
{
var webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent);

return {
name: "WebInspector",
version: webKitVersion ? webKitVersion[1] : "n/a"
};
},


_buildPages: function()
{
var seenIdentifiers = {};
var pages = [];
for (var i = 0; i < this._requests.length; ++i) {
var page = WebInspector.networkLog.pageLoadForRequest(this._requests[i]);
if (!page || seenIdentifiers[page.id])
continue;
seenIdentifiers[page.id] = true;
pages.push(this._convertPage(page));
}
return pages;
},


_convertPage: function(page)
{
return {
startedDateTime: new Date(page.startTime * 1000),
id: "page_" + page.id,
title: page.url, 
pageTimings: {
onContentLoad: this._pageEventTime(page, page.contentLoadTime),
onLoad: this._pageEventTime(page, page.loadTime)
}
}
},


_convertResource: function(request)
{
return (new WebInspector.HAREntry(request)).build();
},


_pageEventTime: function(page, time)
{
var startTime = page.startTime;
if (time === -1 || startTime === -1)
return -1;
return WebInspector.HAREntry._toMilliseconds(time - startTime);
}
}


WebInspector.HARWriter = function()
{
}

WebInspector.HARWriter.prototype = {

write: function(stream, requests, progress)
{
this._stream = stream;
this._harLog = (new WebInspector.HARLog(requests)).build();
this._pendingRequests = 1; 
var entries = this._harLog.entries;
for (var i = 0; i < entries.length; ++i) {
var content = requests[i].content;
if (typeof content === "undefined" && requests[i].finished) {
++this._pendingRequests;
requests[i].requestContent(this._onContentAvailable.bind(this, entries[i]));
} else if (content !== null)
entries[i].response.content.text = content;
}
var compositeProgress = new WebInspector.CompositeProgress(progress);
this._writeProgress = compositeProgress.createSubProgress();
if (--this._pendingRequests) {
this._requestsProgress = compositeProgress.createSubProgress();
this._requestsProgress.setTitle(WebInspector.UIString("Collecting content…"));
this._requestsProgress.setTotalWork(this._pendingRequests);
} else
this._beginWrite();
},


_onContentAvailable: function(entry, content, contentEncoded, mimeType)
{
if (content !== null)
entry.response.content.text = content;
if (this._requestsProgress)
this._requestsProgress.worked();
if (!--this._pendingRequests) {
this._requestsProgress.done();
this._beginWrite();
}
},

_beginWrite: function()
{
const jsonIndent = 2;
this._text = JSON.stringify({log: this._harLog}, null, jsonIndent);
this._writeProgress.setTitle(WebInspector.UIString("Writing file…"));
this._writeProgress.setTotalWork(this._text.length);
this._bytesWritten = 0;
this._writeNextChunk(this._stream);
},


_writeNextChunk: function(stream, error)
{
if (this._bytesWritten >= this._text.length || error) {
stream.close();
this._writeProgress.done();
return;
}
const chunkSize = 100000;
var text = this._text.substring(this._bytesWritten, this._bytesWritten + chunkSize);
this._bytesWritten += text.length;
stream.write(text, this._writeNextChunk.bind(this));
this._writeProgress.setWorked(this._bytesWritten);
}
}













WebInspector.CookieParser = function()
{
}


WebInspector.CookieParser.KeyValue = function(key, value, position)
{
this.key = key;
this.value = value;
this.position = position;
}

WebInspector.CookieParser.prototype = {

cookies: function()
{
return this._cookies;
},


parseCookie: function(cookieHeader)
{
if (!this._initialize(cookieHeader))
return null;

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 null;
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.setSize(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 = new WebInspector.CookieParser.KeyValue(keyValueMatch[1], keyValueMatch[2] && keyValueMatch[2].trim(), this._originalInputLength - this._input.length);
        this._input = this._input.slice(keyValueMatch[0].length);
        return result;
    },

    /**
* @return {boolean}
*/
_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.setSize(keyValue.position - this._lastCookiePosition);


this._lastCookie = typeof keyValue.value === "string" ? 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 = {

name: function()
{
return this._name;
},


value: function()
{
return this._value;
},


type: function()
{
return this._type;
},


httpOnly: function()
{
return "httponly" in this._attributes;
},


secure: function()
{
return "secure" in this._attributes;
},


session: function()
{


return !("expires" in this._attributes || "max-age" in this._attributes);
},


path: function()
{
return this._attributes["path"];
},


port: function()
{
return this._attributes["port"];
},


domain: function()
{
return this._attributes["domain"];
},


expires: function()
{
return this._attributes["expires"];
},


maxAge: function()
{
return this._attributes["max-age"];
},


size: function()
{
return this._size;
},


setSize: function(size)
{
this._size = size;
},


expiresDate: function(requestDate)
{

if (this.maxAge()) {
var targetDate = requestDate === null ? new Date() : requestDate;
return new Date(targetDate.getTime() + 1000 * this.maxAge());
}

if (this.expires())
return new Date(this.expires());

return null;
},


attributes: function()
{
return this._attributes;
},


addAttribute: function(key, value)
{
this._attributes[key.toLowerCase()] = value;
},


remove: function(callback)
{
PageAgent.deleteCookie(this.name(), (this.secure() ? "https://" : "http://") + this.domain() + this.path(), callback);
}
}


WebInspector.Cookie.Type = {
Request: 0,
Response: 1
};

WebInspector.Cookies = {}


WebInspector.Cookies.getCookiesAsync = function(callback)
{

function mycallback(error, cookies, cookiesString)
{
if (error)
return;
callback(cookies.map(WebInspector.Cookies.buildCookieProtocolObject));
}

PageAgent.getCookies(mycallback);
}


WebInspector.Cookies.buildCookieProtocolObject = function(protocolCookie)
{
var cookie = new WebInspector.Cookie(protocolCookie.name, protocolCookie.value, null);
cookie.addAttribute("domain", protocolCookie["domain"]);
cookie.addAttribute("path", protocolCookie["path"]);
cookie.addAttribute("port", protocolCookie["port"]);
if (protocolCookie["expires"])
cookie.addAttribute("expires", protocolCookie["expires"]);
if (protocolCookie["httpOnly"])
cookie.addAttribute("httpOnly");
if (protocolCookie["secure"])
cookie.addAttribute("secure");
cookie.setSize(protocolCookie["size"]);
return cookie;
}


WebInspector.Cookies.cookieMatchesResourceURL = function(cookie, resourceURL)
{
var url = resourceURL.asParsedURL();
if (!url || !WebInspector.Cookies.cookieDomainMatchesResourceDomain(cookie.domain(), url.host))
return false;
return (url.path.startsWith(cookie.path())
&& (!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.Toolbar = function()
{
this.element = document.getElementById("toolbar");
WebInspector.installDragHandle(this.element, this._toolbarDragStart.bind(this), this._toolbarDrag.bind(this), this._toolbarDragEnd.bind(this), "default");

this._dropdownButton = document.getElementById("toolbar-dropdown-arrow");
this._dropdownButton.addEventListener("click", this._toggleDropdown.bind(this), false);

this._panelsMenuButton = document.getElementById("toolbar-panels-menu");
if (this._isToolbarCustomizable()) {
this._panelsMenuButton.addEventListener("mousedown", this._togglePanelsMenu.bind(this), false);
this._panelsMenuButton.removeStyleClass("hidden");
}

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

this._panelDescriptors = [];
}

WebInspector.Toolbar.prototype = {
resize: function()
{
this._updateDropdownButtonAndHideDropdown();
},


addPanel: function(panelDescriptor)
{
this._panelDescriptors.push(panelDescriptor);
panelDescriptor._toolbarElement = this._createPanelToolbarItem(panelDescriptor);
if (!this._isToolbarCustomizable() || this._isPanelVisible(panelDescriptor.name()))
this.element.insertBefore(panelDescriptor._toolbarElement, this._panelInsertLocation(panelDescriptor));
this._updatePanelsMenuState();
this.resize();
},


_panelInsertLocation: function(panelDescriptor)
{
if (!this._isToolbarCustomizable())
return null;

if (this._isDefaultPanel(panelDescriptor.name()))
return this._firstNonDefaultPanel || null;

if (!this._firstNonDefaultPanel)
this._firstNonDefaultPanel = panelDescriptor._toolbarElement;
return null;
},


_isDefaultPanel: function(name)
{
var defaultPanels = {
"elements": true,
"resources": true,
"scripts": true,
"console": true,
"network": true,
"timeline": true,
};
return !!defaultPanels[name];
},


_isPanelVisibleByDefault: function(name)
{
var visible = {
"elements": true,
"console": true,
"network": true,
"scripts": true,
"timeline": true,
"profiles": true,
"cpu-profiler": true,
"heap-profiler": true,
"audits": true,
"resources": true,
};
return !!visible[name];
},


_isToolbarCustomizable: function()
{
return WebInspector.experimentsSettings.customizableToolbar.isEnabled();
},


_isPanelVisible: function(name)
{
if (!this._isToolbarCustomizable())
return true;
var visiblePanels = WebInspector.settings.visiblePanels.get();
return visiblePanels.hasOwnProperty(name) ? visiblePanels[name] : this._isPanelVisibleByDefault(name);
},


_setPanelVisible: function(name, visible)
{
var visiblePanels = WebInspector.settings.visiblePanels.get();
visiblePanels[name] = visible;
WebInspector.settings.visiblePanels.set(visiblePanels);
},


_hidePanel: function(panelDescriptor)
{
if (!this._isPanelVisible(panelDescriptor.name()))
return;
var switchToSibling = panelDescriptor._toolbarElement.nextSibling;
if (!switchToSibling || !switchToSibling.classList.contains("toggleable"))
switchToSibling = panelDescriptor._toolbarElement.previousSibling;
if (!switchToSibling || !switchToSibling.classList || !switchToSibling.classList.contains("toggleable"))
return;
this._setPanelVisible(panelDescriptor.name(), false);
this.element.removeChild(panelDescriptor._toolbarElement);
if (WebInspector.inspectorView.currentPanel().name === panelDescriptor.name()) {
for (var i = 0; i < this._panelDescriptors.length; ++i) {
var descr = this._panelDescriptors[i];
if (descr._toolbarElement === switchToSibling) {
WebInspector.showPanel(descr.name());
break;
}
}
}
this._updatePanelsMenuState();
this.resize();
},

_updatePanelsMenuState: function()
{
if (this._panelDescriptors.every(function (descr) { return this._isPanelVisible(descr.name()); }, this) && this._allItemsFitOntoToolbar())
document.getElementById("toolbar-panels-menu").addStyleClass("disabled");
else
document.getElementById("toolbar-panels-menu").removeStyleClass("disabled");
},


_allItemsFitOntoToolbar: function()
{
var toolbarItems = this.element.querySelectorAll(".toolbar-item.toggleable");
return toolbarItems.length === 0 || this.element.scrollHeight < toolbarItems[0].offsetHeight * 2;
},


_showPanel: function(panelDescriptor)
{
if (this._isPanelVisible(panelDescriptor.name()))
return;
this.element.appendChild(panelDescriptor._toolbarElement);
panelDescriptor._toolbarElement.removeStyleClass("hidden");
this._setPanelVisible(panelDescriptor.name(), true);
this._updatePanelsMenuState();
this.resize();
},


_createPanelToolbarItem: function(panelDescriptor, noCloseButton)
{
var toolbarItem = document.createElement("button");
toolbarItem.className = "toolbar-item toggleable";
toolbarItem.panelDescriptor = panelDescriptor;
toolbarItem.addStyleClass(panelDescriptor.name());


function onContextMenuEvent(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Close"), this._hidePanel.bind(this, panelDescriptor));
contextMenu.show();
}
if (!this._isDefaultPanel(panelDescriptor.name()))
toolbarItem.addEventListener("contextmenu", onContextMenuEvent.bind(this), true);

function onToolbarItemClicked()
{
this._showPanel(panelDescriptor);
this._updateDropdownButtonAndHideDropdown();
WebInspector.inspectorView.setCurrentPanel(panelDescriptor.panel());
}
toolbarItem.addEventListener("click", onToolbarItemClicked.bind(this), false);

function onToolbarItemCloseButtonClicked(event)
{
event.stopPropagation();
this._hidePanel(panelDescriptor);
}

function panelSelected()
{
if (WebInspector.inspectorView.currentPanel() && panelDescriptor.name() === WebInspector.inspectorView.currentPanel().name)
toolbarItem.addStyleClass("toggled-on");
else
toolbarItem.removeStyleClass("toggled-on");
}
WebInspector.inspectorView.addEventListener(WebInspector.InspectorView.Events.PanelSelected, panelSelected);

var iconElement = toolbarItem.createChild("div", "toolbar-icon");
toolbarItem.createChild("div", "toolbar-label").textContent = panelDescriptor.title();
if (this._isToolbarCustomizable() && !this._isDefaultPanel(panelDescriptor.name()) && !noCloseButton) {
var closeButton = toolbarItem.createChild("div", "close-button");
closeButton.addEventListener("click", onToolbarItemCloseButtonClicked.bind(this), false);
}
if (panelDescriptor.iconURL()) {
iconElement.addStyleClass("custom-toolbar-icon");
iconElement.style.backgroundImage = "url(" + panelDescriptor.iconURL() + ")";
}
panelSelected();
return toolbarItem;
},


_isDockedToBottom: function()
{
return !!WebInspector.dockController && WebInspector.dockController.dockSide() == WebInspector.DockController.State.DockedToBottom;
},


_isUndocked: function()
{
return !!WebInspector.dockController && WebInspector.dockController.dockSide() == WebInspector.DockController.State.Undocked;
},


_toolbarDragStart: function(event)
{
if (this._isUndocked())
return false;

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

if (target !== this.element && !target.hasStyleClass("toolbar-item"))
return false;

this._lastScreenX = event.screenX;
this._lastScreenY = event.screenY;
this._lastHeightDuringDrag = window.innerHeight;
this._startDistanceToRight = window.innerWidth - event.clientX;
this._startDinstanceToBottom = window.innerHeight - event.clientY;
return true;
},

_toolbarDragEnd: function(event)
{


this._toolbarDrag(event);
delete this._lastScreenX;
delete this._lastScreenY;
delete this._lastHeightDuringDrag;
delete this._startDistanceToRight;
delete this._startDinstanceToBottom;
},

_toolbarDrag: function(event)
{
event.preventDefault();

if (this._isUndocked())
return this._toolbarDragMoveWindow(event);

return this._toolbarDragChangeDocking(event);
},

_toolbarDragMoveWindow: function(event)
{
var x = event.screenX - this._lastScreenX;
var y = event.screenY - this._lastScreenY;
this._lastScreenX = event.screenX;
this._lastScreenY = event.screenY;
InspectorFrontendHost.moveWindowBy(x, y);
},

_toolbarDragChangeDocking: function(event)
{
if (this._isDockedToBottom()) {
var distanceToRight = window.innerWidth - event.clientX;
if (distanceToRight < this._startDistanceToRight * 2 / 3) {
InspectorFrontendHost.requestSetDockSide(WebInspector.DockController.State.DockedToRight);
return true;
}
} else {
var distanceToBottom = window.innerHeight - event.clientY;
if (distanceToBottom < this._startDinstanceToBottom * 2 / 3) {
InspectorFrontendHost.requestSetDockSide(WebInspector.DockController.State.DockedToBottom);
return true;
}
}
},

_onClose: function()
{
WebInspector.close();
},

_setDropdownVisible: function(visible)
{
if (!this._dropdown) {
if (!visible)
return;
this._dropdown = new WebInspector.ToolbarDropdown(this);
}
if (visible)
this._dropdown.show();
else
this._dropdown.hide();
},

_toggleDropdown: function()
{
this._setDropdownVisible(!this._dropdown || !this._dropdown.visible);
},

_togglePanelsMenu: function(event)
{
function activatePanel(panelDescriptor)
{
this._showPanel(panelDescriptor);
WebInspector.showPanel(panelDescriptor.name());
}

var contextMenu = new WebInspector.ContextMenu(event);
var currentPanelName = WebInspector.inspectorView.currentPanel().name;
var toolbarItems = this.element.querySelectorAll(".toolbar-item.toggleable");
for (var i = 0; i < toolbarItems.length; ++i) {
if (toolbarItems[i].offsetTop >= toolbarItems[0].offsetHeight) {
var descr = toolbarItems[i].panelDescriptor;
if (descr.name() === currentPanelName)
contextMenu.appendCheckboxItem(descr.title(), activatePanel.bind(this, descr), true);
else
contextMenu.appendItem(descr.title(), activatePanel.bind(this, descr));
}
}
contextMenu.appendSeparator();
for (var i = 0; i < this._panelDescriptors.length; ++i) {
var descr = this._panelDescriptors[i];
if (this._isPanelVisible(descr.name()))
continue;
contextMenu.appendItem(descr.title(), activatePanel.bind(this, descr));
}

contextMenu.showSoftMenu();
},

_updateDropdownButtonAndHideDropdown: function()
{
WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateDropdownButtonAndHideDropdown);
},

_innerUpdateDropdownButtonAndHideDropdown: function()
{
if (this._isToolbarCustomizable()) {
this._updatePanelsMenuState();
return;
}
this._setDropdownVisible(false);

if (this.element.scrollHeight > this.element.offsetHeight)
this._dropdownButton.removeStyleClass("hidden");
else
this._dropdownButton.addStyleClass("hidden");
}
}


WebInspector.ToolbarDropdown = function(toolbar)
{
this._toolbar = toolbar;
this._arrow = document.getElementById("toolbar-dropdown-arrow");
this.element = document.createElement("div");
this.element.id = "toolbar-dropdown";
this.element.className = "toolbar-small";
this._contentElement = this.element.createChild("div", "scrollable-content");
this._contentElement.tabIndex = 0;
this._contentElement.addEventListener("keydown", this._onKeyDown.bind(this), true);
}

WebInspector.ToolbarDropdown.prototype = {
show: function()
{
if (this.visible)
return;
var style = this.element.style;
this._populate();
var top = this._arrow.totalOffsetTop() + this._arrow.clientHeight;
this._arrow.addStyleClass("dropdown-visible");
this.element.style.top = top + "px";
this.element.style.right = window.innerWidth - this._arrow.totalOffsetLeft() - this._arrow.clientWidth + "px";
this._contentElement.style.maxHeight = window.innerHeight - top - 20 + "px";
this._toolbar.element.appendChild(this.element);
},

hide: function()
{
if (!this.visible)
return;
this._arrow.removeStyleClass("dropdown-visible");
this.element.parentNode.removeChild(this.element);
this._contentElement.removeChildren();
},

get visible()
{
return !!this.element.parentNode;
},

_populate: function()
{
var toolbarItems = this._toolbar.element.querySelectorAll(".toolbar-item.toggleable");

var needsSeparator = false;
for (var i = 0; i < toolbarItems.length; ++i) {
if (toolbarItems[i].offsetTop >= toolbarItems[0].offsetHeight) {
this._contentElement.appendChild(this._toolbar._createPanelToolbarItem(toolbarItems[i].panelDescriptor, true));
needsSeparator = true;
}
}

var panelDescriptors = this._toolbar._panelDescriptors;
for (var i = 0; i < panelDescriptors.length; ++i) {
var descr = panelDescriptors[i];
if (this._toolbar._isPanelVisible(descr.name()))
continue;
if (needsSeparator) {
this._contentElement.createChild("div", "toolbar-items-separator");
needsSeparator = false;
}
this._contentElement.appendChild(this._toolbar._createPanelToolbarItem(descr, true));
}
},

_onKeyDown: function(event)
{
if (event.keyCode !== WebInspector.KeyboardShortcut.Keys.Esc.code)
return;
event.consume();
this.hide();
}
}


WebInspector.toolbar = null;






WebInspector.SearchController = function()
{
this._element = document.createElement("table");
this._element.className = "toolbar-search";
this._element.cellSpacing = 0;

this._firstRowElement = this._element.createChild("tr");
this._secondRowElement = this._element.createChild("tr", "hidden");


var searchControlElementColumn = this._firstRowElement.createChild("td"); 
this._searchControlElement = searchControlElementColumn.createChild("span", "toolbar-search-control");
this._searchInputElement = this._searchControlElement.createChild("input", "search-replace");
this._searchInputElement.id = "search-input-field";
this._searchInputElement.placeholder = WebInspector.UIString("Find");

this._filterControlElement = searchControlElementColumn.createChild("span", "toolbar-search-control");
this._filterControlElement.addStyleClass("hidden");
this._filterInputElement = this._filterControlElement.createChild("input", "filter");
this._filterInputElement.id = "filter-input-field";
this._filterInputElement.placeholder = WebInspector.UIString("Filter");

this._matchesElement = this._searchControlElement.createChild("label", "search-results-matches");
this._matchesElement.setAttribute("for", "search-input-field");

var searchNavigationElement = this._searchControlElement.createChild("div", "toolbar-search-navigation-controls");

this._searchNavigationPrevElement = searchNavigationElement.createChild("div", "toolbar-search-navigation toolbar-search-navigation-prev");
this._searchNavigationPrevElement.addEventListener("click", this._onPrevButtonSearch.bind(this), false);
this._searchNavigationPrevElement.title = WebInspector.UIString("Search Previous");

this._searchNavigationNextElement = searchNavigationElement.createChild("div", "toolbar-search-navigation toolbar-search-navigation-next"); 
this._searchNavigationNextElement.addEventListener("click", this._onNextButtonSearch.bind(this), false);
this._searchNavigationNextElement.title = WebInspector.UIString("Search Next");

this._searchInputElement.addEventListener("mousedown", this._onSearchFieldManualFocus.bind(this), false); 
this._searchInputElement.addEventListener("keydown", this._onKeyDown.bind(this), true);
this._filterInputElement.addEventListener("keydown", this._onKeyDown.bind(this), true);
this._filterInputElement.addEventListener("input", this._onFilterInput.bind(this), false);
this._searchInputElement.addEventListener("input", this._onSearchInput.bind(this), false);

this._replaceInputElement = this._secondRowElement.createChild("td").createChild("input", "search-replace toolbar-replace-control");
this._replaceInputElement.addEventListener("keydown", this._onKeyDown.bind(this), true);
this._replaceInputElement.placeholder = WebInspector.UIString("Replace");


this._findButtonElement = this._firstRowElement.createChild("td").createChild("button", "hidden");
this._findButtonElement.textContent = WebInspector.UIString("Find");
this._findButtonElement.tabIndex = -1;
this._findButtonElement.addEventListener("click", this._onNextButtonSearch.bind(this), false);

this._replaceButtonElement = this._secondRowElement.createChild("td").createChild("button");
this._replaceButtonElement.textContent = WebInspector.UIString("Replace");
this._replaceButtonElement.disabled = true;
this._replaceButtonElement.tabIndex = -1;
this._replaceButtonElement.addEventListener("click", this._replace.bind(this), false);


this._prevButtonElement = this._firstRowElement.createChild("td").createChild("button", "hidden");
this._prevButtonElement.textContent = WebInspector.UIString("Previous");
this._prevButtonElement.disabled = true;
this._prevButtonElement.tabIndex = -1;
this._prevButtonElement.addEventListener("click", this._onPrevButtonSearch.bind(this), false);

this._replaceAllButtonElement = this._secondRowElement.createChild("td").createChild("button");
this._replaceAllButtonElement.textContent = WebInspector.UIString("Replace All");
this._replaceAllButtonElement.addEventListener("click", this._replaceAll.bind(this), false);


this._replaceElement = this._firstRowElement.createChild("td").createChild("span");

this._replaceCheckboxElement = this._replaceElement.createChild("input");
this._replaceCheckboxElement.type = "checkbox";
this._replaceCheckboxElement.id = "search-replace-trigger";
this._replaceCheckboxElement.addEventListener("click", this._updateSecondRowVisibility.bind(this), false);

this._replaceLabelElement = this._replaceElement.createChild("label");
this._replaceLabelElement.textContent = WebInspector.UIString("Replace");
this._replaceLabelElement.setAttribute("for", "search-replace-trigger");


this._filterCheckboxContainer = this._firstRowElement.createChild("td").createChild("span");

this._filterCheckboxElement = this._filterCheckboxContainer.createChild("input");
this._filterCheckboxElement.type = "checkbox";
this._filterCheckboxElement.id = "filter-trigger";
this._filterCheckboxElement.addEventListener("click", this._filterCheckboxClick.bind(this), false);

this._filterLabelElement = this._filterCheckboxContainer.createChild("label");
this._filterLabelElement.textContent = WebInspector.UIString("Filter");
this._filterLabelElement.setAttribute("for", "filter-trigger");


var cancelButtonElement = this._firstRowElement.createChild("td").createChild("button");
cancelButtonElement.textContent = WebInspector.UIString("Cancel");
cancelButtonElement.tabIndex = -1;
cancelButtonElement.addEventListener("click", this.cancelSearch.bind(this), false);
}

WebInspector.SearchController.prototype = {
updateSearchMatchesCount: function(matches, panel)
{
if (!panel)
panel = WebInspector.inspectorView.currentPanel();

panel.currentSearchMatches = matches;

if (panel === WebInspector.inspectorView.currentPanel())
this._updateSearchMatchesCountAndCurrentMatchIndex(WebInspector.inspectorView.currentPanel().currentQuery ? matches : 0, -1);
},

updateCurrentMatchIndex: function(currentMatchIndex, panel)
{
if (panel === WebInspector.inspectorView.currentPanel())
this._updateSearchMatchesCountAndCurrentMatchIndex(panel.currentSearchMatches, currentMatchIndex);
},

cancelSearch: function()
{
if (!this._searchIsVisible)
return;
if (this._filterCheckboxElement.checked) {
this._filterCheckboxElement.checked = false;
this._switchFilterToSearch();
} 
delete this._searchIsVisible;
WebInspector.inspectorView.setFooterElement(null);
this.resetSearch();
},

resetSearch: function()
{
this._performSearch("", false, false);
this._updateReplaceVisibility();
this._matchesElement.textContent = "";
},

disableSearchUntilExplicitAction: function()
{
this._performSearch("", false, false);
},


handleShortcut: function(event)
{
var isMac = WebInspector.isMac();

switch (event.keyIdentifier) {
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) {
this.showSearchField();
event.consume(true);
return true;
}
break;

case "F3":
if (!isMac) {
this.showSearchField();
event.consume();
}
break;

case "U+0047": 
var currentPanel = WebInspector.inspectorView.currentPanel();

if (isMac && event.metaKey && !event.ctrlKey && !event.altKey) {
if (event.shiftKey)
currentPanel.jumpToPreviousSearchResult();
else
currentPanel.jumpToNextSearchResult();
event.consume(true);
return true;
}
break;
}
return false;
},

_updateSearchNavigationButtonState: function(enabled)
{
this._replaceButtonElement.disabled = !enabled;
this._prevButtonElement.disabled = !enabled;
var panel = WebInspector.inspectorView.currentPanel();
if (enabled) {
this._searchNavigationPrevElement.addStyleClass("enabled");
this._searchNavigationNextElement.addStyleClass("enabled");
} else {
this._searchNavigationPrevElement.removeStyleClass("enabled");
this._searchNavigationNextElement.removeStyleClass("enabled");
}
},


_updateSearchMatchesCountAndCurrentMatchIndex: function(matches, currentMatchIndex)
{
if (matches === 0 || currentMatchIndex >= 0)
this._matchesElement.textContent = WebInspector.UIString("%d of %d", currentMatchIndex + 1, matches);
this._updateSearchNavigationButtonState(matches > 0);
},

showSearchField: function()
{
WebInspector.inspectorView.setFooterElement(this._element);
this._updateReplaceVisibility();
this._updateFilterVisibility();
if (WebInspector.currentFocusElement() !== this._searchInputElement) {
var selection = window.getSelection();
if (selection.rangeCount)
this._searchInputElement.value = selection.toString().replace(/\r?\n.*/, "");
}
this._performSearch(this._searchInputElement.value, true, false);
this._searchInputElement.focus();
this._searchInputElement.select();
this._searchIsVisible = true;
},

_switchFilterToSearch: function()
{
this._filterControlElement.addStyleClass("hidden");
this._searchControlElement.removeStyleClass("hidden");
this._searchInputElement.focus();
this._searchInputElement.select();
this._searchInputElement.value = this._filterInputElement.value;
this.resetFilter();
},

_switchSearchToFilter: function()
{
this._filterControlElement.removeStyleClass("hidden");
this._searchControlElement.addStyleClass("hidden");
this._filterInputElement.focus();
this._filterInputElement.select();
this._filterInputElement.value = this._searchInputElement.value;
this.resetSearch();
},

_updateFilterVisibility: function()
{
if (WebInspector.inspectorView.currentPanel().canFilter())
this._filterCheckboxContainer.removeStyleClass("hidden");
else
this._filterCheckboxContainer.addStyleClass("hidden");
},

_updateReplaceVisibility: function()
{
var panel = WebInspector.inspectorView.currentPanel();
if (panel && panel.canSearchAndReplace())
this._replaceElement.removeStyleClass("hidden");
else {
this._replaceElement.addStyleClass("hidden");
this._replaceCheckboxElement.checked = false;
this._updateSecondRowVisibility();
}
},

_onSearchFieldManualFocus: function(event)
{
WebInspector.setCurrentFocusElement(event.target);
},

_onKeyDown: function(event)
{

if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
event.consume(true);
this.cancelSearch();
WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement());
if (WebInspector.currentFocusElement() === event.target)
WebInspector.currentFocusElement().select();
return false;
}

if (isEnterKey(event)) {
if (event.target === this._searchInputElement)
this._performSearch(event.target.value, true, event.shiftKey);
else if (event.target === this._replaceInputElement)
this._replace();
}
},

_onNextButtonSearch: function(event)
{

this._performSearch(this._searchInputElement.value, true, false);
this._searchInputElement.focus();
},

_onPrevButtonSearch: function(event)
{
if (!this._searchNavigationPrevElement.hasStyleClass("enabled"))
return;

this._performSearch(this._searchInputElement.value, true, true);
this._searchInputElement.focus();
},


_performSearch: function(query, forceSearch, isBackwardSearch)
{
if (!query || !query.length) {
delete this._currentQuery;

for (var panelName in WebInspector.panels) {
var panel = WebInspector.panels[panelName];
var hadCurrentQuery = !!panel.currentQuery;
delete panel.currentQuery;
if (hadCurrentQuery)
panel.searchCanceled();
}
this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1);
return;
}

var currentPanel = WebInspector.inspectorView.currentPanel();
if (query === currentPanel.currentQuery && currentPanel.currentQuery === this._currentQuery) {


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

if (!forceSearch && query.length < 3 && !this._currentQuery)
return;

this._currentQuery = query;

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

_updateSecondRowVisibility: function()
{
if (!this._searchIsVisible)
return;
if (this._replaceCheckboxElement.checked) {
this._element.addStyleClass("toolbar-search-replace");
this._secondRowElement.removeStyleClass("hidden");
this._prevButtonElement.removeStyleClass("hidden");
this._findButtonElement.removeStyleClass("hidden");
this._replaceCheckboxElement.tabIndex = -1;
this._replaceInputElement.focus();
} else {
this._element.removeStyleClass("toolbar-search-replace");
this._secondRowElement.addStyleClass("hidden");
this._prevButtonElement.addStyleClass("hidden");
this._findButtonElement.addStyleClass("hidden");
this._replaceCheckboxElement.tabIndex = 0;
this._searchInputElement.focus();
}
WebInspector.inspectorView.setFooterElement(this._element);
},

_replace: function()
{
var currentPanel = WebInspector.inspectorView.currentPanel();
currentPanel.replaceSelectionWith(this._replaceInputElement.value);
var query = this._currentQuery;
delete this._currentQuery;
this._performSearch(query, true, false);
},

_replaceAll: function()
{
var currentPanel = WebInspector.inspectorView.currentPanel();
currentPanel.replaceAllWith(this._searchInputElement.value, this._replaceInputElement.value);
},

_filterCheckboxClick: function()
{
if (this._filterCheckboxElement.checked) { 
this._switchSearchToFilter();
this._performFilter(this._filterInputElement.value);
} else {
this._switchFilterToSearch();
this._performSearch(this._searchInputElement.value, false, false);
}
},


_performFilter: function(query)
{
WebInspector.inspectorView.currentPanel().performFilter(query);
},

_onFilterInput: function(event)
{
this._performFilter(event.target.value);
},

_onSearchInput: function(event)
{
this._performSearch(event.target.value, false, false);
},

resetFilter: function()
{
this._performFilter("");
}
}


WebInspector.searchController = null;






WebInspector.InspectElementModeController = function()
{
this.toggleSearchButton = new WebInspector.StatusBarButton(WebInspector.UIString("Select an element in the page to inspect it."), "node-search-status-bar-item");
this.toggleSearchButton.addEventListener("click", this.toggleSearch, this);
this._shortcut = WebInspector.InspectElementModeController.createShortcut();
}

WebInspector.InspectElementModeController.createShortcut = function()
{
return WebInspector.KeyboardShortcut.makeDescriptor("c", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift);
}

WebInspector.InspectElementModeController.prototype = {
enabled: function()
{
return this.toggleSearchButton.toggled;
},

disable: function()
{
if (this.enabled())
this.toggleSearch();
},

toggleSearch: function()
{
var enabled = !this.enabled();

function callback(error)
{
if (!error)
this.toggleSearchButton.toggled = enabled;
}
WebInspector.domAgent.setInspectModeEnabled(enabled, callback.bind(this));
},


handleShortcut: function(event)
{
if (WebInspector.KeyboardShortcut.makeKeyFromEvent(event) !== this._shortcut.key)
return false;
this.toggleSearch();
event.consume(true);
return true;
}
}






WebInspector.WorkerManager = function()
{
this._workerIdToWindow = {};
InspectorBackend.registerWorkerDispatcher(new WebInspector.WorkerDispatcher(this));
}

WebInspector.WorkerManager.isWorkerFrontend = function()
{
return !!WebInspector.queryParamsObject["dedicatedWorkerId"] ||
!!WebInspector.queryParamsObject["isSharedWorker"];
}

WebInspector.WorkerManager.isDedicatedWorkerFrontend = function()
{
return !!WebInspector.queryParamsObject["dedicatedWorkerId"];
}

WebInspector.WorkerManager.loaded = function()
{
var workerId = WebInspector.queryParamsObject["dedicatedWorkerId"];
if (workerId)
WebInspector.WorkerManager._initializeDedicatedWorkerFrontend(workerId);
else
WebInspector.workerManager = new WebInspector.WorkerManager();
}

WebInspector.WorkerManager.loadCompleted = function()
{


if (WebInspector.queryParamsObject["workerPaused"]) {
DebuggerAgent.pause();
RuntimeAgent.run(calculateTitle);
} else if (WebInspector.WorkerManager.isWorkerFrontend())
calculateTitle();

function calculateTitle()
{
WebInspector.WorkerManager._calculateWorkerInspectorTitle();
}

if (WebInspector.workerManager)
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, WebInspector.workerManager._mainFrameNavigated, WebInspector.workerManager);
}

WebInspector.WorkerManager._initializeDedicatedWorkerFrontend = function(workerId)
{
function receiveMessage(event)
{
var message = event.data;
InspectorBackend.dispatch(message);
}
window.addEventListener("message", receiveMessage, true);


InspectorBackend.sendMessageObjectToBackend = function(message)
{
window.opener.postMessage({workerId: workerId, command: "sendMessageToBackend", message: message}, "*");
}
}

WebInspector.WorkerManager._calculateWorkerInspectorTitle = function()
{
var expression = "location.href";
if (WebInspector.queryParamsObject["isSharedWorker"])
expression += " + (this.name ? ' (' + this.name + ')' : '')";
RuntimeAgent.evaluate.invoke({expression:expression, doNotPauseOnExceptionsAndMuteConsole:true, returnByValue: true}, evalCallback.bind(this));


function evalCallback(error, result, wasThrown)
{
if (error || wasThrown) {
console.error(error);
return;
}
InspectorFrontendHost.inspectedURLChanged(result.value);
}
}

WebInspector.WorkerManager.Events = {
WorkerAdded: "worker-added",
WorkerRemoved: "worker-removed",
WorkersCleared: "workers-cleared",
}

WebInspector.WorkerManager.prototype = {
_workerCreated: function(workerId, url, inspectorConnected)
{
if (inspectorConnected)
this._openInspectorWindow(workerId, true);
this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerAdded, {workerId: workerId, url: url, inspectorConnected: inspectorConnected});
},

_workerTerminated: function(workerId)
{
this.closeWorkerInspector(workerId);
this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerRemoved, workerId);
},

_sendMessageToWorkerInspector: function(workerId, message)
{
var workerInspectorWindow = this._workerIdToWindow[workerId];
if (workerInspectorWindow)
workerInspectorWindow.postMessage(message, "*");
},

openWorkerInspector: function(workerId)
{
var existingInspector = this._workerIdToWindow[workerId];
if (existingInspector) {
existingInspector.focus();
return;
}

this._openInspectorWindow(workerId, false);
WorkerAgent.connectToWorker(workerId);
},

_openInspectorWindow: function(workerId, workerIsPaused)
{
var search = window.location.search;
var hash = window.location.hash;
var url = window.location.href;

url = url.replace(hash, "");
url += (search ? "&dedicatedWorkerId=" : "?dedicatedWorkerId=") + workerId;
if (workerIsPaused)
url += "&workerPaused=true";
url = url.replace("docked=true&", "");
url += hash;
var width = WebInspector.settings.workerInspectorWidth.get();
var height = WebInspector.settings.workerInspectorHeight.get();

var workerInspectorWindow = window.open(url, undefined, "location=0,width=" + width + ",height=" + height);
workerInspectorWindow.addEventListener("resize", this._onWorkerInspectorResize.bind(this, workerInspectorWindow), false);
this._workerIdToWindow[workerId] = workerInspectorWindow;
workerInspectorWindow.addEventListener("beforeunload", this._workerInspectorClosing.bind(this, workerId), true);


window.addEventListener("beforeunload", this._pageInspectorClosing.bind(this), true);
WebInspector.notifications.addEventListener(WebInspector.Events.InspectorClosing, this._pageInspectorClosing, this);
},

closeWorkerInspector: function(workerId)
{
var workerInspectorWindow = this._workerIdToWindow[workerId];
if (workerInspectorWindow)
workerInspectorWindow.close();
},

_mainFrameNavigated: function(event)
{
for (var workerId in this._workerIdToWindow)
this.closeWorkerInspector(workerId);
this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkersCleared);
},

_pageInspectorClosing: function()
{
this._ignoreWorkerInspectorClosing = true;
for (var workerId in this._workerIdToWindow) {
this._workerIdToWindow[workerId].close();
WorkerAgent.disconnectFromWorker(parseInt(workerId, 10));
}
},

_onWorkerInspectorResize: function(workerInspectorWindow)
{
var doc = workerInspectorWindow.document;
WebInspector.settings.workerInspectorWidth.set(doc.width);
WebInspector.settings.workerInspectorHeight.set(doc.height);
},

_workerInspectorClosing: function(workerId, event)
{
if (event.target.location.href === "about:blank")
return;
if (this._ignoreWorkerInspectorClosing)
return;
delete this._workerIdToWindow[workerId];
WorkerAgent.disconnectFromWorker(workerId);
},

_disconnectedFromWorker: function()
{
var screen = new WebInspector.WorkerTerminatedScreen();
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, screen.hide, screen);
screen.showModal();
},

__proto__: WebInspector.Object.prototype
}


WebInspector.WorkerDispatcher = function(workerManager)
{
this._workerManager = workerManager;
window.addEventListener("message", this._receiveMessage.bind(this), true);
}

WebInspector.WorkerDispatcher.prototype = {
_receiveMessage: function(event)
{
var workerId = event.data["workerId"];
workerId = parseInt(workerId, 10);
var command = event.data.command;
var message = event.data.message;

if (command == "sendMessageToBackend")
WorkerAgent.sendMessageToWorker(workerId, message);
},

workerCreated: function(workerId, url, inspectorConnected)
{
this._workerManager._workerCreated(workerId, url, inspectorConnected);
},

workerTerminated: function(workerId)
{
this._workerManager._workerTerminated(workerId);
},

dispatchMessageFromWorker: function(workerId, message)
{
this._workerManager._sendMessageToWorkerInspector(workerId, message);
},

disconnectedFromWorker: function()
{
this._workerManager._disconnectedFromWorker();
}
}


WebInspector.WorkerTerminatedScreen = function()
{
WebInspector.HelpScreen.call(this, WebInspector.UIString("Inspected worker terminated"));
var p = this.contentElement.createChild("p");
p.addStyleClass("help-section");
p.textContent = WebInspector.UIString("Inspected worker has terminated. Once it restarts we will attach to it automatically.");
}

WebInspector.WorkerTerminatedScreen.prototype = {

willHide: function()
{
WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this.hide, this);
WebInspector.HelpScreen.prototype.willHide.call(this);
},

__proto__: WebInspector.HelpScreen.prototype
}






WebInspector.UserMetrics = function()
{
for (var actionName in WebInspector.UserMetrics._ActionCodes) {
var actionCode = WebInspector.UserMetrics._ActionCodes[actionName];
this[actionName] = new WebInspector.UserMetrics._Recorder(actionCode);
}

function settingChanged(trueCode, falseCode, event)
{
if (event.data)
InspectorFrontendHost.recordSettingChanged(trueCode);
else
InspectorFrontendHost.recordSettingChanged(falseCode);
}

WebInspector.settings.domWordWrap.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.ElementsDOMWrapOn, WebInspector.UserMetrics._SettingCodes.ElementsDOMWrapOff));
WebInspector.settings.monitoringXHREnabled.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.ConsoleMonitorXHROn, WebInspector.UserMetrics._SettingCodes.ConsoleMonitorXHROff));
WebInspector.settings.preserveConsoleLog.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.ConsolePreserveLogOn, WebInspector.UserMetrics._SettingCodes.ConsolePreserveLogOff));
WebInspector.settings.resourcesLargeRows.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.NetworkShowLargeRowsOn, WebInspector.UserMetrics._SettingCodes.NetworkShowLargeRowsOff));
}





WebInspector.UserMetrics._ActionCodes = {
WindowDocked: 1,
WindowUndocked: 2,
ScriptsBreakpointSet: 3,
TimelineStarted: 4,
ProfilesCPUProfileTaken: 5,
ProfilesHeapProfileTaken: 6,
AuditsStarted: 7,
ConsoleEvaluated: 8
}

WebInspector.UserMetrics._SettingCodes = {
ElementsDOMWrapOn: 1,
ElementsDOMWrapOff: 2,
ConsoleMonitorXHROn: 3,
ConsoleMonitorXHROff: 4,
ConsolePreserveLogOn: 5,
ConsolePreserveLogOff: 6,
NetworkShowLargeRowsOn: 7,
NetworkShowLargeRowsOff: 8
}

WebInspector.UserMetrics._PanelCodes = {
elements: 1,
resources: 2,
network: 3,
scripts: 4,
timeline: 5,
profiles: 6,
audits: 7,
console: 8
}

WebInspector.UserMetrics.UserAction = "UserAction";

WebInspector.UserMetrics.UserActionNames = {
ForcedElementState: "forcedElementState",
FileSaved: "fileSaved",
RevertRevision: "revertRevision",
ApplyOriginalContent: "applyOriginalContent",
TogglePrettyPrint: "togglePrettyPrint",
SetBreakpoint: "setBreakpoint",
OpenSourceLink: "openSourceLink",
NetworkSort: "networkSort",
NetworkRequestSelected: "networkRequestSelected",
NetworkRequestTabSelected: "networkRequestTabSelected",
HeapSnapshotFilterChanged: "heapSnapshotFilterChanged"
};

WebInspector.UserMetrics.prototype = {
panelShown: function(panelName)
{
InspectorFrontendHost.recordPanelShown(WebInspector.UserMetrics._PanelCodes[panelName] || 0);
}
}


WebInspector.UserMetrics._Recorder = function(actionCode)
{
this._actionCode = actionCode;
}

WebInspector.UserMetrics._Recorder.prototype = {
record: function()
{
InspectorFrontendHost.recordActionTaken(this._actionCode);
}
}

WebInspector.userMetrics = new WebInspector.UserMetrics();






WebInspector.RuntimeModel = function(resourceTreeModel)
{
resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._didLoadCachedResources, this);
this._frameIdToContextList = {};
}

WebInspector.RuntimeModel.Events = {
FrameExecutionContextListAdded: "FrameExecutionContextListAdded",
FrameExecutionContextListRemoved: "FrameExecutionContextListRemoved",
}

WebInspector.RuntimeModel.prototype = {

setCurrentExecutionContext: function(executionContext)
{
this._currentExecutionContext = executionContext;
},


currentExecutionContext: function()
{
return this._currentExecutionContext;
},


contextLists: function()
{
return Object.values(this._frameIdToContextList);
},


contextListByFrame: function(frame)
{
return this._frameIdToContextList[frame.id];
},

_frameAdded: function(event)
{
var frame = event.data;
var context = new WebInspector.FrameExecutionContextList(frame);
this._frameIdToContextList[frame.id] = context;
this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, context);
},

_frameNavigated: function(event)
{
var frame = event.data;
var context = this._frameIdToContextList[frame.id];
if (context)
context._frameNavigated(frame);
},

_frameDetached: function(event)
{
var frame = event.data;
var context = this._frameIdToContextList[frame.id];
if (!context)
return;
this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, context);
delete this._frameIdToContextList[frame.id];
},

_didLoadCachedResources: function()
{
InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeDispatcher(this));
RuntimeAgent.enable();
},

_executionContextCreated: function(context)
{
var contextList = this._frameIdToContextList[context.frameId];

if (!contextList)
return;
contextList._addExecutionContext(new WebInspector.ExecutionContext(context.id, context.name, context.isPageContext));
},


evaluate: function(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback)
{
if (WebInspector.debuggerModel.selectedCallFrame()) {
WebInspector.debuggerModel.evaluateOnSelectedCallFrame(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback);
return;
}

if (!expression) {

expression = "this";
}


function evalCallback(error, result, wasThrown)
{
if (error) {
console.error(error);
callback(null, false);
return;
}

if (returnByValue)
callback(null, !!wasThrown, wasThrown ? null : result);
else
callback(WebInspector.RemoteObject.fromPayload(result), !!wasThrown);
}
RuntimeAgent.evaluate(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, this._currentExecutionContext ? this._currentExecutionContext.id : undefined, returnByValue, generatePreview, evalCallback);
},


completionsForTextPrompt: function(proxyElement, wordRange, force, completionsReadyCallback)
{

var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, " =:[({;,!+-*/&|^<>", proxyElement, "backward");
var expressionString = expressionRange.toString();
var prefix = wordRange.toString();
this._completionsForExpression(expressionString, prefix, force, completionsReadyCallback);
},


_completionsForExpression: function(expressionString, prefix, force, completionsReadyCallback)
{
var lastIndex = expressionString.length - 1;

var dotNotation = (expressionString[lastIndex] === ".");
var bracketNotation = (expressionString[lastIndex] === "[");

if (dotNotation || bracketNotation)
expressionString = expressionString.substr(0, lastIndex);

if (expressionString && parseInt(expressionString, 10) == expressionString) {

completionsReadyCallback([]);
return;
}

if (!prefix && !expressionString && !force) {
completionsReadyCallback([]);
return;
}

if (!expressionString && WebInspector.debuggerModel.selectedCallFrame())
WebInspector.debuggerModel.getSelectedCallFrameVariables(receivedPropertyNames.bind(this));
else
this.evaluate(expressionString, "completion", true, true, false, false, evaluated.bind(this));

function evaluated(result, wasThrown)
{
if (!result || wasThrown) {
completionsReadyCallback([]);
return;
}

function getCompletions(primitiveType)
{
var object;
if (primitiveType === "string")
object = new String("");
else if (primitiveType === "number")
object = new Number(0);
else if (primitiveType === "boolean")
object = new Boolean(false);
else
object = this;

var 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) {
}
}
return resultSet;
}

if (result.type === "object" || result.type === "function")
result.callFunctionJSON(getCompletions, undefined, receivedPropertyNames.bind(this));
else if (result.type === "string" || result.type === "number" || result.type === "boolean")
this.evaluate("(" + getCompletions + ")(\"" + result.type + "\")", "completion", false, true, true, false, receivedPropertyNamesFromEval.bind(this));
}

function receivedPropertyNamesFromEval(notRelevant, wasThrown, result)
{
if (result && !wasThrown)
receivedPropertyNames.call(this, result.value);
else
completionsReadyCallback([]);
}

function receivedPropertyNames(propertyNames)
{
RuntimeAgent.releaseObjectGroup("completion");
if (!propertyNames) {
completionsReadyCallback([]);
return;
}
var includeCommandLineAPI = (!dotNotation && !bracketNotation);
if (includeCommandLineAPI) {
const commandLineAPI = ["dir", "dirxml", "keys", "values", "profile", "profileEnd", "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear",
"getEventListeners", "table", "$", "$$", "$x"];
for (var i = 0; i < commandLineAPI.length; ++i)
propertyNames[commandLineAPI[i]] = true;
}
this._reportCompletions(completionsReadyCallback, dotNotation, bracketNotation, expressionString, prefix, Object.keys(propertyNames));
}
},


_reportCompletions: function(completionsReadyCallback, dotNotation, bracketNotation, expressionString, prefix, properties) {
if (bracketNotation) {
if (prefix.length && prefix[0] === "'")
var quoteUsed = "'";
else
var quoteUsed = "\"";
}

var results = [];

if (!expressionString) {
const keywords = ["break", "case", "catch", "continue", "default", "delete", "do", "else", "finally", "for", "function", "if", "in",
"instanceof", "new", "return", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with"];
properties = properties.concat(keywords);
}

properties.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 (prefix.length && !property.startsWith(prefix))
continue;

results.push(property);
}
completionsReadyCallback(results);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.runtimeModel = null;


WebInspector.RuntimeDispatcher = function(runtimeModel)
{
this._runtimeModel = runtimeModel;
}

WebInspector.RuntimeDispatcher.prototype = {
executionContextCreated: function(context)
{
this._runtimeModel._executionContextCreated(context);
}
}


WebInspector.ExecutionContext = function(id, name, isPageContext)
{
this.id = id;
this.name = (isPageContext && !name) ? "<page context>" : name;
this.isMainWorldContext = isPageContext;
}


WebInspector.ExecutionContext.comparator = function(a, b)
{

if (a.isMainWorldContext)
return -1;
if (b.isMainWorldContext)
return +1;
return a.name.localeCompare(b.name);
}


WebInspector.FrameExecutionContextList = function(frame)
{
this._frame = frame;
this._executionContexts = [];
}

WebInspector.FrameExecutionContextList.EventTypes = {
ContextsUpdated: "ContextsUpdated",
ContextAdded: "ContextAdded"
}

WebInspector.FrameExecutionContextList.prototype =
{
_frameNavigated: function(frame)
{
this._frame = frame;
this._executionContexts = [];
this.dispatchEventToListeners(WebInspector.FrameExecutionContextList.EventTypes.ContextsUpdated, this);
},


_addExecutionContext: function(context)
{
var insertAt = insertionIndexForObjectInListSortedByFunction(context, this._executionContexts, WebInspector.ExecutionContext.comparator);
this._executionContexts.splice(insertAt, 0, context);
this.dispatchEventToListeners(WebInspector.FrameExecutionContextList.EventTypes.ContextAdded, this);
},

executionContexts: function()
{
return this._executionContexts;
},

mainWorldContext: function() 
{
return this._executionContexts[0];
},


contextBySecurityOrigin: function(securityOrigin)
{
for (var i = 0; i < this._executionContexts.length; ++i) {
var context = this._executionContexts[i];
if (!context.isMainWorldContext && context.name === securityOrigin)
return context; 
}
},

get frameId()
{
return this._frame.id;
},

get url()
{
return this._frame.url;
},

get displayName()
{
if (!this._frame.parentFrame)
return "<top frame>";
var name = this._frame.name || "";
var subtitle = new WebInspector.ParsedURL(this._frame.url).displayName;
if (subtitle) {
if (!name)
return subtitle;
return name + "( " + subtitle + " )";
}
return "<iframe>";
},

__proto__: WebInspector.Object.prototype
}






WebInspector.HandlerRegistry = function(setting)
{
WebInspector.Object.call(this);
this._handlers = {};
this._setting = setting;
this._activeHandler = this._setting.get();
WebInspector.ContextMenu.registerProvider(this);
}

WebInspector.HandlerRegistry.prototype = {
get handlerNames()
{
return Object.getOwnPropertyNames(this._handlers);
},

get activeHandler()
{
return this._activeHandler;
},

set activeHandler(value)
{
this._activeHandler = value;
this._setting.set(value);
},


dispatch: function(data)
{
return this.dispatchToHandler(this._activeHandler, data);
},


dispatchToHandler: function(name, data)
{
var handler = this._handlers[name];
var result = handler && handler(data);
return !!result;
},

registerHandler: function(name, handler)
{
this._handlers[name] = handler;
this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
},

unregisterHandler: function(name)
{
delete this._handlers[name];
this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
},


appendApplicableItems: function(event, contextMenu, target)
{
if (event.hasBeenHandledByHandlerRegistry)
return;
event.hasBeenHandledByHandlerRegistry = true;
this._appendContentProviderItems(contextMenu, target);
this._appendHrefItems(contextMenu, target);
},


_appendContentProviderItems: function(contextMenu, target)
{
if (!(target instanceof WebInspector.UISourceCode || target instanceof WebInspector.Resource || target instanceof WebInspector.NetworkRequest))
return;
var contentProvider =   (target);
if (!contentProvider.contentURL())
return;

contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, contentProvider.contentURL(), false));

for (var i = 1; i < this.handlerNames.length; ++i) {
var handler = this.handlerNames[i];
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open using %s" : "Open Using %s", handler),
this.dispatchToHandler.bind(this, handler, { url: contentProvider.contentURL() }));
}
contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, contentProvider.contentURL()));

if (!contentProvider.contentURL())
return;

var contentType = contentProvider.contentType();
if (contentType !== WebInspector.resourceTypes.Document &&
contentType !== WebInspector.resourceTypes.Stylesheet &&
contentType !== WebInspector.resourceTypes.Script)
return;

function doSave(forceSaveAs, content)
{
var url = contentProvider.contentURL();
WebInspector.fileManager.save(url, content, forceSaveAs);
WebInspector.fileManager.close(url);
}

function save(forceSaveAs)
{
if (contentProvider instanceof WebInspector.UISourceCode) {
var uiSourceCode =   (contentProvider);
if (uiSourceCode.isDirty()) {
doSave(forceSaveAs, uiSourceCode.workingCopy());
uiSourceCode.commitWorkingCopy(function() { });
return;
}
}
contentProvider.requestContent(doSave.bind(this, forceSaveAs));
}

contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString("Save"), save.bind(this, false));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Save as..." : "Save As..."), save.bind(this, true));
},


_appendHrefItems: function(contextMenu, target)
{
if (!(target instanceof Node))
return;
var targetNode =   (target);

var anchorElement = targetNode.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || targetNode.enclosingNodeOrSelfWithClass("webkit-html-external-link");
if (!anchorElement)
return;

var resourceURL = anchorElement.href;
if (!resourceURL)
return;


contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, resourceURL, false));
if (WebInspector.resourceForURL(resourceURL))
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in Resources panel" : "Open Link in Resources Panel"), WebInspector.openResource.bind(null, resourceURL, true));
contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, resourceURL));
},

__proto__: WebInspector.Object.prototype
}


WebInspector.HandlerRegistry.EventTypes = {
HandlersUpdated: "HandlersUpdated"
}


WebInspector.HandlerSelector = function(handlerRegistry)
{
this._handlerRegistry = handlerRegistry;
this.element = document.createElement("select");
this.element.addEventListener("change", this._onChange.bind(this), false);
this._update();
this._handlerRegistry.addEventListener(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated, this._update.bind(this));
}

WebInspector.HandlerSelector.prototype =
{
_update: function()
{
this.element.removeChildren();
var names = this._handlerRegistry.handlerNames;
var activeHandler = this._handlerRegistry.activeHandler;

for (var i = 0; i < names.length; ++i) {
var option = document.createElement("option");
option.textContent = names[i];
option.selected = activeHandler === names[i];
this.element.appendChild(option);
}
this.element.disabled = names.length <= 1;
},

_onChange: function(event)
{
var value = event.target.value;
this._handlerRegistry.activeHandler = value;
}
}



WebInspector.openAnchorLocationRegistry = null;






WebInspector.SnippetStorage = function(settingPrefix, namePrefix)
{
this._snippets = {};

this._lastSnippetIdentifierSetting = WebInspector.settings.createSetting(settingPrefix + "Snippets_lastIdentifier", 0);
this._snippetsSetting = WebInspector.settings.createSetting(settingPrefix + "Snippets", []);
this._namePrefix = namePrefix;

this._loadSettings();
}

WebInspector.SnippetStorage.prototype = {
get namePrefix()
{
return this._namePrefix;
},

_saveSettings: function()
{
var savedSnippets = [];
for (var id in this._snippets)
savedSnippets.push(this._snippets[id].serializeToObject());
this._snippetsSetting.set(savedSnippets);
},


snippets: function()
{
var result = [];
for (var id in this._snippets)
result.push(this._snippets[id]);
return result;
},


snippetForId: function(id)
{
return this._snippets[id];
},

_loadSettings: function()
{
var savedSnippets = this._snippetsSetting.get();
for (var i = 0; i < savedSnippets.length; ++i)
this._snippetAdded(WebInspector.Snippet.fromObject(this, savedSnippets[i]));
},


deleteSnippet: function(snippet)
{
delete this._snippets[snippet.id];
this._saveSettings();
},


createSnippet: function()
{
var nextId = this._lastSnippetIdentifierSetting.get() + 1;
var snippetId = String(nextId);
this._lastSnippetIdentifierSetting.set(nextId);
var snippet = new WebInspector.Snippet(this, snippetId);
this._snippetAdded(snippet);
this._saveSettings();
return snippet;
},


_snippetAdded: function(snippet)
{
this._snippets[snippet.id] = snippet;
},

reset: function()
{
this._lastSnippetIdentifierSetting.set(0);
this._snippetsSetting.set([]);
this._snippets = {};
},

__proto__: WebInspector.Object.prototype
}


WebInspector.Snippet = function(storage, id, name, content)
{
this._storage = storage;
this._id = id;
this._name = name || storage.namePrefix + id;
this._content = content || "";
}


WebInspector.Snippet.fromObject = function(storage, serializedSnippet)
{
return new WebInspector.Snippet(storage, serializedSnippet.id, serializedSnippet.name, serializedSnippet.content);
}

WebInspector.Snippet.prototype = {

get id()
{
return this._id;
},


get name()
{
return this._name;
},

set name(name)
{
if (this._name === name)
return;

this._name = name;
this._storage._saveSettings();
},


get content()
{
return this._content;
},

set content(content)
{
if (this._content === content)
return;

this._content = content;
this._storage._saveSettings();
},


serializeToObject: function()
{
var serializedSnippet = {};
serializedSnippet.id = this.id;
serializedSnippet.name = this.name;
serializedSnippet.content = this.content;
return serializedSnippet;
},

__proto__: WebInspector.Object.prototype
}






WebInspector.ScriptSnippetModel = function(workspace)
{
this._workspace = workspace;

this._uiSourceCodeForScriptId = {};
this._scriptForUISourceCode = new Map();

this._uiSourceCodeForSnippetId = {};
this._snippetIdForUISourceCode = new Map();

this._snippetStorage = new WebInspector.SnippetStorage("script", "Script snippet #");
this._lastSnippetEvaluationIndexSetting = WebInspector.settings.createSetting("lastSnippetEvaluationIndex", 0);
this._snippetScriptMapping = new WebInspector.SnippetScriptMapping(this);
this._workspaceProvider = new WebInspector.SimpleWorkspaceProvider(this._workspace, WebInspector.projectTypes.Snippets);
this.reset();
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
}

WebInspector.ScriptSnippetModel.prototype = {

get scriptMapping()
{
return this._snippetScriptMapping;
},

_loadSnippets: function()
{
var snippets = this._snippetStorage.snippets();
for (var i = 0; i < snippets.length; ++i)
this._addScriptSnippet(snippets[i]);
},


createScriptSnippet: function()
{
var snippet = this._snippetStorage.createSnippet();
return this._addScriptSnippet(snippet);
},


_addScriptSnippet: function(snippet)
{
var uiSourceCode = this._workspaceProvider.addFileByName("", snippet.name, new WebInspector.SnippetContentProvider(snippet), true);
var scriptFile = new WebInspector.SnippetScriptFile(this, uiSourceCode);
uiSourceCode.setScriptFile(scriptFile);
this._snippetIdForUISourceCode.put(uiSourceCode, snippet.id);
uiSourceCode.setSourceMapping(this._snippetScriptMapping);
this._uiSourceCodeForSnippetId[snippet.id] = uiSourceCode;
return uiSourceCode;
},


deleteScriptSnippet: function(uiSourceCode)
{
var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode);
var snippet = this._snippetStorage.snippetForId(snippetId);
this._snippetStorage.deleteSnippet(snippet);
this._removeBreakpoints(uiSourceCode);
this._releaseSnippetScript(uiSourceCode);
delete this._uiSourceCodeForSnippetId[snippet.id];
this._snippetIdForUISourceCode.remove(uiSourceCode);
this._workspaceProvider.removeFileByName("", snippet.name);
},


renameScriptSnippet: function(uiSourceCode, newName)
{
var breakpointLocations = this._removeBreakpoints(uiSourceCode);
var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode);
var snippet = this._snippetStorage.snippetForId(snippetId);
if (!snippet || !newName || snippet.name === newName)
return;
snippet.name = newName;
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
},


_setScriptSnippetContent: function(uiSourceCode, newContent)
{
var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode);
var snippet = this._snippetStorage.snippetForId(snippetId);
snippet.content = newContent;
},


_scriptSnippetEdited: function(uiSourceCode)
{
var script = this._scriptForUISourceCode.get(uiSourceCode);
if (!script)
return;

var breakpointLocations = this._removeBreakpoints(uiSourceCode);
var scriptUISourceCode = this._releaseSnippetScript(uiSourceCode);
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
if (scriptUISourceCode)
this._restoreBreakpoints(scriptUISourceCode, breakpointLocations);
},


_nextEvaluationIndex: function(snippetId)
{
var evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1;
this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);
return evaluationIndex;
},


evaluateScriptSnippet: function(uiSourceCode)
{
var breakpointLocations = this._removeBreakpoints(uiSourceCode);
this._releaseSnippetScript(uiSourceCode);
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode);
var evaluationIndex = this._nextEvaluationIndex(snippetId);
uiSourceCode._evaluationIndex = evaluationIndex;
var evaluationUrl = this._evaluationSourceURL(uiSourceCode);

var expression = uiSourceCode.workingCopy();





if (WebInspector.debuggerModel.selectedCallFrame()) {
expression = uiSourceCode.workingCopy() + "\n//@ sourceURL=" + evaluationUrl + "\n";
WebInspector.evaluateInConsole(expression, true);
return;
}

WebInspector.showConsole();
DebuggerAgent.compileScript(expression, evaluationUrl, compileCallback.bind(this));


function compileCallback(error, scriptId, syntaxErrorMessage)
{
if (!uiSourceCode || uiSourceCode._evaluationIndex !== evaluationIndex)
return;

if (error) {
console.error(error);
return;
}

if (!scriptId) {
var consoleMessage = WebInspector.ConsoleMessage.create(
WebInspector.ConsoleMessage.MessageSource.JS,
WebInspector.ConsoleMessage.MessageLevel.Error,
syntaxErrorMessage || "");
WebInspector.console.addMessage(consoleMessage);
return;
}

var breakpointLocations = this._removeBreakpoints(uiSourceCode);
this._restoreBreakpoints(uiSourceCode, breakpointLocations);

this._runScript(scriptId);
}
},


_runScript: function(scriptId)
{
var currentExecutionContext = WebInspector.runtimeModel.currentExecutionContext();
DebuggerAgent.runScript(scriptId, currentExecutionContext ? currentExecutionContext.id : undefined, "console", false, runCallback.bind(this));


function runCallback(error, result, wasThrown)
{
if (error) {
console.error(error);
return;
}

this._printRunScriptResult(result, wasThrown);
}
},


_printRunScriptResult: function(result, wasThrown)
{
var level = (wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
var message = WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.JS, level, "", undefined, undefined, undefined, undefined, [result]);
WebInspector.console.addMessage(message)
},


_rawLocationToUILocation: function(rawLocation)
{
var uiSourceCode = this._uiSourceCodeForScriptId[rawLocation.scriptId];
return new WebInspector.UILocation(uiSourceCode, rawLocation.lineNumber, rawLocation.columnNumber || 0);
},


_uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var script = this._scriptForUISourceCode.get(uiSourceCode);
if (!script)
return null;

return WebInspector.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
},


_addScript: function(script)
{
var snippetId = this._snippetIdForSourceURL(script.sourceURL);
if (!snippetId)
return;
var uiSourceCode = this._uiSourceCodeForSnippetId[snippetId];

if (!uiSourceCode || this._evaluationSourceURL(uiSourceCode) !== script.sourceURL)
return;

console.assert(!this._scriptForUISourceCode.get(uiSourceCode));
this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
this._scriptForUISourceCode.put(uiSourceCode, script);
uiSourceCode.scriptFile().setHasDivergedFromVM(false);
script.pushSourceMapping(this._snippetScriptMapping);
},


_removeBreakpoints: function(uiSourceCode)
{
var breakpointLocations = WebInspector.breakpointManager.breakpointLocationsForUISourceCode(uiSourceCode);
for (var i = 0; i < breakpointLocations.length; ++i)
breakpointLocations[i].breakpoint.remove();
return breakpointLocations;
},


_restoreBreakpoints: function(uiSourceCode, breakpointLocations)
{
for (var i = 0; i < breakpointLocations.length; ++i) {
var uiLocation = breakpointLocations[i].uiLocation;
var breakpoint = breakpointLocations[i].breakpoint;
WebInspector.breakpointManager.setBreakpoint(uiSourceCode, uiLocation.lineNumber, breakpoint.condition(), breakpoint.enabled());
}
},


_releaseSnippetScript: function(uiSourceCode)
{
var script = this._scriptForUISourceCode.get(uiSourceCode);
if (!script)
return null;

uiSourceCode.scriptFile().setIsDivergingFromVM(true);
uiSourceCode.scriptFile().setHasDivergedFromVM(true);
delete this._uiSourceCodeForScriptId[script.scriptId];
this._scriptForUISourceCode.remove(uiSourceCode);
delete uiSourceCode._evaluationIndex;
script.popSourceMapping(this._snippetScriptMapping);
uiSourceCode.scriptFile().setIsDivergingFromVM(false);
return script.rawLocationToUILocation(0, 0).uiSourceCode;
},

_debuggerReset: function()
{
for (var snippetId in this._uiSourceCodeForSnippetId) {
var uiSourceCode = this._uiSourceCodeForSnippetId[snippetId];
this._releaseSnippetScript(uiSourceCode);
}
},


_evaluationSourceURL: function(uiSourceCode)
{
var evaluationSuffix = "_" + uiSourceCode._evaluationIndex;
var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode);
return WebInspector.Script.snippetSourceURLPrefix + snippetId + evaluationSuffix;
},


_snippetIdForSourceURL: function(sourceURL)
{
var snippetPrefix = WebInspector.Script.snippetSourceURLPrefix;
if (!sourceURL.startsWith(snippetPrefix))
return null;
var splittedURL = sourceURL.substring(snippetPrefix.length).split("_");
var snippetId = splittedURL[0];
return snippetId;
},

reset: function()
{

this._uiSourceCodeForScriptId = {};
this._scriptForUISourceCode = new Map();

this._uiSourceCodeForSnippetId = {};
this._snippetIdForUISourceCode = new Map();
this._workspaceProvider.reset();
this._loadSnippets();
},

__proto__: WebInspector.Object.prototype
}


WebInspector.SnippetScriptFile = function(scriptSnippetModel, uiSourceCode)
{
WebInspector.ScriptFile.call(this);
this._scriptSnippetModel = scriptSnippetModel;
this._uiSourceCode = uiSourceCode;
this._hasDivergedFromVM = true;
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
}

WebInspector.SnippetScriptFile.prototype = {

hasDivergedFromVM: function()
{
return this._hasDivergedFromVM;
},


setHasDivergedFromVM: function(hasDivergedFromVM)
{
this._hasDivergedFromVM = hasDivergedFromVM;
},


isDivergingFromVM: function()
{
return this._isDivergingFromVM;
},

checkMapping: function()
{
},


isMergingToVM: function()
{
return false;
},


setIsDivergingFromVM: function(isDivergingFromVM)
{
this._isDivergingFromVM = isDivergingFromVM;
},

_workingCopyCommitted: function()
{
this._scriptSnippetModel._setScriptSnippetContent(this._uiSourceCode, this._uiSourceCode.workingCopy());
},

_workingCopyChanged: function()
{
this._scriptSnippetModel._scriptSnippetEdited(this._uiSourceCode);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.SnippetScriptMapping = function(scriptSnippetModel)
{
this._scriptSnippetModel = scriptSnippetModel;
}

WebInspector.SnippetScriptMapping.prototype = {

rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation =  (rawLocation);
return this._scriptSnippetModel._rawLocationToUILocation(debuggerModelLocation);
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
return this._scriptSnippetModel._uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
},


isIdentity: function()
{
return true;
},


snippetIdForSourceURL: function(sourceURL)
{
return this._scriptSnippetModel._snippetIdForSourceURL(sourceURL);
},


addScript: function(script)
{
this._scriptSnippetModel._addScript(script);
}
}


WebInspector.SnippetContentProvider = function(snippet)
{
WebInspector.StaticContentProvider.call(this, WebInspector.resourceTypes.Script, snippet.content);
}

WebInspector.SnippetContentProvider.prototype = {
__proto__: WebInspector.StaticContentProvider.prototype
}


WebInspector.scriptSnippetModel = null;






WebInspector.Progress = function()
{
}

WebInspector.Progress.prototype = {

setTotalWork: function(totalWork) { },


setTitle: function(title) { },


setWorked: function(worked, title) { },


worked: function(worked) { },

done: function() { },


isCanceled: function() { return false; }
}


WebInspector.CompositeProgress = function(parent)
{
this._parent = parent;
this._children = [];
this._childrenDone = 0;
this._parent.setTotalWork(1);
this._parent.setWorked(0);
}

WebInspector.CompositeProgress.prototype = {
_childDone: function()
{
if (++this._childrenDone === this._children.length)
this._parent.done();
},


createSubProgress: function(weight)
{
var child = new WebInspector.SubProgress(this, weight);
this._children.push(child);
return child;
},

_update: function()
{
var totalWeights = 0;
var done = 0;

for (var i = 0; i < this._children.length; ++i) {
var child = this._children[i];
if (child._totalWork)
done += child._weight * child._worked / child._totalWork;
totalWeights += child._weight;
}
this._parent.setWorked(done / totalWeights);
}
}


WebInspector.SubProgress = function(composite, weight)
{
this._composite = composite;
this._weight = weight || 1;
this._worked = 0;
}

WebInspector.SubProgress.prototype = {

isCanceled: function()
{
return this._composite._parent.isCanceled();
},


setTitle: function(title)
{
this._composite._parent.setTitle(title);
},

done: function()
{
this.setWorked(this._totalWork);
this._composite._childDone();
},


setTotalWork: function(totalWork)
{
this._totalWork = totalWork;
this._composite._update();
},


setWorked: function(worked, title)
{
this._worked = worked;
if (typeof title !== "undefined")
this.setTitle(title);
this._composite._update();
},


worked: function(worked)
{
this.setWorked(this._worked + (worked || 1));
}
}






WebInspector.ProgressIndicator = function()
{
this.element = document.createElement("div");
this.element.className = "progress-bar-container";
this._labelElement = this.element.createChild("span");
this._progressElement = this.element.createChild("progress");
this._stopButton = new WebInspector.StatusBarButton(WebInspector.UIString("Cancel"), "progress-bar-stop-button");
this._stopButton.addEventListener("click", this.cancel, this);
this.element.appendChild(this._stopButton.element);
this._isCanceled = false;
this._worked = 0;
}

WebInspector.ProgressIndicator.Events = {
Done: "Done"
}

WebInspector.ProgressIndicator.prototype = {

show: function(parent)
{
parent.appendChild(this.element);
},

hide: function()
{
var parent = this.element.parentElement;
if (parent)
parent.removeChild(this.element);
},

done: function()
{
if (this._isDone)
return;
this._isDone = true;
this.hide();
this.dispatchEventToListeners(WebInspector.ProgressIndicator.Events.Done);
},

cancel: function()
{
this._isCanceled = true;
},

isCanceled: function()
{
return this._isCanceled;
},


setTitle: function(title)
{
this._labelElement.textContent = title;
},


setTotalWork: function(totalWork)
{
this._progressElement.max = totalWork;
},


setWorked: function(worked, title)
{
this._worked = worked;
this._progressElement.value = worked;
if (title)
this.setTitle(title);
},


worked: function(worked)
{
this.setWorked(this._worked + (worked || 1));
},

__proto__: WebInspector.Object.prototype
}






WebInspector.StylesSourceMapping = function(cssModel, workspace)
{
this._cssModel = cssModel;
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset, this);
this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameCreatedOrNavigated, this._mainFrameCreatedOrNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
this._initialize();
}

WebInspector.StylesSourceMapping.prototype = {

rawLocationToUILocation: function(rawLocation)
{
var location =   (rawLocation);
var uiSourceCode = this._workspace.uiSourceCodeForURL(location.url);
return new WebInspector.UILocation(uiSourceCode, location.lineNumber, 0);
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
return new WebInspector.CSSLocation(uiSourceCode.url || "", lineNumber);
},


isIdentity: function()
{
return true;
},

_resourceAdded: function(event)
{
var resource =   (event.data);
if (resource.contentType() !== WebInspector.resourceTypes.Stylesheet)
return;
if (!resource.url)
return;
var uiSourceCode = this._workspace.uiSourceCodeForURL(resource.url);
if (!uiSourceCode)
return;
this._bindUISourceCode(uiSourceCode);
},

_uiSourceCodeAddedToWorkspace: function(event)
{
var uiSourceCode =   (event.data);
if (uiSourceCode.contentType() !== WebInspector.resourceTypes.Stylesheet)
return;
if (!uiSourceCode.url || !WebInspector.resourceForURL(uiSourceCode.url))
return;
this._bindUISourceCode(uiSourceCode);
},

_bindUISourceCode: function(uiSourceCode)
{
if (this._mappedURLs[uiSourceCode.url])
return;
this._mappedURLs[uiSourceCode.url] = true;
uiSourceCode.setSourceMapping(this);
var styleFile = new WebInspector.StyleFile(uiSourceCode);
uiSourceCode.setStyleFile(styleFile);
this._cssModel.setSourceMapping(uiSourceCode.url, this);
},

_projectWillReset: function(event)
{
var project = event.data;
var uiSourceCodes = project.uiSourceCodes();
for (var i = 0; i < uiSourceCodes; ++i)
delete this._mappedURLs[uiSourceCodes[i].url];
},

_initialize: function()
{

this._mappedURLs = {};
},


_mainFrameCreatedOrNavigated: function(event)
{
for (var mappedURL in this._mappedURLs) {
var uiSourceCode = this._workspace.uiSourceCodeForURL(mappedURL);
if (!uiSourceCode)
continue;
uiSourceCode.styleFile().dispose();
uiSourceCode.setStyleFile(null);
uiSourceCode.setSourceMapping(null);
}
this._initialize();
}
}


WebInspector.StyleFile = function(uiSourceCode)
{
this._uiSourceCode = uiSourceCode;
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
}

WebInspector.StyleFile.updateTimeout = 200;

WebInspector.StyleFile.prototype = {
_workingCopyCommitted: function(event)
{
if (this._isAddingRevision)
return;

this._commitIncrementalEdit(true);
},

_workingCopyChanged: function(event)
{
if (this._isAddingRevision)
return;


if (WebInspector.StyleFile.updateTimeout >= 0) {
this._incrementalUpdateTimer = setTimeout(this._commitIncrementalEdit.bind(this, false), WebInspector.StyleFile.updateTimeout)
} else
this._commitIncrementalEdit(false);
},


_commitIncrementalEdit: function(majorChange)
{
this._clearIncrementalUpdateTimer();
WebInspector.styleContentBinding.setStyleContent(this._uiSourceCode, this._uiSourceCode.workingCopy(), majorChange, this._styleContentSet.bind(this));
},


_styleContentSet: function(error)
{
if (error)
WebInspector.showErrorMessage(error);
},

_clearIncrementalUpdateTimer: function()
{
if (!this._incrementalUpdateTimer)
return;
clearTimeout(this._incrementalUpdateTimer);
delete this._incrementalUpdateTimer;
},


addRevision: function(content)
{
this._isAddingRevision = true;
this._uiSourceCode.addRevision(content);
delete this._isAddingRevision;
},

dispose: function()
{
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
}
}


WebInspector.StyleContentBinding = function(cssModel, workspace)
{
this._cssModel = cssModel;
this._workspace = workspace;
this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetChanged, this);
}

WebInspector.StyleContentBinding.prototype = {

setStyleContent: function(uiSourceCode, content, majorChange, userCallback)
{
var resource = WebInspector.resourceForURL(uiSourceCode.url);
if (!resource) {
userCallback("No resource found: " + uiSourceCode.url);
return;
}

var styleSheetId = this._cssModel.resourceBinding().styleSheetIdForResource(resource);
if (!styleSheetId) {
userCallback("No stylesheet found: " + resource.frameId + ":" + resource.url);
return;
}

this._isSettingContent = true;
function callback(error)
{
userCallback(error);
delete this._isSettingContent;
}
this._cssModel.setStyleSheetText(styleSheetId, content, majorChange, callback.bind(this));
},


_styleSheetChanged: function(event)
{
if (this._isSettingContent)
return;

if (!event.data.majorChange)
return;


function callback(error, content)
{
if (!error)
this._innerStyleSheetChanged(event.data.styleSheetId, content);
}
CSSAgent.getStyleSheetText(event.data.styleSheetId, callback.bind(this));
},


_innerStyleSheetChanged: function(styleSheetId, content)
{
var styleSheetURL = this._cssModel.resourceBinding().resourceURLForStyleSheetId(styleSheetId);
if (typeof styleSheetURL !== "string")
return;

var uiSourceCode = this._workspace.uiSourceCodeForURL(styleSheetURL)
if (!uiSourceCode)
return;

if (uiSourceCode.styleFile())
uiSourceCode.styleFile().addRevision(content);
}
}


WebInspector.styleContentBinding = null;






WebInspector.NetworkUISourceCodeProvider = function(networkWorkspaceProvider, workspace)
{
this._networkWorkspaceProvider = networkWorkspaceProvider;
this._workspace = workspace;
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);

this._processedURLs = {};
this._lastDynamicAnonymousScriptIndexForURL = {};
}

WebInspector.NetworkUISourceCodeProvider.prototype = {
_populate: function()
{
function populateFrame(frame)
{
for (var i = 0; i < frame.childFrames.length; ++i)
populateFrame.call(this, frame.childFrames[i]);

var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this._resourceAdded({data:resources[i]});
}

populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
},


_parsedScriptSource: function(event)
{
var script =   (event.data);
if (!script.sourceURL || script.isInlineScript() || script.isSnippet())
return;
var isDynamicAnonymousScript;




if (!script.hasSourceURL && !script.isContentScript) {
var requestURL = script.sourceURL.replace(/#.*/, "");
if (WebInspector.resourceForURL(requestURL) || WebInspector.networkLog.requestForURL(requestURL))
return;
}

if (script.isContentScript && !script.hasSourceURL) {
var parsedURL = new WebInspector.ParsedURL(script.sourceURL);
if (!parsedURL.host)
return;
}
this._addFile(script.sourceURL, script, script.isContentScript);
},


_resourceAdded: function(event)
{
var resource =   (event.data);
this._addFile(resource.url, resource);
},


_mainFrameNavigated: function(event)
{
this._reset();
},


_addFile: function(url, contentProvider, isContentScript)
{
if (this._workspace.hasMappingForURL(url))
return;

var type = contentProvider.contentType();
if (type !== WebInspector.resourceTypes.Stylesheet && type !== WebInspector.resourceTypes.Document && type !== WebInspector.resourceTypes.Script)
return;
if (this._processedURLs[url])
return;
this._processedURLs[url] = true;
var isEditable = type !== WebInspector.resourceTypes.Document;
this._networkWorkspaceProvider.addFileForURL(url, contentProvider, isEditable, isContentScript);
},

_reset: function()
{
this._processedURLs = {};
this._lastDynamicAnonymousScriptIndexForURL = {};
this._networkWorkspaceProvider.reset();
this._populate();
}
}


WebInspector.networkWorkspaceProvider = null;






WebInspector.ElementsPanelDescriptor = function()
{
WebInspector.PanelDescriptor.call(this, "elements", WebInspector.UIString("Elements"), "ElementsPanel", "ElementsPanel.js");
WebInspector.ContextMenu.registerProvider(this);
}

WebInspector.ElementsPanelDescriptor.prototype = {

appendApplicableItems: function(event, contextMenu, target)
{
if (!(target instanceof WebInspector.RemoteObject))
return;
var remoteObject =   (target);
if (remoteObject.subtype !== "node")
return;
this.panel().appendApplicableItems(event, contextMenu, target);
},

registerShortcuts: function()
{
var elementsSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));

var navigate = WebInspector.ElementsPanelDescriptor.ShortcutKeys.NavigateUp.concat(WebInspector.ElementsPanelDescriptor.ShortcutKeys.NavigateDown);
elementsSection.addRelatedKeys(navigate, WebInspector.UIString("Navigate elements"));

var expandCollapse = WebInspector.ElementsPanelDescriptor.ShortcutKeys.Expand.concat(WebInspector.ElementsPanelDescriptor.ShortcutKeys.Collapse);
elementsSection.addRelatedKeys(expandCollapse, WebInspector.UIString("Expand/collapse"));

elementsSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.EditAttribute, WebInspector.UIString("Edit attribute"));
elementsSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.HideElement, WebInspector.UIString("Hide element"));
elementsSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.ToggleEditAsHTML, WebInspector.UIString("Toggle edit as HTML"));

var stylesPaneSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Styles Pane"));

var nextPreviousProperty = WebInspector.ElementsPanelDescriptor.ShortcutKeys.NextProperty.concat(WebInspector.ElementsPanelDescriptor.ShortcutKeys.PreviousProperty);
stylesPaneSection.addRelatedKeys(nextPreviousProperty, WebInspector.UIString("Next/previous property"));

stylesPaneSection.addRelatedKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.IncrementValue, WebInspector.UIString("Increment value"));
stylesPaneSection.addRelatedKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.DecrementValue, WebInspector.UIString("Decrement value"));

stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.IncrementBy10, WebInspector.UIString("Increment by %f", 10));
stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.DecrementBy10, WebInspector.UIString("Decrement by %f", 10));

stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.IncrementBy100, WebInspector.UIString("Increment by %f", 100));
stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.DecrementBy100, WebInspector.UIString("Decrement by %f", 100));

stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.IncrementBy01, WebInspector.UIString("Increment by %f", 0.1));
stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.DecrementBy01, WebInspector.UIString("Decrement by %f", 0.1));
},

__proto__: WebInspector.PanelDescriptor.prototype
}

WebInspector.ElementsPanelDescriptor.ShortcutKeys = {
NavigateUp: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up)
],

NavigateDown: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down)
],

Expand: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Right)
],

Collapse: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Left)
],

EditAttribute: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Enter)
],

HideElement: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.H)
],

ToggleEditAsHTML: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F2)
],

NextProperty: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Tab)
],

PreviousProperty: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Tab, WebInspector.KeyboardShortcut.Modifiers.Shift)
],

IncrementValue: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up)
],

DecrementValue: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down)
],

IncrementBy10: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp),
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up, WebInspector.KeyboardShortcut.Modifiers.Shift)
],

DecrementBy10: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown),
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down, WebInspector.KeyboardShortcut.Modifiers.Shift)
],

IncrementBy100: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp, WebInspector.KeyboardShortcut.Modifiers.Shift)
],

DecrementBy100: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown, WebInspector.KeyboardShortcut.Modifiers.Shift)
],

IncrementBy01: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp, WebInspector.KeyboardShortcut.Modifiers.Alt)
],

DecrementBy01: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown, WebInspector.KeyboardShortcut.Modifiers.Alt)
]
};







WebInspector.NetworkPanelDescriptor = function()
{
WebInspector.PanelDescriptor.call(this, "network", WebInspector.UIString("Network"), "NetworkPanel", "NetworkPanel.js");
WebInspector.ContextMenu.registerProvider(this);
}

WebInspector.NetworkPanelDescriptor.prototype = {

appendApplicableItems: function(event, contextMenu, target)
{
if (!(target instanceof WebInspector.NetworkRequest))
return;
this.panel().appendApplicableItems(event, contextMenu, target);
},

__proto__: WebInspector.PanelDescriptor.prototype
}






WebInspector.ProfilesPanelDescriptor = function()
{
WebInspector.PanelDescriptor.call(this, "profiles", WebInspector.UIString("Profiles"), "ProfilesPanel", "ProfilesPanel.js");
}

WebInspector.ProfilesPanelDescriptor.prototype = {
registerShortcuts: function()
{
var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Profiles Panel"));
section.addAlternateKeys(WebInspector.ProfilesPanelDescriptor.ShortcutKeys.StartStopRecording, WebInspector.UIString("Start/stop recording"));
},

__proto__: WebInspector.PanelDescriptor.prototype
}

WebInspector.ProfilesPanelDescriptor.ShortcutKeys = {
StartStopRecording: [
WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
]
}

WebInspector.ProfilesPanelDescriptor.ProfileURLRegExp = /webkit-profile:\/\/(.+)\/(.+)/;

WebInspector.ProfilesPanelDescriptor.UserInitiatedProfileName = "org.webkit.profiles.user-initiated";


WebInspector.ProfilesPanelDescriptor.isUserInitiatedProfile = function(title)
{
return title.startsWith(WebInspector.ProfilesPanelDescriptor.UserInitiatedProfileName);
}


WebInspector.ProfilesPanelDescriptor.userInitiatedProfileIndex = function(title)
{
if (!WebInspector.ProfilesPanelDescriptor.isUserInitiatedProfile(title))
throw "Not user-initiated profile title.";
var suffix = title.substring(WebInspector.ProfilesPanelDescriptor.UserInitiatedProfileName.length + 1);
return parseInt(suffix, 10);
}


WebInspector.ProfilesPanelDescriptor.resolveProfileTitle = function(title)
{
if (!WebInspector.ProfilesPanelDescriptor.isUserInitiatedProfile(title))
return title;
return WebInspector.UIString("Profile %d", WebInspector.ProfilesPanelDescriptor.userInitiatedProfileIndex(title));
}


WebInspector.ProfilesPanelDescriptor._openCPUProfile = function(event)
{
event.preventDefault();
var panel = WebInspector.showPanel("profiles");
var link =   (event.target);
var view =   (panel.showProfile("CPU", link.profileUID));
if (!view)
return;
if (typeof link.timeLeft === "number" && typeof link.timeRight === "number")
view.selectRange(link.timeLeft, link.timeRight);
}


WebInspector.ProfilesPanelDescriptor.linkifyCPUProfile = function(uid, linkText, timeLeft, timeRight, tooltipText)
{
var link = document.createElement("a");
link.innerText = linkText;
link.href = WebInspector.UIString("show CPU profile");
link.target = "_blank";
if (tooltipText)
link.title = tooltipText;
link.timeLeft = timeLeft;
link.timeRight = timeRight;
link.profileUID = uid;
link.addEventListener("click", WebInspector.ProfilesPanelDescriptor._openCPUProfile, true);
return link;
}






WebInspector.ScriptsPanelDescriptor = function()
{
WebInspector.PanelDescriptor.call(this, "scripts", WebInspector.UIString("Sources"), "ScriptsPanel", "ScriptsPanel.js");
WebInspector.ContextMenu.registerProvider(this);
}

WebInspector.ScriptsPanelDescriptor.prototype = {

appendApplicableItems: function(event, contextMenu, target)
{
var hasApplicableItems = target instanceof WebInspector.UISourceCode;

if (!hasApplicableItems && target instanceof WebInspector.RemoteObject) {
var remoteObject =   (target);
if (remoteObject.type !== "function")
return;
}

this.panel().appendApplicableItems(event, contextMenu, target);
},

registerShortcuts: function()
{
var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Sources Panel"));

section.addAlternateKeys(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.PauseContinue, WebInspector.UIString("Pause/Continue"));
section.addAlternateKeys(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepOver, WebInspector.UIString("Step over"));
section.addAlternateKeys(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepInto, WebInspector.UIString("Step into"));
section.addAlternateKeys(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepOut, WebInspector.UIString("Step out"));

var nextAndPrevFrameKeys = WebInspector.ScriptsPanelDescriptor.ShortcutKeys.NextCallFrame.concat(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.PrevCallFrame);
section.addRelatedKeys(nextAndPrevFrameKeys, WebInspector.UIString("Next/previous call frame"));

section.addAlternateKeys(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.EvaluateSelectionInConsole, WebInspector.UIString("Evaluate selection in console"));
section.addAlternateKeys(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.GoToMember, WebInspector.UIString("Go to member"));
section.addAlternateKeys(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.ToggleBreakpoint, WebInspector.UIString("Toggle breakpoint"));
},

__proto__: WebInspector.PanelDescriptor.prototype
}

WebInspector.ScriptsPanelDescriptor.ShortcutKeys = {
RunSnippet: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Enter, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
],

PauseContinue: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F8),
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Slash, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
],

StepOver: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F10),
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.SingleQuote, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
],

StepInto: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11),
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
],

StepOut: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11, WebInspector.KeyboardShortcut.Modifiers.Shift),
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
],

EvaluateSelectionInConsole: [
WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.Ctrl)
],

GoToMember: [
WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift)
],

ToggleBreakpoint: [
WebInspector.KeyboardShortcut.makeDescriptor("b", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
],

NextCallFrame: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Period, WebInspector.KeyboardShortcut.Modifiers.Ctrl)
],

PrevCallFrame: [
WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Comma, WebInspector.KeyboardShortcut.Modifiers.Ctrl)
]
};






WebInspector.TimelinePanelDescriptor = function()
{
WebInspector.PanelDescriptor.call(this, "timeline", WebInspector.UIString("Timeline"), "TimelinePanel", "TimelinePanel.js");
}

WebInspector.TimelinePanelDescriptor.prototype = {
registerShortcuts: function()
{
var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Timeline Panel"));
section.addAlternateKeys(WebInspector.TimelinePanelDescriptor.ShortcutKeys.StartStopRecording, WebInspector.UIString("Start/stop recording"));
section.addAlternateKeys(WebInspector.TimelinePanelDescriptor.ShortcutKeys.SaveToFile, WebInspector.UIString("Save timeline data"));
section.addAlternateKeys(WebInspector.TimelinePanelDescriptor.ShortcutKeys.LoadFromFile, WebInspector.UIString("Load timeline data"));
},

__proto__: WebInspector.PanelDescriptor.prototype
}

WebInspector.TimelinePanelDescriptor.ShortcutKeys = {
StartStopRecording: [
WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
],

SaveToFile: [
WebInspector.KeyboardShortcut.makeDescriptor("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
],

LoadFromFile: [
WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
]
}






WebInspector.DockController = function()
{
this._dockToggleButton = new WebInspector.StatusBarButton("", "dock-status-bar-item", 3);
this._dockToggleButtonOption = new WebInspector.StatusBarButton("", "dock-status-bar-item", 3);
this._dockToggleButton.addEventListener("click", this._toggleDockState, this);
this._dockToggleButtonOption.addEventListener("click", this._toggleDockState, this);
this._dockToggleButton.makeLongClickOptionsEnabled(this._createDockOptions.bind(this));

this.setDockSide(WebInspector.queryParamsObject["dockSide"] || "bottom");
WebInspector.settings.showToolbarIcons.addChangeListener(this._updateUI.bind(this));
}

WebInspector.DockController.State = {
DockedToBottom: "bottom",
DockedToRight: "right",
Undocked: "undocked"
}

WebInspector.DockController.Events = {
DockSideChanged: "DockSideChanged"
}

WebInspector.DockController.prototype = {

get element()
{
return this._dockToggleButton.element;
},


dockSide: function()
{
return this._dockSide;
},


setDockSide: function(dockSide)
{
if (this._dockSide === dockSide)
return;

if (this._dockSide)
WebInspector.settings.lastDockState.set(this._dockSide);

this._dockSide = dockSide;
if (dockSide === WebInspector.DockController.State.Undocked) 
WebInspector.userMetrics.WindowDocked.record();
else
WebInspector.userMetrics.WindowUndocked.record();
this._updateUI();
this.dispatchEventToListeners(WebInspector.DockController.Events.DockSideChanged, this._dockSide);
},


setDockingUnavailable: function(unavailable)
{
this._isDockingUnavailable = unavailable;
this._updateUI();
},

_updateUI: function()
{
var body = document.body;
switch (this._dockSide) {
case WebInspector.DockController.State.DockedToBottom:
body.removeStyleClass("undocked");
body.removeStyleClass("dock-to-right");
body.addStyleClass("dock-to-bottom");
break;
case WebInspector.DockController.State.DockedToRight: 
body.removeStyleClass("undocked");
body.addStyleClass("dock-to-right");
body.removeStyleClass("dock-to-bottom");
break;
case WebInspector.DockController.State.Undocked: 
body.addStyleClass("undocked");
body.removeStyleClass("dock-to-right");
body.removeStyleClass("dock-to-bottom");
break;
}

if (WebInspector.settings.showToolbarIcons.get())
document.body.addStyleClass("show-toolbar-icons");
else
document.body.removeStyleClass("show-toolbar-icons");

if (this._isDockingUnavailable && this._dockSide === WebInspector.DockController.State.Undocked) {
this._dockToggleButton.state = "undock";
this._dockToggleButton.setEnabled(false);
return;
}

this._dockToggleButton.setEnabled(true);


var sides = [WebInspector.DockController.State.DockedToBottom, WebInspector.DockController.State.Undocked, WebInspector.DockController.State.DockedToRight];
sides.remove(this._dockSide);
var lastState = WebInspector.settings.lastDockState.get();

sides.remove(lastState);
if (sides.length === 2) { 
lastState = sides[0];
sides.remove(lastState);
}
this._decorateButtonForTargetState(this._dockToggleButton, lastState);
this._decorateButtonForTargetState(this._dockToggleButtonOption, sides[0]);
},


_decorateButtonForTargetState: function(button, state)
{
switch (state) {
case WebInspector.DockController.State.DockedToBottom:
button.title = WebInspector.UIString("Dock to main window.");
button.state = "bottom";
break;
case WebInspector.DockController.State.DockedToRight:
button.title = WebInspector.UIString("Dock to main window.");
button.state = "right";
break;
case WebInspector.DockController.State.Undocked: 
button.title = WebInspector.UIString("Undock into separate window.");
button.state = "undock";
break;
}
},

_createDockOptions: function()
{
return [this._dockToggleButtonOption];
},


_toggleDockState: function(e)
{
var action;
switch (e.target.state) {
case "bottom": action = "bottom"; break;
case "right": action = "right"; break;
case "undock": action = "undocked"; break;
}
InspectorFrontendHost.requestSetDockSide(action);
},

__proto__: WebInspector.Object.prototype
}


WebInspector.dockController = null;





function platformExtensionAPI(coreAPI)
{
function getTabId()
{
return tabId;
}
chrome = window.chrome || {};



var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, "devtools");
if (!devtools_descriptor || devtools_descriptor.get)
Object.defineProperty(chrome, "devtools", { value: {}, enumerable: true });

chrome.devtools.inspectedWindow = {};
chrome.devtools.inspectedWindow.__defineGetter__("tabId", getTabId);
chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
chrome.devtools.network = coreAPI.network;
chrome.devtools.panels = coreAPI.panels;


if (extensionInfo.exposeExperimentalAPIs !== false) {
chrome.experimental = chrome.experimental || {};
chrome.experimental.devtools = chrome.experimental.devtools || {};

var properties = Object.getOwnPropertyNames(coreAPI);
for (var i = 0; i < properties.length; ++i) {
var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
}
chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
}
if (extensionInfo.exposeWebInspectorNamespace)
window.webInspector = coreAPI;
}








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.assertHasKey = function(object, key)
{
if (!object.hasOwnProperty(key))
this.fail("Expected object to contain key '" + key + "'");
};



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.inspectorView.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()
{

}

TestSuite.prototype.testCompletionOnPause = function()
{

}





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.inspectorView.currentPanel(), "Elements panel should be current one.");

WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, waitUntilScriptIsParsed);


test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});

function waitUntilScriptIsParsed()
{
WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, 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.testRendererProcessNativeMemorySize = function()
{
var test = this;
var KB = 1024;
var MB = KB * KB;

function step1(error, memoryBlock)
{
test.assertTrue(!error, "An error has occurred: " + error);
test.assertTrue(memoryBlock.size > 1 * MB && memoryBlock.size < 1500 * MB, "Unfeasible process size: " + memoryBlock.size + " bytes.");

test.releaseControl();
}

MemoryAgent.getProcessMemoryDistribution(false, step1);

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(test._scriptsAreParsed(["debugger_test_page.html"]), "Some scripts are missing.");
checkNoDuplicates();
test.releaseControl();
}

function checkNoDuplicates() {
var uiSourceCodes = test.nonAnonymousUISourceCodes_();
for (var i = 0; i < uiSourceCodes.length; i++) {
var scriptName = uiSourceCodes[i].url;
for (var j = i + 1; j < uiSourceCodes.length; j++)
test.assertTrue(scriptName !== uiSourceCodes[j].url, "Found script duplicates: " + test.uiSourceCodesToString_(uiSourceCodes));
}
}

test._waitUntilScriptsAreParsed(
["debugger_test_page.html"],
function() {
checkNoDuplicates();
setTimeout(switchToElementsTab, 0);
});



this.takeControl();
};




TestSuite.prototype.testPauseWhenLoadingDevTools = function()
{
this.showPanel("scripts");


if (WebInspector.debuggerModel.debuggerPausedDetails)
return;

this._waitForScriptPause(this.releaseControl.bind(this));
this.takeControl();
};




TestSuite.prototype.testPauseWhenScriptIsRunning = function()
{
this.showPanel("scripts");

this.evaluateInConsole_(
'setTimeout("handleClick()" , 0)',
didEvaluateInConsole.bind(this));

function didEvaluateInConsole(resultText) {
this.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);


setTimeout(testScriptPause.bind(this), 300);
}

function testScriptPause() {


WebInspector.panels.scripts._pauseButton.element.click();

this._waitForScriptPause(this.releaseControl.bind(this));
}

this.takeControl();
};



TestSuite.prototype.testNetworkSize = function()
{
var test = this;

function finishResource(resource, finishTime)
{
test.assertEquals(219, resource.transferSize, "Incorrect total encoded data length");
test.assertEquals(25, resource.resourceSize, "Incorrect total data length");
test.releaseControl();
}

this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkRequest", finishResource);


test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});

this.takeControl();
};



TestSuite.prototype.testNetworkSyncSize = function()
{
var test = this;

function finishResource(resource, finishTime)
{
test.assertEquals(219, resource.transferSize, "Incorrect total encoded data length");
test.assertEquals(25, resource.resourceSize, "Incorrect total data length");
test.releaseControl();
}

this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkRequest", finishResource);


test.evaluateInConsole_("var xhr = new XMLHttpRequest(); xhr.open(\"GET\", \"chunked\", false); xhr.send(null);", function() {});

this.takeControl();
};



TestSuite.prototype.testNetworkRawHeadersText = function()
{
var test = this;

function finishResource(resource, finishTime)
{
if (!resource.responseHeadersText)
test.fail("Failure: resource does not have response headers text");
test.assertEquals(164, resource.responseHeadersText.length, "Incorrect response headers text length");
test.releaseControl();
}

this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkRequest", finishResource);


test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});

this.takeControl();
};



TestSuite.prototype.testNetworkTiming = function()
{
var test = this;

function finishResource(resource, finishTime)
{



test.assertTrue(resource.timing.receiveHeadersEnd - resource.timing.connectStart >= 70,
"Time between receiveHeadersEnd and connectStart should be >=70ms, but was " +
"receiveHeadersEnd=" + resource.timing.receiveHeadersEnd + ", connectStart=" + resource.timing.connectStart + ".");
test.assertTrue(resource.responseReceivedTime - resource.startTime >= 0.07,
"Time between responseReceivedTime and startTime should be >=0.07s, but was " +
"responseReceivedTime=" + resource.responseReceivedTime + ", startTime=" + resource.startTime + ".");
test.assertTrue(resource.endTime - resource.startTime >= 0.14,
"Time between endTime and startTime should be >=0.14s, but was " +
"endtime=" + resource.endTime + ", startTime=" + resource.startTime + ".");

test.releaseControl();
}

this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkRequest", finishResource);


test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});

this.takeControl();
};


TestSuite.prototype.testConsoleOnNavigateBack = function()
{
if (WebInspector.console.messages.length === 1)
firstConsoleMessageReceived.call(this);
else
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, firstConsoleMessageReceived, this);

function firstConsoleMessageReceived() {
this.evaluateInConsole_("clickLink();", didClickLink.bind(this));
}

function didClickLink() {

this.assertEquals(1, WebInspector.console.messages.length);
this.assertEquals(1, WebInspector.console.messages[0].totalRepeatCount);
this.evaluateInConsole_("history.back();", didNavigateBack.bind(this));
}

function didNavigateBack()
{

this.evaluateInConsole_("void 0;", didCompleteNavigation.bind(this));
}

function didCompleteNavigation() {
this.assertEquals(1, WebInspector.console.messages.length);
this.assertEquals(1, WebInspector.console.messages[0].totalRepeatCount);
this.releaseControl();
}

this.takeControl();
};


TestSuite.prototype.testReattachAfterCrash = function()
{
this.evaluateInConsole_("1+1;", this.releaseControl.bind(this));
this.takeControl();
};


TestSuite.prototype.testSharedWorker = function()
{
function didEvaluateInConsole(resultText) {
this.assertEquals("2011", resultText);
this.releaseControl();
}
this.evaluateInConsole_("globalVar", didEvaluateInConsole.bind(this));
this.takeControl();
};


TestSuite.prototype.testPauseInSharedWorkerInitialization = function()
{
if (WebInspector.debuggerModel.debuggerPausedDetails)
return;
this._waitForScriptPause(this.releaseControl.bind(this));
this.takeControl();
};


TestSuite.prototype.testTimelineFrames = function()
{
var test = this;

function step1()
{
test.recordTimeline(onTimelineRecorded);
test.evaluateInConsole_("runTest()", function(){});
}

function onTimelineRecorded(records)
{
var frameCount = 0;
var recordsInFrame = {};

for (var i = 0; i < records.length; ++i) {
var record = records[i];
if (record.type !== "BeginFrame") {
recordsInFrame[record.type] = (recordsInFrame[record.type] || 0) + 1;
continue;
}
if (!frameCount++)
continue;

test.assertHasKey(recordsInFrame, "FireAnimationFrame");
test.assertHasKey(recordsInFrame, "Layout");
test.assertHasKey(recordsInFrame, "RecalculateStyles");
test.assertHasKey(recordsInFrame, "Paint");
recordsInFrame = {};
}
test.assertTrue(frameCount >= 5, "Not enough frames");
test.releaseControl();
}

step1();
test.takeControl();
}


TestSuite.prototype.testPageOverlayUpdate = function()
{
var test = this;

function populatePage()
{
var div1 = document.createElement("div");
div1.id = "div1";

div1.style.webkitTransform = "translateZ(0)";
document.body.appendChild(div1);
var div2 = document.createElement("div");
div2.id = "div2";
document.body.appendChild(div2);
}

function step1()
{
test.evaluateInConsole_(populatePage.toString() + "; populatePage();" +
"inspect(document.getElementById('div1'))", function() {});
WebInspector.notifications.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, step2);
}

function step2()
{
WebInspector.notifications.removeEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, step2);
test.recordTimeline(onTimelineRecorded);
setTimeout(step3, 500);
}

function step3()
{
test.evaluateInConsole_("inspect(document.getElementById('div2'))", function() {});
WebInspector.notifications.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, step4);
}

function step4()
{
WebInspector.notifications.removeEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, step4);
test.stopTimeline();
}

function onTimelineRecorded(records)
{
var types = {};
for (var i = 0; i < records.length; ++i)
types[records[i].type] = (types[records[i].type] || 0) + 1;

var frameCount = types["BeginFrame"];

test.assertTrue(frameCount >= 2, "Not enough DevTools overlay updates");


test.assertTrue(frameCount < 6, "Too many updates caused by DevTools overlay");
test.releaseControl();
}

step1();
this.takeControl();
}



TestSuite.prototype.recordTimeline = function(callback)
{
var records = [];
var dispatchOnRecordType = {}

WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, addRecord);
WebInspector.timelineManager.start();

function addRecord(event)
{
innerAddRecord(event.data);
}

function innerAddRecord(record)
{
records.push(record);
if (record.type === "TimeStamp" && record.data.message === "ready")
done();

if (record.children)
record.children.forEach(innerAddRecord);
}

function done()
{
WebInspector.timelineManager.stop();
WebInspector.timelineManager.removeEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, addRecord);
callback(records);
}
}


TestSuite.prototype.stopTimeline = function()
{
this.evaluateInConsole_("console.timeStamp('ready')", function() {});
}

TestSuite.prototype.waitForTestResultsInConsole = function()
{
var messages = WebInspector.console.messages;
for (var i = 0; i < messages.length; ++i) {
var text = messages[i].text;
if (text === "PASS")
return;
else if (/^FAIL/.test(text))
this.fail(text); 
}

function onConsoleMessage(event)
{
var text = event.data.text;
if (text === "PASS")
this.releaseControl();
else if (/^FAIL/.test(text))
this.fail(text);
}

WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, onConsoleMessage, this);
this.takeControl();
};

TestSuite.prototype.checkLogAndErrorMessages = function()
{
var messages = WebInspector.console.messages;

var matchesCount = 0;
function validMessage(message)
{
if (message.text === "log" && message.level === WebInspector.ConsoleMessage.MessageLevel.Log) {
++matchesCount;
return true;
}

if (message.text === "error" && message.level === WebInspector.ConsoleMessage.MessageLevel.Error) {
++matchesCount;
return true;
}
return false;
}

for (var i = 0; i < messages.length; ++i) {
if (validMessage(messages[i]))
continue;
this.fail(messages[i].text + ":" + messages[i].level); 
}

if (matchesCount === 2)
return;


function onConsoleMessage(event)
{
var message = event.data;
if (validMessage(message)) {
if (matchesCount === 2) {
this.releaseControl();
return;
}
} else
this.fail(message.text + ":" + messages[i].level);
}

WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, onConsoleMessage, this);
this.takeControl();
};


TestSuite.prototype.uiSourceCodesToString_ = function(uiSourceCodes)
{
var names = [];
for (var i = 0; i < uiSourceCodes.length; i++)
names.push('"' + uiSourceCodes[i].url + '"');
return names.join(",");
};



TestSuite.prototype.nonAnonymousUISourceCodes_ = function()
{
function filterOutAnonymous(uiSourceCode)
{
return !!uiSourceCode.url;
}

function filterOutService(uiSourceCode)
{
return !uiSourceCode.project().isServiceProject();
}

var uiSourceCodes = WebInspector.workspace.uiSourceCodes();
uiSourceCodes = uiSourceCodes.filter(filterOutService);
return uiSourceCodes.filter(filterOutAnonymous);
};



TestSuite.prototype.evaluateInConsole_ = function(code, callback)
{
WebInspector.showConsole();
WebInspector.consoleView.prompt.text = code;
WebInspector.consoleView.promptElement.dispatchEvent(TestSuite.createKeyEvent("Enter"));

this.addSniffer(WebInspector.ConsoleView.prototype, "_appendConsoleMessage",
function(commandResult) {
callback(commandResult.toMessageElement().textContent);
});
};



TestSuite.prototype._scriptsAreParsed = function(expected)
{
var uiSourceCodes = this.nonAnonymousUISourceCodes_();

var missing = expected.slice(0);
for (var i = 0; i < uiSourceCodes.length; ++i) {
for (var j = 0; j < missing.length; ++j) {
if (uiSourceCodes[i].name().search(missing[j]) !== -1) {
missing.splice(j, 1);
break;
}
}
}
return missing.length === 0;
};



TestSuite.prototype._waitForScriptPause = function(callback)
{
function pauseListener(event) {
WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, pauseListener, this);
callback();
}
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, pauseListener, this);
};



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.panels.scripts, "_addUISourceCode", waitForAllScripts);
}

waitForAllScripts();
};



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 oldLoadCompleted = InspectorFrontendAPI.loadCompleted;
InspectorFrontendAPI.loadCompleted = function()
{
oldLoadCompleted.call(InspectorFrontendAPI);
runTests();
}

})();

}

