|
"use strict"; |
|
var $protobuf = require("../.."); |
|
module.exports = exports = $protobuf.descriptor = $protobuf.Root.fromJSON(require("../../google/protobuf/descriptor.json")).lookup(".google.protobuf"); |
|
|
|
var Namespace = $protobuf.Namespace, |
|
Root = $protobuf.Root, |
|
Enum = $protobuf.Enum, |
|
Type = $protobuf.Type, |
|
Field = $protobuf.Field, |
|
MapField = $protobuf.MapField, |
|
OneOf = $protobuf.OneOf, |
|
Service = $protobuf.Service, |
|
Method = $protobuf.Method; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Root.fromDescriptor = function fromDescriptor(descriptor) { |
|
|
|
|
|
if (typeof descriptor.length === "number") |
|
descriptor = exports.FileDescriptorSet.decode(descriptor); |
|
|
|
var root = new Root(); |
|
|
|
if (descriptor.file) { |
|
var fileDescriptor, |
|
filePackage; |
|
for (var j = 0, i; j < descriptor.file.length; ++j) { |
|
filePackage = root; |
|
if ((fileDescriptor = descriptor.file[j])["package"] && fileDescriptor["package"].length) |
|
filePackage = root.define(fileDescriptor["package"]); |
|
if (fileDescriptor.name && fileDescriptor.name.length) |
|
root.files.push(filePackage.filename = fileDescriptor.name); |
|
if (fileDescriptor.messageType) |
|
for (i = 0; i < fileDescriptor.messageType.length; ++i) |
|
filePackage.add(Type.fromDescriptor(fileDescriptor.messageType[i], fileDescriptor.syntax)); |
|
if (fileDescriptor.enumType) |
|
for (i = 0; i < fileDescriptor.enumType.length; ++i) |
|
filePackage.add(Enum.fromDescriptor(fileDescriptor.enumType[i])); |
|
if (fileDescriptor.extension) |
|
for (i = 0; i < fileDescriptor.extension.length; ++i) |
|
filePackage.add(Field.fromDescriptor(fileDescriptor.extension[i])); |
|
if (fileDescriptor.service) |
|
for (i = 0; i < fileDescriptor.service.length; ++i) |
|
filePackage.add(Service.fromDescriptor(fileDescriptor.service[i])); |
|
var opts = fromDescriptorOptions(fileDescriptor.options, exports.FileOptions); |
|
if (opts) { |
|
var ks = Object.keys(opts); |
|
for (i = 0; i < ks.length; ++i) |
|
filePackage.setOption(ks[i], opts[ks[i]]); |
|
} |
|
} |
|
} |
|
|
|
return root; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
Root.prototype.toDescriptor = function toDescriptor(syntax) { |
|
var set = exports.FileDescriptorSet.create(); |
|
Root_toDescriptorRecursive(this, set.file, syntax); |
|
return set; |
|
}; |
|
|
|
|
|
function Root_toDescriptorRecursive(ns, files, syntax) { |
|
|
|
|
|
var file = exports.FileDescriptorProto.create({ name: ns.filename || (ns.fullName.substring(1).replace(/\./g, "_") || "root") + ".proto" }); |
|
if (syntax) |
|
file.syntax = syntax; |
|
if (!(ns instanceof Root)) |
|
file["package"] = ns.fullName.substring(1); |
|
|
|
|
|
for (var i = 0, nested; i < ns.nestedArray.length; ++i) |
|
if ((nested = ns._nestedArray[i]) instanceof Type) |
|
file.messageType.push(nested.toDescriptor(syntax)); |
|
else if (nested instanceof Enum) |
|
file.enumType.push(nested.toDescriptor()); |
|
else if (nested instanceof Field) |
|
file.extension.push(nested.toDescriptor(syntax)); |
|
else if (nested instanceof Service) |
|
file.service.push(nested.toDescriptor()); |
|
else if (nested instanceof Namespace) |
|
Root_toDescriptorRecursive(nested, files, syntax); |
|
|
|
|
|
file.options = toDescriptorOptions(ns.options, exports.FileOptions); |
|
|
|
|
|
if (file.messageType.length + file.enumType.length + file.extension.length + file.service.length) |
|
files.push(file); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var unnamedMessageIndex = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Type.fromDescriptor = function fromDescriptor(descriptor, syntax) { |
|
|
|
|
|
if (typeof descriptor.length === "number") |
|
descriptor = exports.DescriptorProto.decode(descriptor); |
|
|
|
|
|
var type = new Type(descriptor.name.length ? descriptor.name : "Type" + unnamedMessageIndex++, fromDescriptorOptions(descriptor.options, exports.MessageOptions)), |
|
i; |
|
|
|
if (descriptor.oneofDecl) |
|
for (i = 0; i < descriptor.oneofDecl.length; ++i) |
|
type.add(OneOf.fromDescriptor(descriptor.oneofDecl[i])); |
|
if (descriptor.field) |
|
for (i = 0; i < descriptor.field.length; ++i) { |
|
var field = Field.fromDescriptor(descriptor.field[i], syntax); |
|
type.add(field); |
|
if (descriptor.field[i].hasOwnProperty("oneofIndex")) |
|
type.oneofsArray[descriptor.field[i].oneofIndex].add(field); |
|
} |
|
if (descriptor.extension) |
|
for (i = 0; i < descriptor.extension.length; ++i) |
|
type.add(Field.fromDescriptor(descriptor.extension[i], syntax)); |
|
if (descriptor.nestedType) |
|
for (i = 0; i < descriptor.nestedType.length; ++i) { |
|
type.add(Type.fromDescriptor(descriptor.nestedType[i], syntax)); |
|
if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry) |
|
type.setOption("map_entry", true); |
|
} |
|
if (descriptor.enumType) |
|
for (i = 0; i < descriptor.enumType.length; ++i) |
|
type.add(Enum.fromDescriptor(descriptor.enumType[i])); |
|
if (descriptor.extensionRange && descriptor.extensionRange.length) { |
|
type.extensions = []; |
|
for (i = 0; i < descriptor.extensionRange.length; ++i) |
|
type.extensions.push([ descriptor.extensionRange[i].start, descriptor.extensionRange[i].end ]); |
|
} |
|
if (descriptor.reservedRange && descriptor.reservedRange.length || descriptor.reservedName && descriptor.reservedName.length) { |
|
type.reserved = []; |
|
if (descriptor.reservedRange) |
|
for (i = 0; i < descriptor.reservedRange.length; ++i) |
|
type.reserved.push([ descriptor.reservedRange[i].start, descriptor.reservedRange[i].end ]); |
|
if (descriptor.reservedName) |
|
for (i = 0; i < descriptor.reservedName.length; ++i) |
|
type.reserved.push(descriptor.reservedName[i]); |
|
} |
|
|
|
return type; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
Type.prototype.toDescriptor = function toDescriptor(syntax) { |
|
var descriptor = exports.DescriptorProto.create({ name: this.name }), |
|
i; |
|
|
|
for (i = 0; i < this.fieldsArray.length; ++i) { |
|
var fieldDescriptor; |
|
descriptor.field.push(fieldDescriptor = this._fieldsArray[i].toDescriptor(syntax)); |
|
if (this._fieldsArray[i] instanceof MapField) { |
|
var keyType = toDescriptorType(this._fieldsArray[i].keyType, this._fieldsArray[i].resolvedKeyType), |
|
valueType = toDescriptorType(this._fieldsArray[i].type, this._fieldsArray[i].resolvedType), |
|
valueTypeName = valueType === 11 || valueType === 14 |
|
? this._fieldsArray[i].resolvedType && shortname(this.parent, this._fieldsArray[i].resolvedType) || this._fieldsArray[i].type |
|
: undefined; |
|
descriptor.nestedType.push(exports.DescriptorProto.create({ |
|
name: fieldDescriptor.typeName, |
|
field: [ |
|
exports.FieldDescriptorProto.create({ name: "key", number: 1, label: 1, type: keyType }), |
|
exports.FieldDescriptorProto.create({ name: "value", number: 2, label: 1, type: valueType, typeName: valueTypeName }) |
|
], |
|
options: exports.MessageOptions.create({ mapEntry: true }) |
|
})); |
|
} |
|
} |
|
for (i = 0; i < this.oneofsArray.length; ++i) |
|
descriptor.oneofDecl.push(this._oneofsArray[i].toDescriptor()); |
|
for (i = 0; i < this.nestedArray.length; ++i) { |
|
if (this._nestedArray[i] instanceof Field) |
|
descriptor.field.push(this._nestedArray[i].toDescriptor(syntax)); |
|
else if (this._nestedArray[i] instanceof Type) |
|
descriptor.nestedType.push(this._nestedArray[i].toDescriptor(syntax)); |
|
else if (this._nestedArray[i] instanceof Enum) |
|
descriptor.enumType.push(this._nestedArray[i].toDescriptor()); |
|
|
|
} |
|
if (this.extensions) |
|
for (i = 0; i < this.extensions.length; ++i) |
|
descriptor.extensionRange.push(exports.DescriptorProto.ExtensionRange.create({ start: this.extensions[i][0], end: this.extensions[i][1] })); |
|
if (this.reserved) |
|
for (i = 0; i < this.reserved.length; ++i) |
|
if (typeof this.reserved[i] === "string") |
|
descriptor.reservedName.push(this.reserved[i]); |
|
else |
|
descriptor.reservedRange.push(exports.DescriptorProto.ReservedRange.create({ start: this.reserved[i][0], end: this.reserved[i][1] })); |
|
|
|
descriptor.options = toDescriptorOptions(this.options, exports.MessageOptions); |
|
|
|
return descriptor; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var numberRe = /^(?![eE])[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?$/; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Field.fromDescriptor = function fromDescriptor(descriptor, syntax) { |
|
|
|
|
|
if (typeof descriptor.length === "number") |
|
descriptor = exports.DescriptorProto.decode(descriptor); |
|
|
|
if (typeof descriptor.number !== "number") |
|
throw Error("missing field id"); |
|
|
|
|
|
var fieldType; |
|
if (descriptor.typeName && descriptor.typeName.length) |
|
fieldType = descriptor.typeName; |
|
else |
|
fieldType = fromDescriptorType(descriptor.type); |
|
|
|
|
|
var fieldRule; |
|
switch (descriptor.label) { |
|
|
|
case 1: fieldRule = undefined; break; |
|
case 2: fieldRule = "required"; break; |
|
case 3: fieldRule = "repeated"; break; |
|
default: throw Error("illegal label: " + descriptor.label); |
|
} |
|
|
|
var extendee = descriptor.extendee; |
|
if (descriptor.extendee !== undefined) { |
|
extendee = extendee.length ? extendee : undefined; |
|
} |
|
var field = new Field( |
|
descriptor.name.length ? descriptor.name : "field" + descriptor.number, |
|
descriptor.number, |
|
fieldType, |
|
fieldRule, |
|
extendee |
|
); |
|
|
|
field.options = fromDescriptorOptions(descriptor.options, exports.FieldOptions); |
|
|
|
if (descriptor.defaultValue && descriptor.defaultValue.length) { |
|
var defaultValue = descriptor.defaultValue; |
|
switch (defaultValue) { |
|
case "true": case "TRUE": |
|
defaultValue = true; |
|
break; |
|
case "false": case "FALSE": |
|
defaultValue = false; |
|
break; |
|
default: |
|
var match = numberRe.exec(defaultValue); |
|
if (match) |
|
defaultValue = parseInt(defaultValue); |
|
break; |
|
} |
|
field.setOption("default", defaultValue); |
|
} |
|
|
|
if (packableDescriptorType(descriptor.type)) { |
|
if (syntax === "proto3") { |
|
if (descriptor.options && !descriptor.options.packed) |
|
field.setOption("packed", false); |
|
} else if (!(descriptor.options && descriptor.options.packed)) |
|
field.setOption("packed", false); |
|
} |
|
|
|
return field; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
Field.prototype.toDescriptor = function toDescriptor(syntax) { |
|
var descriptor = exports.FieldDescriptorProto.create({ name: this.name, number: this.id }); |
|
|
|
if (this.map) { |
|
|
|
descriptor.type = 11; |
|
descriptor.typeName = $protobuf.util.ucFirst(this.name); |
|
descriptor.label = 3; |
|
|
|
} else { |
|
|
|
|
|
switch (descriptor.type = toDescriptorType(this.type, this.resolve().resolvedType)) { |
|
case 10: |
|
case 11: |
|
case 14: |
|
descriptor.typeName = this.resolvedType ? shortname(this.parent, this.resolvedType) : this.type; |
|
break; |
|
} |
|
|
|
|
|
switch (this.rule) { |
|
case "repeated": descriptor.label = 3; break; |
|
case "required": descriptor.label = 2; break; |
|
default: descriptor.label = 1; break; |
|
} |
|
|
|
} |
|
|
|
|
|
descriptor.extendee = this.extensionField ? this.extensionField.parent.fullName : this.extend; |
|
|
|
|
|
if (this.partOf) |
|
if ((descriptor.oneofIndex = this.parent.oneofsArray.indexOf(this.partOf)) < 0) |
|
throw Error("missing oneof"); |
|
|
|
if (this.options) { |
|
descriptor.options = toDescriptorOptions(this.options, exports.FieldOptions); |
|
if (this.options["default"] != null) |
|
descriptor.defaultValue = String(this.options["default"]); |
|
} |
|
|
|
if (syntax === "proto3") { |
|
if (!this.packed) |
|
(descriptor.options || (descriptor.options = exports.FieldOptions.create())).packed = false; |
|
} else if (this.packed) |
|
(descriptor.options || (descriptor.options = exports.FieldOptions.create())).packed = true; |
|
|
|
return descriptor; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var unnamedEnumIndex = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
Enum.fromDescriptor = function fromDescriptor(descriptor) { |
|
|
|
|
|
if (typeof descriptor.length === "number") |
|
descriptor = exports.EnumDescriptorProto.decode(descriptor); |
|
|
|
|
|
var values = {}; |
|
if (descriptor.value) |
|
for (var i = 0; i < descriptor.value.length; ++i) { |
|
var name = descriptor.value[i].name, |
|
value = descriptor.value[i].number || 0; |
|
values[name && name.length ? name : "NAME" + value] = value; |
|
} |
|
|
|
return new Enum( |
|
descriptor.name && descriptor.name.length ? descriptor.name : "Enum" + unnamedEnumIndex++, |
|
values, |
|
fromDescriptorOptions(descriptor.options, exports.EnumOptions) |
|
); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Enum.prototype.toDescriptor = function toDescriptor() { |
|
|
|
|
|
var values = []; |
|
for (var i = 0, ks = Object.keys(this.values); i < ks.length; ++i) |
|
values.push(exports.EnumValueDescriptorProto.create({ name: ks[i], number: this.values[ks[i]] })); |
|
|
|
return exports.EnumDescriptorProto.create({ |
|
name: this.name, |
|
value: values, |
|
options: toDescriptorOptions(this.options, exports.EnumOptions) |
|
}); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var unnamedOneofIndex = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
OneOf.fromDescriptor = function fromDescriptor(descriptor) { |
|
|
|
|
|
if (typeof descriptor.length === "number") |
|
descriptor = exports.OneofDescriptorProto.decode(descriptor); |
|
|
|
return new OneOf( |
|
|
|
descriptor.name && descriptor.name.length ? descriptor.name : "oneof" + unnamedOneofIndex++ |
|
|
|
); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
OneOf.prototype.toDescriptor = function toDescriptor() { |
|
return exports.OneofDescriptorProto.create({ |
|
name: this.name |
|
|
|
}); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var unnamedServiceIndex = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
Service.fromDescriptor = function fromDescriptor(descriptor) { |
|
|
|
|
|
if (typeof descriptor.length === "number") |
|
descriptor = exports.ServiceDescriptorProto.decode(descriptor); |
|
|
|
var service = new Service(descriptor.name && descriptor.name.length ? descriptor.name : "Service" + unnamedServiceIndex++, fromDescriptorOptions(descriptor.options, exports.ServiceOptions)); |
|
if (descriptor.method) |
|
for (var i = 0; i < descriptor.method.length; ++i) |
|
service.add(Method.fromDescriptor(descriptor.method[i])); |
|
|
|
return service; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Service.prototype.toDescriptor = function toDescriptor() { |
|
|
|
|
|
var methods = []; |
|
for (var i = 0; i < this.methodsArray.length; ++i) |
|
methods.push(this._methodsArray[i].toDescriptor()); |
|
|
|
return exports.ServiceDescriptorProto.create({ |
|
name: this.name, |
|
method: methods, |
|
options: toDescriptorOptions(this.options, exports.ServiceOptions) |
|
}); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var unnamedMethodIndex = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
Method.fromDescriptor = function fromDescriptor(descriptor) { |
|
|
|
|
|
if (typeof descriptor.length === "number") |
|
descriptor = exports.MethodDescriptorProto.decode(descriptor); |
|
|
|
return new Method( |
|
|
|
descriptor.name && descriptor.name.length ? descriptor.name : "Method" + unnamedMethodIndex++, |
|
"rpc", |
|
descriptor.inputType, |
|
descriptor.outputType, |
|
Boolean(descriptor.clientStreaming), |
|
Boolean(descriptor.serverStreaming), |
|
fromDescriptorOptions(descriptor.options, exports.MethodOptions) |
|
); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Method.prototype.toDescriptor = function toDescriptor() { |
|
return exports.MethodDescriptorProto.create({ |
|
name: this.name, |
|
inputType: this.resolvedRequestType ? this.resolvedRequestType.fullName : this.requestType, |
|
outputType: this.resolvedResponseType ? this.resolvedResponseType.fullName : this.responseType, |
|
clientStreaming: this.requestStream, |
|
serverStreaming: this.responseStream, |
|
options: toDescriptorOptions(this.options, exports.MethodOptions) |
|
}); |
|
}; |
|
|
|
|
|
|
|
|
|
function fromDescriptorType(type) { |
|
switch (type) { |
|
|
|
case 1: return "double"; |
|
case 2: return "float"; |
|
case 3: return "int64"; |
|
case 4: return "uint64"; |
|
case 5: return "int32"; |
|
case 6: return "fixed64"; |
|
case 7: return "fixed32"; |
|
case 8: return "bool"; |
|
case 9: return "string"; |
|
case 12: return "bytes"; |
|
case 13: return "uint32"; |
|
case 15: return "sfixed32"; |
|
case 16: return "sfixed64"; |
|
case 17: return "sint32"; |
|
case 18: return "sint64"; |
|
} |
|
throw Error("illegal type: " + type); |
|
} |
|
|
|
|
|
function packableDescriptorType(type) { |
|
switch (type) { |
|
case 1: |
|
case 2: |
|
case 3: |
|
case 4: |
|
case 5: |
|
case 6: |
|
case 7: |
|
case 8: |
|
case 13: |
|
case 14: |
|
case 15: |
|
case 16: |
|
case 17: |
|
case 18: |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
|
|
function toDescriptorType(type, resolvedType) { |
|
switch (type) { |
|
|
|
case "double": return 1; |
|
case "float": return 2; |
|
case "int64": return 3; |
|
case "uint64": return 4; |
|
case "int32": return 5; |
|
case "fixed64": return 6; |
|
case "fixed32": return 7; |
|
case "bool": return 8; |
|
case "string": return 9; |
|
case "bytes": return 12; |
|
case "uint32": return 13; |
|
case "sfixed32": return 15; |
|
case "sfixed64": return 16; |
|
case "sint32": return 17; |
|
case "sint64": return 18; |
|
} |
|
if (resolvedType instanceof Enum) |
|
return 14; |
|
if (resolvedType instanceof Type) |
|
return resolvedType.group ? 10 : 11; |
|
throw Error("illegal type: " + type); |
|
} |
|
|
|
|
|
function fromDescriptorOptions(options, type) { |
|
if (!options) |
|
return undefined; |
|
var out = []; |
|
for (var i = 0, field, key, val; i < type.fieldsArray.length; ++i) |
|
if ((key = (field = type._fieldsArray[i]).name) !== "uninterpretedOption") |
|
if (options.hasOwnProperty(key)) { |
|
val = options[key]; |
|
if (field.resolvedType instanceof Enum && typeof val === "number" && field.resolvedType.valuesById[val] !== undefined) |
|
val = field.resolvedType.valuesById[val]; |
|
out.push(underScore(key), val); |
|
} |
|
return out.length ? $protobuf.util.toObject(out) : undefined; |
|
} |
|
|
|
|
|
function toDescriptorOptions(options, type) { |
|
if (!options) |
|
return undefined; |
|
var out = []; |
|
for (var i = 0, ks = Object.keys(options), key, val; i < ks.length; ++i) { |
|
val = options[key = ks[i]]; |
|
if (key === "default") |
|
continue; |
|
var field = type.fields[key]; |
|
if (!field && !(field = type.fields[key = $protobuf.util.camelCase(key)])) |
|
continue; |
|
out.push(key, val); |
|
} |
|
return out.length ? type.fromObject($protobuf.util.toObject(out)) : undefined; |
|
} |
|
|
|
|
|
function shortname(from, to) { |
|
var fromPath = from.fullName.split("."), |
|
toPath = to.fullName.split("."), |
|
i = 0, |
|
j = 0, |
|
k = toPath.length - 1; |
|
if (!(from instanceof Root) && to instanceof Namespace) |
|
while (i < fromPath.length && j < k && fromPath[i] === toPath[j]) { |
|
var other = to.lookup(fromPath[i++], true); |
|
if (other !== null && other !== to) |
|
break; |
|
++j; |
|
} |
|
else |
|
for (; i < fromPath.length && j < k && fromPath[i] === toPath[j]; ++i, ++j); |
|
return toPath.slice(j).join("."); |
|
} |
|
|
|
|
|
function underScore(str) { |
|
return str.substring(0,1) |
|
+ str.substring(1) |
|
.replace(/([A-Z])(?=[a-z]|$)/g, function($0, $1) { return "_" + $1.toLowerCase(); }); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|