mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-23 14:15:24 +00:00
Compare commits
35 Commits
v0.5.0-alp
...
v0.5.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
420627d892 | ||
|
|
ce3a409997 | ||
|
|
0f9f1782ae | ||
|
|
d4704a02c5 | ||
|
|
9ca2ed2c93 | ||
|
|
ae12ffdefb | ||
|
|
1e13097126 | ||
|
|
9b8a6b1168 | ||
|
|
8f6dda5cd3 | ||
|
|
91780f236e | ||
|
|
f16474815c | ||
|
|
a8ff6d7e6e | ||
|
|
8395782a2e | ||
|
|
28ea625b01 | ||
|
|
efc569f6ed | ||
|
|
d377e10771 | ||
|
|
fef85877e6 | ||
|
|
19135bfaf4 | ||
|
|
5a147fccc2 | ||
|
|
20976814ba | ||
|
|
27e2612fc9 | ||
|
|
3ea432ef2d | ||
|
|
fe6acbc1e3 | ||
|
|
379b162e64 | ||
|
|
84832955dd | ||
|
|
34b99a51c3 | ||
|
|
fb5245e2af | ||
|
|
ff0a830e0c | ||
|
|
a365f071a4 | ||
|
|
f290e7b5b2 | ||
|
|
83a0ae673c | ||
|
|
7de646c290 | ||
|
|
5d681a72ac | ||
|
|
d725970e6e | ||
|
|
54b82760cd |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -2,4 +2,8 @@
|
|||||||
/target
|
/target
|
||||||
/scratch-project
|
/scratch-project
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
/server/failed-snapshots/
|
/server/failed-snapshots/
|
||||||
|
/*.rbxm
|
||||||
|
/*.rbxmx
|
||||||
|
/*.rbxl
|
||||||
|
/*.rbxlx
|
||||||
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -12,4 +12,7 @@
|
|||||||
url = https://github.com/LPGhatguy/roblox-lua-promise.git
|
url = https://github.com/LPGhatguy/roblox-lua-promise.git
|
||||||
[submodule "plugin/modules/t"]
|
[submodule "plugin/modules/t"]
|
||||||
path = plugin/modules/t
|
path = plugin/modules/t
|
||||||
url = https://github.com/osyrisrblx/t.git
|
url = https://github.com/osyrisrblx/t.git
|
||||||
|
[submodule "plugin/modules/rbx-dom"]
|
||||||
|
path = plugin/modules/rbx-dom
|
||||||
|
url = http://github.com/LPGhatguy/rbx-dom
|
||||||
|
|||||||
21
CHANGELOG.md
21
CHANGELOG.md
@@ -2,6 +2,27 @@
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.5.0 Alpha 11](https://github.com/LPGhatguy/rojo/releases/tag/v0.5.0-alpha.11) (May 29, 2019)
|
||||||
|
* Added support for implicit property values in JSON model files ([#154](https://github.com/LPGhatguy/rojo/pull/154))
|
||||||
|
* `Content` propertyes can now be specified in projects and model files as regular string literals.
|
||||||
|
* Added support for `BrickColor` properties.
|
||||||
|
* Added support for properties added in client release 384, like `Lighting.Technology` being set to `"ShadowMap"`.
|
||||||
|
* Improved performance when working with XML models and places
|
||||||
|
* Fixed serializing empty `Content` properties as XML
|
||||||
|
* Fixed serializing infinite and NaN floating point properties in XML
|
||||||
|
* Improved compatibility with XML models
|
||||||
|
* Plugin should now be able to live-sync more properties, and ignore ones it can't, like `Lighting.Technology`.
|
||||||
|
|
||||||
|
## 0.5.0 Alpha 10
|
||||||
|
* This release was a dud due to [issue #176](https://github.com/LPGhatguy/rojo/issues/176) and was rolled back.
|
||||||
|
|
||||||
|
## [0.5.0 Alpha 9](https://github.com/LPGhatguy/rojo/releases/tag/v0.5.0-alpha.9) (April 4, 2019)
|
||||||
|
* Changed `rojo build` to use buffered I/O, which can make it up to 2x faster in some cases.
|
||||||
|
* Building [*Road Not Taken*](https://github.com/LPGhatguy/roads) to an `rbxlx` file dropped from 150ms to 70ms on my machine
|
||||||
|
* Fixed `LocalizationTable` instances being made from `csv` files incorrectly interpreting empty rows and columns. ([#149](https://github.com/LPGhatguy/rojo/pull/149))
|
||||||
|
* Fixed CSV files with entries that parse as numbers causing Rojo to panic. ([#152](https://github.com/LPGhatguy/rojo/pull/152))
|
||||||
|
* Improved error messages when malformed CSV files are found in a Rojo project.
|
||||||
|
|
||||||
## [0.5.0 Alpha 8](https://github.com/LPGhatguy/rojo/releases/tag/v0.5.0-alpha.8) (March 29, 2019)
|
## [0.5.0 Alpha 8](https://github.com/LPGhatguy/rojo/releases/tag/v0.5.0-alpha.8) (March 29, 2019)
|
||||||
* Added support for a bunch of new types when dealing with XML model/place files:
|
* Added support for a bunch of new types when dealing with XML model/place files:
|
||||||
* `ColorSequence`
|
* `ColorSequence`
|
||||||
|
|||||||
796
Cargo.lock
generated
796
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"server",
|
"server",
|
||||||
"rojo-e2e",
|
]
|
||||||
]
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 1
|
||||||
39
design.gv
39
design.gv
@@ -1,39 +0,0 @@
|
|||||||
digraph G {
|
|
||||||
graph [
|
|
||||||
ranksep = "0.7",
|
|
||||||
nodesep = "1.0",
|
|
||||||
];
|
|
||||||
node [
|
|
||||||
fontname = "Hack",
|
|
||||||
shape = "record",
|
|
||||||
];
|
|
||||||
|
|
||||||
roblox_studio -> plugin [dir = "both"];
|
|
||||||
plugin -> web_server [style = "dashed", dir = "both"];
|
|
||||||
|
|
||||||
web_server -> session;
|
|
||||||
|
|
||||||
session -> rbx_session;
|
|
||||||
session -> fs_watcher;
|
|
||||||
session -> message_queue;
|
|
||||||
|
|
||||||
fs_watcher -> imfs [weight = "10"];
|
|
||||||
fs_watcher -> rbx_session [constraint = "false"];
|
|
||||||
|
|
||||||
imfs -> fs;
|
|
||||||
|
|
||||||
rbx_session -> imfs;
|
|
||||||
rbx_session -> middlewares [weight = "10"];
|
|
||||||
rbx_session -> message_queue [constraint = "false"];
|
|
||||||
|
|
||||||
plugin [label = "Studio Plugin"];
|
|
||||||
roblox_studio [label = "Roblox Studio"];
|
|
||||||
fs [label = "Filesystem"];
|
|
||||||
fs_watcher [label = "Filesystem Watcher"];
|
|
||||||
session [label = "Session"];
|
|
||||||
web_server [label = "Web API"];
|
|
||||||
imfs [label = "In-Memory Filesystem"];
|
|
||||||
rbx_session [label = "RbxSession"];
|
|
||||||
message_queue [label = "MessageQueue"];
|
|
||||||
middlewares [label = "Middlewares"];
|
|
||||||
}
|
|
||||||
@@ -28,13 +28,13 @@ Now that we have a project, one thing we can do is build a Roblox place file for
|
|||||||
All we have to do is call `rojo build`:
|
All we have to do is call `rojo build`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
rojo build -o MyNewProject.rbxl
|
rojo build -o MyNewProject.rbxlx
|
||||||
```
|
```
|
||||||
|
|
||||||
If you open `MyNewProject.rbxl` in Roblox Studio now, you should see a `Folder` containing a `ModuleScript` under `ReplicatedStorage`!
|
If you open `MyNewProject.rbxlx` in Roblox Studio now, you should see a `Folder` containing a `ModuleScript` under `ReplicatedStorage`!
|
||||||
|
|
||||||
!!! info
|
!!! info
|
||||||
To generate an XML place file instead, like if you're checking the place file into version control, just use `rbxlx` as the extension on the output file instead.
|
To generate a binary place file instead, use `rbxl`. Note that support for binary model/place files (`rbxm` and `rbxl`) is very limited in Rojo presently.
|
||||||
|
|
||||||
## Live-Syncing into Studio
|
## Live-Syncing into Studio
|
||||||
Building a place file is great for the initial build, but for actively working on your place, you'll want something quicker.
|
Building a place file is great for the initial build, but for actively working on your place, you'll want something quicker.
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ If you have Rust installed, the easiest way to get Rojo is with Cargo!
|
|||||||
To install the latest 0.5.0 alpha, use:
|
To install the latest 0.5.0 alpha, use:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cargo install rojo --version 0.5.0-alpha.8
|
cargo install rojo --version 0.5.0-alpha.11
|
||||||
```
|
```
|
||||||
|
|
||||||
## Installing the Plugin
|
## Installing the Plugin
|
||||||
|
|
||||||
### Installing from GitHub
|
### Installing from GitHub
|
||||||
The Rojo Roblox Studio plugin is available available from Rojo's [GitHub Releases page](https://github.com/LPGhatguy/rojo/releases).
|
The Rojo Roblox Studio plugin is available from Rojo's [GitHub Releases page](https://github.com/LPGhatguy/rojo/releases).
|
||||||
|
|
||||||
Download the attached `rbxm` file and put it into your Roblox Studio plugins folder. You can find that folder by pressing **Plugins Folder** from your Plugins toolbar in Roblox Studio:
|
Download the attached `rbxm` file and put it into your Roblox Studio plugins folder. You can find that folder by pressing **Plugins Folder** from your Plugins toolbar in Roblox Studio:
|
||||||
|
|
||||||
@@ -42,4 +42,4 @@ Download the attached `rbxm` file and put it into your Roblox Studio plugins fol
|
|||||||
Visit [Rojo's Roblox.com Plugin page](https://www.roblox.com/library/1997686364/Rojo-0-5-0-alpha-3) in Roblox Studio and press **Install**.
|
Visit [Rojo's Roblox.com Plugin page](https://www.roblox.com/library/1997686364/Rojo-0-5-0-alpha-3) in Roblox Studio and press **Install**.
|
||||||
|
|
||||||
## Visual Studio Code Extension
|
## Visual Studio Code Extension
|
||||||
If you use Visual Studio Code on Windows, you can install [Evaera's unofficial Rojo extension](https://marketplace.visualstudio.com/items?itemName=evaera.vscode-rojo), which will install both halves of Rojo for you. It even has a nifty UI to add partitions and start/stop the Rojo server!
|
If you use Visual Studio Code, you can install [Evaera's unofficial Rojo extension](https://marketplace.visualstudio.com/items?itemName=evaera.vscode-rojo), which will install both halves of Rojo for you. It even has a nifty UI to sync files and start/stop the Rojo server!
|
||||||
@@ -86,6 +86,6 @@ It would turn into instances in this shape:
|
|||||||
## Binary and XML Models
|
## Binary and XML Models
|
||||||
Rojo supports both binary (`.rbxm`) and XML (`.rbxmx`) models generated by Roblox Studio or another tool.
|
Rojo supports both binary (`.rbxm`) and XML (`.rbxmx`) models generated by Roblox Studio or another tool.
|
||||||
|
|
||||||
Not all property types are supported for all formats!
|
Support for the `rbxmx` is very good, while support for `rbxm` is still very early, buggy, and lacking features.
|
||||||
|
|
||||||
For a rundown of supported types, check out [rbx_tree's type coverage chart](https://github.com/LPGhatguy/rbx-tree#property-type-coverage).
|
For a rundown of supported types, check out [rbx-dom's type coverage chart](https://github.com/LPGhatguy/rbx-dom#property-type-coverage).
|
||||||
@@ -6,13 +6,16 @@
|
|||||||
"$path": "src"
|
"$path": "src"
|
||||||
},
|
},
|
||||||
"Roact": {
|
"Roact": {
|
||||||
"$path": "modules/roact/lib"
|
"$path": "modules/roact/src"
|
||||||
},
|
},
|
||||||
"Promise": {
|
"Promise": {
|
||||||
"$path": "modules/promise/lib"
|
"$path": "modules/promise/lib"
|
||||||
},
|
},
|
||||||
"t": {
|
"t": {
|
||||||
"$path": "modules/t/lib/t.lua"
|
"$path": "modules/t/lib"
|
||||||
|
},
|
||||||
|
"RbxDom": {
|
||||||
|
"$path": "modules/rbx-dom/rbx_dom_lua/src"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1
plugin/modules/rbx-dom
Submodule
1
plugin/modules/rbx-dom
Submodule
Submodule plugin/modules/rbx-dom added at ac129152f2
Submodule plugin/modules/roact updated: 8da5b29805...2fb60ea648
Submodule plugin/modules/t updated: a3a80ebf0a...f643b50682
@@ -13,13 +13,13 @@
|
|||||||
"$path": "src"
|
"$path": "src"
|
||||||
},
|
},
|
||||||
"Roact": {
|
"Roact": {
|
||||||
"$path": "modules/roact/lib"
|
"$path": "modules/roact/src"
|
||||||
},
|
},
|
||||||
"Promise": {
|
"Promise": {
|
||||||
"$path": "modules/promise/lib"
|
"$path": "modules/promise/lib"
|
||||||
},
|
},
|
||||||
"t": {
|
"t": {
|
||||||
"$path": "modules/t/lib/t.lua"
|
"$path": "modules/t/lib"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"TestEZ": {
|
"TestEZ": {
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "rojo",
|
|
||||||
"servePort": 8000,
|
|
||||||
"partitions": {
|
|
||||||
"plugin": {
|
|
||||||
"path": "src",
|
|
||||||
"target": "ReplicatedStorage.Rojo.Plugin"
|
|
||||||
},
|
|
||||||
"modules/roact": {
|
|
||||||
"path": "modules/roact/lib",
|
|
||||||
"target": "ReplicatedStorage.Rojo.Roact"
|
|
||||||
},
|
|
||||||
"modules/rodux": {
|
|
||||||
"path": "modules/rodux/lib",
|
|
||||||
"target": "ReplicatedStorage.Rojo.Rodux"
|
|
||||||
},
|
|
||||||
"modules/roact-rodux": {
|
|
||||||
"path": "modules/roact-rodux/lib",
|
|
||||||
"target": "ReplicatedStorage.Rojo.RoactRodux"
|
|
||||||
},
|
|
||||||
"modules/promise": {
|
|
||||||
"path": "modules/promise/lib",
|
|
||||||
"target": "ReplicatedStorage.Rojo.Promise"
|
|
||||||
},
|
|
||||||
"modules/testez": {
|
|
||||||
"path": "modules/testez/lib",
|
|
||||||
"target": "ReplicatedStorage.TestEZ"
|
|
||||||
},
|
|
||||||
"tests": {
|
|
||||||
"path": "testBootstrap.server.lua",
|
|
||||||
"target": "TestService.testBootstrap"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -80,7 +80,8 @@ function App:init()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function App:render()
|
function App:render()
|
||||||
local children
|
-- FIXME: https://github.com/Roblox/roact/issues/209
|
||||||
|
local children = {}
|
||||||
|
|
||||||
if self.state.sessionStatus == SessionStatus.Connected then
|
if self.state.sessionStatus == SessionStatus.Connected then
|
||||||
children = {
|
children = {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
return {
|
return {
|
||||||
codename = "Epiphany",
|
codename = "Epiphany",
|
||||||
version = {0, 5, 0, "-alpha.8"},
|
version = {0, 5, 0, "-alpha.11"},
|
||||||
expectedServerVersionString = "0.5.0 or newer",
|
expectedServerVersionString = "0.5.0 or newer",
|
||||||
protocolVersion = 2,
|
protocolVersion = 2,
|
||||||
defaultHost = "localhost",
|
defaultHost = "localhost",
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ local setCanonicalProperty = require(script.Parent.setCanonicalProperty)
|
|||||||
local rojoValueToRobloxValue = require(script.Parent.rojoValueToRobloxValue)
|
local rojoValueToRobloxValue = require(script.Parent.rojoValueToRobloxValue)
|
||||||
local Types = require(script.Parent.Types)
|
local Types = require(script.Parent.Types)
|
||||||
|
|
||||||
|
local function setParent(instance, newParent)
|
||||||
|
pcall(function()
|
||||||
|
instance.Parent = newParent
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
local Reconciler = {}
|
local Reconciler = {}
|
||||||
Reconciler.__index = Reconciler
|
Reconciler.__index = Reconciler
|
||||||
|
|
||||||
@@ -117,7 +123,7 @@ function Reconciler:reconcile(virtualInstancesById, id, instance)
|
|||||||
|
|
||||||
-- Some instances, like services, don't like having their Parent
|
-- Some instances, like services, don't like having their Parent
|
||||||
-- property poked, even if we're setting it to the same value.
|
-- property poked, even if we're setting it to the same value.
|
||||||
setCanonicalProperty(instance, "Parent", parent)
|
setParent(instance, parent)
|
||||||
end
|
end
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
@@ -154,7 +160,7 @@ function Reconciler:__reify(virtualInstancesById, id, parent)
|
|||||||
self:__reify(virtualInstancesById, childId, instance)
|
self:__reify(virtualInstancesById, childId, instance)
|
||||||
end
|
end
|
||||||
|
|
||||||
setCanonicalProperty(instance, "Parent", parent)
|
setParent(instance, parent)
|
||||||
self.instanceMap:insert(id, instance)
|
self.instanceMap:insert(id, instance)
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|||||||
@@ -1,38 +1,33 @@
|
|||||||
local primitiveTypes = {
|
local RbxDom = require(script:FindFirstAncestor("Rojo").RbxDom)
|
||||||
Bool = true,
|
|
||||||
Enum = true,
|
|
||||||
Float32 = true,
|
|
||||||
Float64 = true,
|
|
||||||
Int32 = true,
|
|
||||||
Int64 = true,
|
|
||||||
String = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
local directConstructors = {
|
|
||||||
CFrame = CFrame.new,
|
|
||||||
Color3 = Color3.new,
|
|
||||||
Color3uint8 = Color3.fromRGB,
|
|
||||||
Rect = Rect.new,
|
|
||||||
UDim = UDim.new,
|
|
||||||
UDim2 = UDim2.new,
|
|
||||||
Vector2 = Vector2.new,
|
|
||||||
Vector2int16 = Vector2int16.new,
|
|
||||||
Vector3 = Vector3.new,
|
|
||||||
Vector3int16 = Vector3int16.new,
|
|
||||||
}
|
|
||||||
|
|
||||||
local function rojoValueToRobloxValue(value)
|
local function rojoValueToRobloxValue(value)
|
||||||
if primitiveTypes[value.Type] then
|
-- TODO: Manually decode this value by looking up its GUID The Rojo server
|
||||||
return value.Value
|
-- doesn't give us valid ref values yet, so this isn't important yet.
|
||||||
|
if value.Type == "Ref" then
|
||||||
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local constructor = directConstructors[value.Type]
|
-- TODO: Remove this once rbx_dom_weak and rbx_dom_lua agree on encoding
|
||||||
if constructor ~= nil then
|
if value.Type == "BinaryString" then
|
||||||
return constructor(unpack(value.Value))
|
local actualValue = ""
|
||||||
|
|
||||||
|
for i = 1, #value.Value do
|
||||||
|
actualValue = actualValue .. string.char(i)
|
||||||
|
end
|
||||||
|
|
||||||
|
value = {
|
||||||
|
Type = "BinaryString",
|
||||||
|
Value = actualValue,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local errorMessage = ("The Rojo plugin doesn't know how to handle values of type %q yet!"):format(tostring(value.Type))
|
local success, decodedValue = RbxDom.EncodedValue.decode(value)
|
||||||
error(errorMessage)
|
|
||||||
|
if not success then
|
||||||
|
error(decodedValue, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
return decodedValue
|
||||||
end
|
end
|
||||||
|
|
||||||
return rojoValueToRobloxValue
|
return rojoValueToRobloxValue
|
||||||
@@ -1,33 +1,17 @@
|
|||||||
|
local RbxDom = require(script:FindFirstAncestor("Rojo").RbxDom)
|
||||||
|
|
||||||
local Logging = require(script.Parent.Logging)
|
local Logging = require(script.Parent.Logging)
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Attempts to set a property on the given instance.
|
Attempts to set a property on the given instance.
|
||||||
|
|
||||||
This method deals in terms of what Rojo calls 'canonical properties', which
|
|
||||||
don't necessarily exist either in serialization or in Lua-reflected APIs,
|
|
||||||
but may be present in the API dump.
|
|
||||||
|
|
||||||
Ideally, canonical properties map 1:1 with properties we can assign, but in
|
|
||||||
some cases like LocalizationTable contents and CollectionService tags, we
|
|
||||||
have to read/write properties a little differently.
|
|
||||||
]]
|
]]
|
||||||
local function setCanonicalProperty(instance, key, value)
|
local function setCanonicalProperty(instance, key, value)
|
||||||
-- The 'Contents' property of LocalizationTable isn't directly exposed, but
|
if not RbxDom.CanonicalProperty.isScriptable(instance.ClassName, key) then
|
||||||
-- has corresponding (deprecated) getters and setters.
|
return false
|
||||||
if instance.ClassName == "LocalizationTable" and key == "Contents" then
|
|
||||||
instance:SetContents(value)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Temporary workaround for fixing issue #141 in this specific case.
|
|
||||||
if instance.ClassName == "Lighting" and key == "Technology" then
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If we don't have permissions to access this value at all, we can skip it.
|
-- If we don't have permissions to access this value at all, we can skip it.
|
||||||
local readSuccess, existingValue = pcall(function()
|
local readSuccess, existingValue = RbxDom.CanonicalProperty.read(instance, key)
|
||||||
return instance[key]
|
|
||||||
end)
|
|
||||||
|
|
||||||
if not readSuccess then
|
if not readSuccess then
|
||||||
-- An error will be thrown if there was a permission issue or if the
|
-- An error will be thrown if there was a permission issue or if the
|
||||||
@@ -35,17 +19,13 @@ local function setCanonicalProperty(instance, key, value)
|
|||||||
-- because it's probably their fault.
|
-- because it's probably their fault.
|
||||||
if existingValue:find("lacking permission") then
|
if existingValue:find("lacking permission") then
|
||||||
Logging.trace("Permission error reading property %s on class %s", tostring(key), instance.ClassName)
|
Logging.trace("Permission error reading property %s on class %s", tostring(key), instance.ClassName)
|
||||||
return
|
return false
|
||||||
else
|
else
|
||||||
error(("Invalid property %s on class %s: %s"):format(tostring(key), instance.ClassName, existingValue), 2)
|
error(("Invalid property %s on class %s: %s"):format(tostring(key), instance.ClassName, existingValue), 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local writeSuccess, err = pcall(function()
|
local writeSuccess, err = RbxDom.CanonicalProperty.write(instance, key, value)
|
||||||
if existingValue ~= value then
|
|
||||||
instance[key] = value
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
if not writeSuccess then
|
if not writeSuccess then
|
||||||
error(("Cannot set property %s on class %s: %s"):format(tostring(key), instance.ClassName, err), 2)
|
error(("Cannot set property %s on class %s: %s"):format(tostring(key), instance.ClassName, err), 2)
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "rojo-e2e"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
# Rojo End-to-End
|
|
||||||
This is a WIP test runner designed for Rojo. It will eventually start up the Rojo server and plugin and test functionality end-to-end.
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
use std::{
|
|
||||||
path::Path,
|
|
||||||
process::Command,
|
|
||||||
thread,
|
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let plugin_path = Path::new("../plugin");
|
|
||||||
let server_path = Path::new("../server");
|
|
||||||
let tests_path = Path::new("../tests");
|
|
||||||
|
|
||||||
let server = Command::new("cargo")
|
|
||||||
.args(&["run", "--", "serve", "../test-projects/empty"])
|
|
||||||
.current_dir(server_path)
|
|
||||||
.spawn();
|
|
||||||
|
|
||||||
thread::sleep(Duration::from_millis(1000));
|
|
||||||
|
|
||||||
// TODO: Wait for server to start responding on the right port
|
|
||||||
|
|
||||||
let test_client = Command::new("lua")
|
|
||||||
.args(&["runTest.lua", "tests/empty.lua"])
|
|
||||||
.current_dir(plugin_path)
|
|
||||||
.spawn();
|
|
||||||
|
|
||||||
thread::sleep(Duration::from_millis(300));
|
|
||||||
|
|
||||||
// TODO: Collect output from the client for success/failure?
|
|
||||||
|
|
||||||
println!("Dying!");
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rojo"
|
name = "rojo"
|
||||||
version = "0.5.0-alpha.8"
|
version = "0.5.0-alpha.11"
|
||||||
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
||||||
description = "A tool to create robust Roblox projects"
|
description = "A tool to create robust Roblox projects"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@@ -30,15 +30,14 @@ log = "0.4"
|
|||||||
maplit = "1.0.1"
|
maplit = "1.0.1"
|
||||||
notify = "4.0"
|
notify = "4.0"
|
||||||
rbx_binary = "0.4.0"
|
rbx_binary = "0.4.0"
|
||||||
rbx_dom_weak = "1.3.0"
|
rbx_dom_weak = "1.7.0"
|
||||||
rbx_xml = "0.6.0"
|
rbx_xml = "0.9.0"
|
||||||
rbx_reflection = "2.0.374"
|
rbx_reflection = "3.0.384"
|
||||||
regex = "1.0"
|
regex = "1.0"
|
||||||
reqwest = "0.9.5"
|
reqwest = "0.9.5"
|
||||||
rlua = "0.16"
|
rlua = "0.16"
|
||||||
ritz = "0.1.0"
|
ritz = "0.1.0"
|
||||||
serde = "1.0"
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_derive = "1.0"
|
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
uuid = { version = "0.7", features = ["v4", "serde"] }
|
uuid = { version = "0.7", features = ["v4", "serde"] }
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
fs::File,
|
fs::File,
|
||||||
io,
|
io::{self, Write, BufWriter},
|
||||||
};
|
};
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
@@ -74,6 +74,11 @@ impl_from!(BuildError {
|
|||||||
SnapshotError => SnapshotError,
|
SnapshotError => SnapshotError,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fn xml_encode_config() -> rbx_xml::EncodeOptions {
|
||||||
|
rbx_xml::EncodeOptions::new()
|
||||||
|
.property_behavior(rbx_xml::EncodePropertyBehavior::WriteUnknown)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(options: &BuildOptions) -> Result<(), BuildError> {
|
pub fn build(options: &BuildOptions) -> Result<(), BuildError> {
|
||||||
let output_kind = options.output_kind
|
let output_kind = options.output_kind
|
||||||
.or_else(|| detect_output_kind(options))
|
.or_else(|| detect_output_kind(options))
|
||||||
@@ -92,7 +97,7 @@ pub fn build(options: &BuildOptions) -> Result<(), BuildError> {
|
|||||||
let mut imfs = Imfs::new();
|
let mut imfs = Imfs::new();
|
||||||
imfs.add_roots_from_project(&project)?;
|
imfs.add_roots_from_project(&project)?;
|
||||||
let tree = construct_oneoff_tree(&project, &imfs)?;
|
let tree = construct_oneoff_tree(&project, &imfs)?;
|
||||||
let mut file = File::create(&options.output_file)?;
|
let mut file = BufWriter::new(File::create(&options.output_file)?);
|
||||||
|
|
||||||
match output_kind {
|
match output_kind {
|
||||||
OutputKind::Rbxmx => {
|
OutputKind::Rbxmx => {
|
||||||
@@ -100,7 +105,7 @@ pub fn build(options: &BuildOptions) -> Result<(), BuildError> {
|
|||||||
// descendants.
|
// descendants.
|
||||||
|
|
||||||
let root_id = tree.get_root_id();
|
let root_id = tree.get_root_id();
|
||||||
rbx_xml::encode(&tree, &[root_id], &mut file)?;
|
rbx_xml::to_writer(&mut file, &tree, &[root_id], xml_encode_config())?;
|
||||||
},
|
},
|
||||||
OutputKind::Rbxlx => {
|
OutputKind::Rbxlx => {
|
||||||
// Place files don't contain an entry for the DataModel, but our
|
// Place files don't contain an entry for the DataModel, but our
|
||||||
@@ -108,7 +113,7 @@ pub fn build(options: &BuildOptions) -> Result<(), BuildError> {
|
|||||||
|
|
||||||
let root_id = tree.get_root_id();
|
let root_id = tree.get_root_id();
|
||||||
let top_level_ids = tree.get_instance(root_id).unwrap().get_children_ids();
|
let top_level_ids = tree.get_instance(root_id).unwrap().get_children_ids();
|
||||||
rbx_xml::encode(&tree, top_level_ids, &mut file)?;
|
rbx_xml::to_writer(&mut file, &tree, top_level_ids, xml_encode_config())?;
|
||||||
},
|
},
|
||||||
OutputKind::Rbxm => {
|
OutputKind::Rbxm => {
|
||||||
let root_id = tree.get_root_id();
|
let root_id = tree.get_root_id();
|
||||||
@@ -121,5 +126,7 @@ pub fn build(options: &BuildOptions) -> Result<(), BuildError> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.flush()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -80,10 +80,10 @@ pub fn upload(options: &UploadOptions) -> Result<(), UploadError> {
|
|||||||
match options.kind {
|
match options.kind {
|
||||||
Some("place") | None => {
|
Some("place") | None => {
|
||||||
let top_level_ids = tree.get_instance(root_id).unwrap().get_children_ids();
|
let top_level_ids = tree.get_instance(root_id).unwrap().get_children_ids();
|
||||||
rbx_xml::encode(&tree, top_level_ids, &mut contents)?;
|
rbx_xml::to_writer_default(&mut contents, &tree, top_level_ids)?;
|
||||||
},
|
},
|
||||||
Some("model") => {
|
Some("model") => {
|
||||||
rbx_xml::encode(&tree, &[root_id], &mut contents)?;
|
rbx_xml::to_writer_default(&mut contents, &tree, &[root_id])?;
|
||||||
},
|
},
|
||||||
Some(invalid) => return Err(UploadError::InvalidKind(invalid.to_owned())),
|
Some(invalid) => return Err(UploadError::InvalidKind(invalid.to_owned())),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use failure::Fail;
|
use failure::Fail;
|
||||||
use serde_derive::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
use crate::project::{Project, ProjectNode};
|
use crate::project::{Project, ProjectNode};
|
||||||
|
|
||||||
@@ -89,11 +89,13 @@ impl Imfs {
|
|||||||
|
|
||||||
pub fn add_root(&mut self, path: &Path) -> Result<(), FsError> {
|
pub fn add_root(&mut self, path: &Path) -> Result<(), FsError> {
|
||||||
debug_assert!(path.is_absolute());
|
debug_assert!(path.is_absolute());
|
||||||
debug_assert!(!self.is_within_roots(path));
|
|
||||||
|
|
||||||
self.roots.insert(path.to_path_buf());
|
if !self.is_within_roots(path) {
|
||||||
|
self.roots.insert(path.to_path_buf());
|
||||||
|
self.descend_and_read_from_disk(path)?;
|
||||||
|
}
|
||||||
|
|
||||||
self.descend_and_read_from_disk(path)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_root(&mut self, path: &Path) {
|
pub fn remove_root(&mut self, path: &Path) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::{
|
|||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde_derive::Serialize;
|
use serde::Serialize;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! # use std::path::PathBuf;
|
//! # use std::path::PathBuf;
|
||||||
//! # use serde_derive::{Serialize, Deserialize};
|
//! # use serde::{Serialize, Deserialize};
|
||||||
//!
|
//!
|
||||||
//! #[derive(Serialize, Deserialize)]
|
//! #[derive(Serialize, Deserialize)]
|
||||||
//! struct Mine {
|
//! struct Mine {
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ use std::{
|
|||||||
use log::warn;
|
use log::warn;
|
||||||
use failure::Fail;
|
use failure::Fail;
|
||||||
use rbx_dom_weak::{UnresolvedRbxValue, RbxValue};
|
use rbx_dom_weak::{UnresolvedRbxValue, RbxValue};
|
||||||
use serde_derive::{Serialize, Deserialize};
|
use serde::{Serialize, Serializer, Deserialize};
|
||||||
use serde::{Serialize, Serializer};
|
|
||||||
|
|
||||||
static DEFAULT_PLACE: &'static str = include_str!("../assets/place.project.json");
|
static DEFAULT_PLACE: &'static str = include_str!("../assets/place.project.json");
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use rlua::Lua;
|
use rlua::Lua;
|
||||||
use serde_derive::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use log::{info, trace, error};
|
use log::{info, trace, error};
|
||||||
use rbx_dom_weak::{RbxTree, RbxId};
|
use rbx_dom_weak::{RbxTree, RbxId};
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ use rlua::Lua;
|
|||||||
use failure::Fail;
|
use failure::Fail;
|
||||||
use log::info;
|
use log::info;
|
||||||
use maplit::hashmap;
|
use maplit::hashmap;
|
||||||
use rbx_dom_weak::{RbxTree, RbxValue, RbxInstanceProperties};
|
use rbx_dom_weak::{RbxTree, RbxValue, RbxInstanceProperties, UnresolvedRbxValue};
|
||||||
use serde_derive::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use rbx_reflection::{try_resolve_value, ValueResolveError};
|
use rbx_reflection::{try_resolve_value, ValueResolveError};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -106,6 +106,7 @@ pub enum SnapshotError {
|
|||||||
},
|
},
|
||||||
|
|
||||||
XmlModelDecodeError {
|
XmlModelDecodeError {
|
||||||
|
#[fail(cause)]
|
||||||
inner: rbx_xml::DecodeError,
|
inner: rbx_xml::DecodeError,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
},
|
},
|
||||||
@@ -115,6 +116,12 @@ pub enum SnapshotError {
|
|||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
CsvDecodeError {
|
||||||
|
#[fail(cause)]
|
||||||
|
inner: csv::Error,
|
||||||
|
path: PathBuf,
|
||||||
|
},
|
||||||
|
|
||||||
ProjectNodeUnusable,
|
ProjectNodeUnusable,
|
||||||
|
|
||||||
ProjectNodeInvalidTransmute {
|
ProjectNodeInvalidTransmute {
|
||||||
@@ -146,11 +153,14 @@ impl fmt::Display for SnapshotError {
|
|||||||
write!(output, "Malformed .model.json model: {} in path {}", inner, path.display())
|
write!(output, "Malformed .model.json model: {} in path {}", inner, path.display())
|
||||||
},
|
},
|
||||||
SnapshotError::XmlModelDecodeError { inner, path } => {
|
SnapshotError::XmlModelDecodeError { inner, path } => {
|
||||||
write!(output, "Malformed rbxmx model: {:?} in path {}", inner, path.display())
|
write!(output, "Malformed rbxmx model: {} in path {}", inner, path.display())
|
||||||
},
|
},
|
||||||
SnapshotError::BinaryModelDecodeError { inner, path } => {
|
SnapshotError::BinaryModelDecodeError { inner, path } => {
|
||||||
write!(output, "Malformed rbxm model: {:?} in path {}", inner, path.display())
|
write!(output, "Malformed rbxm model: {:?} in path {}", inner, path.display())
|
||||||
},
|
},
|
||||||
|
SnapshotError::CsvDecodeError { inner, path } => {
|
||||||
|
write!(output, "Malformed csv file: {} in path {}", inner, path.display())
|
||||||
|
},
|
||||||
SnapshotError::ProjectNodeUnusable => {
|
SnapshotError::ProjectNodeUnusable => {
|
||||||
write!(output, "Rojo project nodes must specify either $path or $className.")
|
write!(output, "Rojo project nodes must specify either $path or $className.")
|
||||||
},
|
},
|
||||||
@@ -475,16 +485,87 @@ fn snapshot_txt_file<'source>(
|
|||||||
fn snapshot_csv_file<'source>(
|
fn snapshot_csv_file<'source>(
|
||||||
file: &'source ImfsFile,
|
file: &'source ImfsFile,
|
||||||
) -> SnapshotResult<'source> {
|
) -> SnapshotResult<'source> {
|
||||||
|
/// Struct that holds any valid row from a Roblox CSV translation table.
|
||||||
|
///
|
||||||
|
/// We manually deserialize into this table from CSV, but let JSON handle
|
||||||
|
/// serializing.
|
||||||
|
#[derive(Debug, Default, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct LocalizationEntry<'a> {
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
key: Option<&'a str>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
context: Option<&'a str>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
example: Option<&'a str>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
source: Option<&'a str>,
|
||||||
|
|
||||||
|
values: HashMap<&'a str, &'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
let instance_name = file.path
|
let instance_name = file.path
|
||||||
.file_stem().expect("Could not extract file stem")
|
.file_stem().expect("Could not extract file stem")
|
||||||
.to_str().expect("Could not convert path to UTF-8");
|
.to_str().expect("Could not convert path to UTF-8");
|
||||||
|
|
||||||
let entries: Vec<LocalizationEntryJson> = csv::Reader::from_reader(file.contents.as_slice())
|
// Normally, we'd be able to let the csv crate construct our struct for us.
|
||||||
.deserialize()
|
//
|
||||||
// TODO: Propagate error upward instead of panicking
|
// However, because of a limitation with Serde's 'flatten' feature, it's not
|
||||||
.map(|result| result.expect("Malformed localization table found!"))
|
// possible presently to losslessly collect extra string values while using
|
||||||
.map(LocalizationEntryCsv::to_json)
|
// csv+Serde.
|
||||||
.collect();
|
//
|
||||||
|
// https://github.com/BurntSushi/rust-csv/issues/151
|
||||||
|
let mut reader = csv::Reader::from_reader(file.contents.as_slice());
|
||||||
|
|
||||||
|
let headers = reader.headers()
|
||||||
|
.map_err(|inner| SnapshotError::CsvDecodeError {
|
||||||
|
inner,
|
||||||
|
path: file.path.to_path_buf(),
|
||||||
|
})?
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let mut records = Vec::new();
|
||||||
|
|
||||||
|
for record in reader.into_records() {
|
||||||
|
let record = record
|
||||||
|
.map_err(|inner| SnapshotError::CsvDecodeError {
|
||||||
|
inner,
|
||||||
|
path: file.path.to_path_buf(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
records.push(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut entries = Vec::new();
|
||||||
|
|
||||||
|
for record in &records {
|
||||||
|
let mut entry = LocalizationEntry::default();
|
||||||
|
|
||||||
|
for (header, value) in headers.iter().zip(record.into_iter()) {
|
||||||
|
if header.is_empty() || value.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
match header {
|
||||||
|
"Key" => entry.key = Some(value),
|
||||||
|
"Source" => entry.source = Some(value),
|
||||||
|
"Context" => entry.context = Some(value),
|
||||||
|
"Example" => entry.example = Some(value),
|
||||||
|
_ => {
|
||||||
|
entry.values.insert(header, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry.key.is_none() && entry.source.is_none() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.push(entry);
|
||||||
|
}
|
||||||
|
|
||||||
let table_contents = serde_json::to_string(&entries)
|
let table_contents = serde_json::to_string(&entries)
|
||||||
.expect("Could not encode JSON for localization table");
|
.expect("Could not encode JSON for localization table");
|
||||||
@@ -506,39 +587,6 @@ fn snapshot_csv_file<'source>(
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "PascalCase")]
|
|
||||||
struct LocalizationEntryCsv {
|
|
||||||
key: String,
|
|
||||||
context: String,
|
|
||||||
example: String,
|
|
||||||
source: String,
|
|
||||||
#[serde(flatten)]
|
|
||||||
values: HashMap<String, String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LocalizationEntryCsv {
|
|
||||||
fn to_json(self) -> LocalizationEntryJson {
|
|
||||||
LocalizationEntryJson {
|
|
||||||
key: self.key,
|
|
||||||
context: self.context,
|
|
||||||
example: self.example,
|
|
||||||
source: self.source,
|
|
||||||
values: self.values,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
struct LocalizationEntryJson {
|
|
||||||
key: String,
|
|
||||||
context: String,
|
|
||||||
example: String,
|
|
||||||
source: String,
|
|
||||||
values: HashMap<String, String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn snapshot_json_model_file<'source>(
|
fn snapshot_json_model_file<'source>(
|
||||||
file: &'source ImfsFile,
|
file: &'source ImfsFile,
|
||||||
) -> SnapshotResult<'source> {
|
) -> SnapshotResult<'source> {
|
||||||
@@ -554,7 +602,7 @@ fn snapshot_json_model_file<'source>(
|
|||||||
path: file.path.to_owned(),
|
path: file.path.to_owned(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut snapshot = json_instance.into_snapshot();
|
let mut snapshot = json_instance.into_snapshot()?;
|
||||||
snapshot.metadata.source_path = Some(file.path.to_owned());
|
snapshot.metadata.source_path = Some(file.path.to_owned());
|
||||||
|
|
||||||
Ok(Some(snapshot))
|
Ok(Some(snapshot))
|
||||||
@@ -570,23 +618,31 @@ struct JsonModelInstance {
|
|||||||
children: Vec<JsonModelInstance>,
|
children: Vec<JsonModelInstance>,
|
||||||
|
|
||||||
#[serde(default = "HashMap::new", skip_serializing_if = "HashMap::is_empty")]
|
#[serde(default = "HashMap::new", skip_serializing_if = "HashMap::is_empty")]
|
||||||
properties: HashMap<String, RbxValue>,
|
properties: HashMap<String, UnresolvedRbxValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsonModelInstance {
|
impl JsonModelInstance {
|
||||||
fn into_snapshot(mut self) -> RbxSnapshotInstance<'static> {
|
fn into_snapshot(self) -> Result<RbxSnapshotInstance<'static>, SnapshotError> {
|
||||||
let children = self.children
|
let mut children = Vec::with_capacity(self.children.len());
|
||||||
.drain(..)
|
|
||||||
.map(JsonModelInstance::into_snapshot)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
RbxSnapshotInstance {
|
for child in self.children {
|
||||||
|
children.push(child.into_snapshot()?);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut properties = HashMap::with_capacity(self.properties.len());
|
||||||
|
|
||||||
|
for (key, value) in self.properties {
|
||||||
|
let resolved_value = try_resolve_value(&self.class_name, &key, &value)?;
|
||||||
|
properties.insert(key, resolved_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(RbxSnapshotInstance {
|
||||||
name: Cow::Owned(self.name),
|
name: Cow::Owned(self.name),
|
||||||
class_name: Cow::Owned(self.class_name),
|
class_name: Cow::Owned(self.class_name),
|
||||||
properties: self.properties,
|
properties,
|
||||||
children,
|
children,
|
||||||
metadata: Default::default(),
|
metadata: Default::default(),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,20 +653,16 @@ fn snapshot_xml_model_file<'source>(
|
|||||||
.file_stem().expect("Could not extract file stem")
|
.file_stem().expect("Could not extract file stem")
|
||||||
.to_str().expect("Could not convert path to UTF-8");
|
.to_str().expect("Could not convert path to UTF-8");
|
||||||
|
|
||||||
let mut temp_tree = RbxTree::new(RbxInstanceProperties {
|
let options = rbx_xml::DecodeOptions::new()
|
||||||
name: "Temp".to_owned(),
|
.property_behavior(rbx_xml::DecodePropertyBehavior::ReadUnknown);
|
||||||
class_name: "Folder".to_owned(),
|
|
||||||
properties: HashMap::new(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let root_id = temp_tree.get_root_id();
|
let temp_tree = rbx_xml::from_reader(file.contents.as_slice(), options)
|
||||||
rbx_xml::decode(&mut temp_tree, root_id, file.contents.as_slice())
|
|
||||||
.map_err(|inner| SnapshotError::XmlModelDecodeError {
|
.map_err(|inner| SnapshotError::XmlModelDecodeError {
|
||||||
inner,
|
inner,
|
||||||
path: file.path.clone(),
|
path: file.path.clone(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let root_instance = temp_tree.get_instance(root_id).unwrap();
|
let root_instance = temp_tree.get_instance(temp_tree.get_root_id()).unwrap();
|
||||||
let children = root_instance.get_children_ids();
|
let children = root_instance.get_children_ids();
|
||||||
|
|
||||||
match children.len() {
|
match children.len() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use serde_derive::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use rbx_dom_weak::{RbxTree, RbxId, RbxInstanceProperties, RbxValue};
|
use rbx_dom_weak::{RbxTree, RbxId, RbxInstanceProperties, RbxValue};
|
||||||
use serde_derive::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
path_map::PathMap,
|
path_map::PathMap,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use hyper::{
|
|||||||
Request,
|
Request,
|
||||||
Response,
|
Response,
|
||||||
};
|
};
|
||||||
use serde_derive::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use rbx_dom_weak::{RbxId, RbxInstance};
|
use rbx_dom_weak::{RbxId, RbxInstance};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ macro_rules! generate_snapshot_tests {
|
|||||||
|
|
||||||
generate_snapshot_tests!(
|
generate_snapshot_tests!(
|
||||||
empty,
|
empty,
|
||||||
|
json_model,
|
||||||
|
localization,
|
||||||
multi_partition_game,
|
multi_partition_game,
|
||||||
nested_partitions,
|
nested_partitions,
|
||||||
single_partition_game,
|
single_partition_game,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use log::error;
|
use log::error;
|
||||||
use serde_derive::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use rbx_dom_weak::{RbxId, RbxTree};
|
use rbx_dom_weak::{RbxId, RbxTree};
|
||||||
|
|
||||||
use librojo::{
|
use librojo::{
|
||||||
|
|||||||
6
test-projects/json_model/default.project.json
Normal file
6
test-projects/json_model/default.project.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "json_model",
|
||||||
|
"tree": {
|
||||||
|
"$path": "src"
|
||||||
|
}
|
||||||
|
}
|
||||||
76
test-projects/json_model/expected-snapshot.json
Normal file
76
test-projects/json_model/expected-snapshot.json
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"name": "json_model",
|
||||||
|
"class_name": "Folder",
|
||||||
|
"properties": {},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"name": "children",
|
||||||
|
"class_name": "Folder",
|
||||||
|
"properties": {},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"name": "The Child",
|
||||||
|
"class_name": "StringValue",
|
||||||
|
"properties": {},
|
||||||
|
"children": [],
|
||||||
|
"metadata": {
|
||||||
|
"ignore_unknown_instances": false,
|
||||||
|
"source_path": null,
|
||||||
|
"project_definition": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"ignore_unknown_instances": false,
|
||||||
|
"source_path": "src/children.model.json",
|
||||||
|
"project_definition": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "explicit",
|
||||||
|
"class_name": "StringValue",
|
||||||
|
"properties": {
|
||||||
|
"Value": {
|
||||||
|
"Type": "String",
|
||||||
|
"Value": "Hello, world!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [],
|
||||||
|
"metadata": {
|
||||||
|
"ignore_unknown_instances": false,
|
||||||
|
"source_path": "src/explicit.model.json",
|
||||||
|
"project_definition": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "implicit",
|
||||||
|
"class_name": "StringValue",
|
||||||
|
"properties": {
|
||||||
|
"Value": {
|
||||||
|
"Type": "String",
|
||||||
|
"Value": "What's happenin', Earth?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [],
|
||||||
|
"metadata": {
|
||||||
|
"ignore_unknown_instances": false,
|
||||||
|
"source_path": "src/implicit.model.json",
|
||||||
|
"project_definition": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"ignore_unknown_instances": false,
|
||||||
|
"source_path": "src",
|
||||||
|
"project_definition": [
|
||||||
|
"json_model",
|
||||||
|
{
|
||||||
|
"class_name": null,
|
||||||
|
"children": {},
|
||||||
|
"properties": {},
|
||||||
|
"ignore_unknown_instances": null,
|
||||||
|
"path": "src"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
10
test-projects/json_model/src/children.model.json
Normal file
10
test-projects/json_model/src/children.model.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"Name": "children",
|
||||||
|
"ClassName": "Folder",
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"Name": "The Child",
|
||||||
|
"ClassName": "StringValue"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
11
test-projects/json_model/src/explicit.model.json
Normal file
11
test-projects/json_model/src/explicit.model.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"Name": "explicit",
|
||||||
|
"ClassName": "StringValue",
|
||||||
|
"Properties": {
|
||||||
|
"Value": {
|
||||||
|
"Type": "String",
|
||||||
|
"Value": "Hello, world!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Children": []
|
||||||
|
}
|
||||||
7
test-projects/json_model/src/implicit.model.json
Normal file
7
test-projects/json_model/src/implicit.model.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"Name": "implicit",
|
||||||
|
"ClassName": "StringValue",
|
||||||
|
"Properties": {
|
||||||
|
"Value": "What's happenin', Earth?"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
test-projects/localization/default.project.json
Normal file
6
test-projects/localization/default.project.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "localization",
|
||||||
|
"tree": {
|
||||||
|
"$path": "src"
|
||||||
|
}
|
||||||
|
}
|
||||||
69
test-projects/localization/expected-snapshot.json
Normal file
69
test-projects/localization/expected-snapshot.json
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"name": "localization",
|
||||||
|
"class_name": "Folder",
|
||||||
|
"properties": {},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"name": "empty-column-bug-147",
|
||||||
|
"class_name": "LocalizationTable",
|
||||||
|
"properties": {
|
||||||
|
"Contents": {
|
||||||
|
"Type": "String",
|
||||||
|
"Value": "[{\"key\":\"Language.Name\",\"source\":\"English\",\"values\":{}},{\"key\":\"Language.Region\",\"source\":\"United States\",\"values\":{}},{\"key\":\"Label.Thickness\",\"source\":\"Thickness\",\"values\":{}},{\"key\":\"Label.Opacity\",\"source\":\"Opacity\",\"values\":{}},{\"key\":\"Toolbar.Undo\",\"source\":\"Undo\",\"values\":{}},{\"key\":\"Toolbar.Redo\",\"source\":\"Redo\",\"values\":{}},{\"key\":\"Toolbar.Camera\",\"source\":\"Top-down camera\",\"values\":{}},{\"key\":\"Toolbar.Saves\",\"source\":\"Saved drawings\",\"values\":{}},{\"key\":\"Toolbar.Preferences\",\"source\":\"Settings\",\"values\":{}},{\"key\":\"Toolbar.Mode.Vector\",\"source\":\"Vector mode\",\"values\":{}},{\"key\":\"Toolbar.Mode.Pixel\",\"source\":\"Pixel mode\",\"values\":{}}]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [],
|
||||||
|
"metadata": {
|
||||||
|
"ignore_unknown_instances": false,
|
||||||
|
"source_path": "src/empty-column-bug-147.csv",
|
||||||
|
"project_definition": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "integers-bug-145",
|
||||||
|
"class_name": "LocalizationTable",
|
||||||
|
"properties": {
|
||||||
|
"Contents": {
|
||||||
|
"Type": "String",
|
||||||
|
"Value": "[{\"key\":\"Count\",\"example\":\"A number demonstrating issue 145\",\"source\":\"3\",\"values\":{\"es\":\"7\"}}]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [],
|
||||||
|
"metadata": {
|
||||||
|
"ignore_unknown_instances": false,
|
||||||
|
"source_path": "src/integers-bug-145.csv",
|
||||||
|
"project_definition": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "normal",
|
||||||
|
"class_name": "LocalizationTable",
|
||||||
|
"properties": {
|
||||||
|
"Contents": {
|
||||||
|
"Type": "String",
|
||||||
|
"Value": "[{\"key\":\"Ack\",\"example\":\"An exclamation of despair\",\"source\":\"Ack!\",\"values\":{\"es\":\"¡Ay!\"}}]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [],
|
||||||
|
"metadata": {
|
||||||
|
"ignore_unknown_instances": false,
|
||||||
|
"source_path": "src/normal.csv",
|
||||||
|
"project_definition": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"ignore_unknown_instances": false,
|
||||||
|
"source_path": "src",
|
||||||
|
"project_definition": [
|
||||||
|
"localization",
|
||||||
|
{
|
||||||
|
"class_name": null,
|
||||||
|
"children": {},
|
||||||
|
"properties": {},
|
||||||
|
"ignore_unknown_instances": null,
|
||||||
|
"path": "src"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
17
test-projects/localization/src/empty-column-bug-147.csv
Normal file
17
test-projects/localization/src/empty-column-bug-147.csv
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
,Key,Source,Context,Example
|
||||||
|
,,,,
|
||||||
|
Metadata,Language.Name,English,,
|
||||||
|
,Language.Region,United States,,
|
||||||
|
,,,,
|
||||||
|
Options,Label.Thickness,Thickness,,
|
||||||
|
,Label.Opacity,Opacity,,
|
||||||
|
,,,,
|
||||||
|
Toolbar,Toolbar.Undo,Undo,,
|
||||||
|
,Toolbar.Redo,Redo,,
|
||||||
|
,,,,
|
||||||
|
,Toolbar.Camera,Top-down camera,,
|
||||||
|
,Toolbar.Saves,Saved drawings,,
|
||||||
|
,Toolbar.Preferences,Settings,,
|
||||||
|
,,,,
|
||||||
|
,Toolbar.Mode.Vector,Vector mode,,
|
||||||
|
,Toolbar.Mode.Pixel,Pixel mode,,
|
||||||
|
2
test-projects/localization/src/integers-bug-145.csv
Normal file
2
test-projects/localization/src/integers-bug-145.csv
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Key,Source,Context,Example,es
|
||||||
|
Count,3,,A number demonstrating issue 145,7
|
||||||
|
2
test-projects/localization/src/normal.csv
Normal file
2
test-projects/localization/src/normal.csv
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Key,Source,Context,Example,es
|
||||||
|
Ack,Ack!,,An exclamation of despair,¡Ay!
|
||||||
|
411
test-projects/terrain/Terrain.rbxmx
Normal file
411
test-projects/terrain/Terrain.rbxmx
Normal file
@@ -0,0 +1,411 @@
|
|||||||
|
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
|
||||||
|
<Meta name="ExplicitAutoJoints">true</Meta>
|
||||||
|
<External>null</External>
|
||||||
|
<External>nil</External>
|
||||||
|
<Item class="Terrain" referent="RBX6DE6533CDF9645EFB1BBC5A35FCAD7A2">
|
||||||
|
<Properties>
|
||||||
|
<bool name="Anchored">true</bool>
|
||||||
|
<float name="BackParamA">-0.5</float>
|
||||||
|
<float name="BackParamB">0.5</float>
|
||||||
|
<token name="BackSurface">0</token>
|
||||||
|
<token name="BackSurfaceInput">0</token>
|
||||||
|
<float name="BottomParamA">-0.5</float>
|
||||||
|
<float name="BottomParamB">0.5</float>
|
||||||
|
<token name="BottomSurface">4</token>
|
||||||
|
<token name="BottomSurfaceInput">0</token>
|
||||||
|
<CoordinateFrame name="CFrame">
|
||||||
|
<X>0</X>
|
||||||
|
<Y>0</Y>
|
||||||
|
<Z>0</Z>
|
||||||
|
<R00>1</R00>
|
||||||
|
<R01>0</R01>
|
||||||
|
<R02>0</R02>
|
||||||
|
<R10>0</R10>
|
||||||
|
<R11>1</R11>
|
||||||
|
<R12>0</R12>
|
||||||
|
<R20>0</R20>
|
||||||
|
<R21>0</R21>
|
||||||
|
<R22>1</R22>
|
||||||
|
</CoordinateFrame>
|
||||||
|
<bool name="CanCollide">true</bool>
|
||||||
|
<bool name="CastShadow">true</bool>
|
||||||
|
<int name="CollisionGroupId">0</int>
|
||||||
|
<Color3uint8 name="Color3uint8">4288914085</Color3uint8>
|
||||||
|
<PhysicalProperties name="CustomPhysicalProperties">
|
||||||
|
<CustomPhysics>false</CustomPhysics>
|
||||||
|
</PhysicalProperties>
|
||||||
|
<float name="FrontParamA">-0.5</float>
|
||||||
|
<float name="FrontParamB">0.5</float>
|
||||||
|
<token name="FrontSurface">0</token>
|
||||||
|
<token name="FrontSurfaceInput">0</token>
|
||||||
|
<float name="LeftParamA">-0.5</float>
|
||||||
|
<float name="LeftParamB">0.5</float>
|
||||||
|
<token name="LeftSurface">0</token>
|
||||||
|
<token name="LeftSurfaceInput">0</token>
|
||||||
|
<bool name="Locked">true</bool>
|
||||||
|
<bool name="Massless">false</bool>
|
||||||
|
<token name="Material">256</token>
|
||||||
|
<BinaryString name="MaterialColors"><![CDATA[AAAAAAAAan8/P39rf2Y/ilY+j35fi21PZmxvZbDqw8faiVpHOi4kHh4lZlw76JxKc3trhHta
|
||||||
|
gcLgc4RKxr21zq2UlJSM]]></BinaryString>
|
||||||
|
<string name="Name">Terrain</string>
|
||||||
|
<BinaryString name="PhysicsGrid"><![CDATA[AgMAAADC//8A//8A//8A/P8DAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAD/AAD/AAD/AAH9AAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAP//AP//AP//Af/4
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAD/AAD/AAD/AAH4AAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAP//AP//AP//Af/4AAAAAAAAAAAAAAAB
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAD/AAD/AAD/AAH4AAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAABAP//AP//AP//Af/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAD/AAD/AAD/AAH4AAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAP//AP//AP//Af/4AAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAB
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAABAAD/AAD/AAD/AAH4AAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAB
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAABAP//AP//AP//Af/8AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAD/AAD/AAD/AAH9AAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAP//AP//AP//Af/5AAAAAAAAAAAAAAAB
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AAD/AAD/AAD/AAH5AAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAP//AP//AP//Af/5AAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAAAAAD/AAD/AAD/AAH5AAAAAAAAAAAAAAABAAAAAAAAAAAAAAAB
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AP//AP//AP//Af/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAABAAAAAAAAAAAAAAAAAAD/AAD/AAD/AAH+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAP//AP//AP//Af/+AAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA
|
||||||
|
AAD/AAD/AAD/AAH+AAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAP//AP//
|
||||||
|
AP//Af/+AAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAD/AAD/AAD/AAH+AAAAAAAAAAAAAAAB
|
||||||
|
AAAAAAAAAAAAAAABAAAAAAAAAAA=]]></BinaryString>
|
||||||
|
<float name="Reflectance">0</float>
|
||||||
|
<float name="RightParamA">-0.5</float>
|
||||||
|
<float name="RightParamB">0.5</float>
|
||||||
|
<token name="RightSurface">0</token>
|
||||||
|
<token name="RightSurfaceInput">0</token>
|
||||||
|
<int name="RootPriority">0</int>
|
||||||
|
<Vector3 name="RotVelocity">
|
||||||
|
<X>0</X>
|
||||||
|
<Y>0</Y>
|
||||||
|
<Z>0</Z>
|
||||||
|
</Vector3>
|
||||||
|
<BinaryString name="SmoothGrid"><![CDATA[AQX///////////////+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4DMQqFCrYAdQuVC80KigA5CgoAM
|
||||||
|
Qs5C60KpgA1CgULggAxC00LxQq6ADUKDQuKADELPQvxCx4AOQt6ADEK+QvpC1IAOQsuADEKk
|
||||||
|
QutC1IAOQqyADEKlQu5C14AOQqmADEKbQvJC60KIgA1CmoAMQoZC6kLyQpyA/4D/gLtCukLH
|
||||||
|
gBxC8oICgA5CgYALggNCsIAMQtoCgAuCA0LFgAyCAYALggNCzoALQoCCAYALggNC9IAMggGA
|
||||||
|
C0LlggOADIIBgAtCyIIDgAxC3QKAC0K7ggOADELFAoALQqOCA0KCgAtCoQKAC0KAggNCpIAM
|
||||||
|
AoD/gP+Aq0KtggFC1YAaQomCA0LJgA1C3YAKQsyCBIAMggGACkKzggSAC0LZggGACkKeggSA
|
||||||
|
C0LcggGAC4IEgAtCroIBgAuCBEKOgAuCAYALggRCq4ALggGAC4IEQryAC4IBgAuCBELegAuC
|
||||||
|
AYALQtyCBIALQs0CAAAAAAAAAAAAAAABgP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4ANQtdC7EKhgBxC2ELs
|
||||||
|
QqKAHELYQvpCuoAcQs5C+0LHgBxCt0LwQsmAHEK2Qu9CyIAcQrNC+ELdgBxCpUL1QueAHEKV
|
||||||
|
QudC3IAcQpdC6kLfgBxCnELzQuxCiIAbQpRC7ULpQomAG0KDQttC2IAcQo9C7ELrQo6AG0Ki
|
||||||
|
QvRC50KAgBtCoULnQs6AHEKsQvJC2YAcQsBC/ELWgBxCuULkQrCAHELMQvhCw4AcQsRC+ULR
|
||||||
|
gBxCt0L7QuCAHEKUQt1CyYDhSISAHUjYSOhIoYAbSIBI50j0SNeAF4IDQrWADAKADIIDQruA
|
||||||
|
DAKADIIDQtuADELogAyCA0L1gAxCvYAMQuGCA4AMQpSADELdggOAGkLOggNChgBCjEKKAEKR
|
||||||
|
QoKAAkKGQoKADkKzggNC6ULYQu5C6kLcQvBC6ELRQuBC6ELsQulC5ULXgAxCn4IDQvBC30L0
|
||||||
|
Qu5C4ELzQvRC5UL1QvhC90L1QvJC5IAMQqKCA0KZQopCm0KUQohCl0KhQptCqkKowqIBQqBC
|
||||||
|
k4AMQqSCA0KCgBlCmIIDQoaAGUKIggOAGkKRggNCj4AZQq+CA4AaQrmCA4AaQsSCA4AaQuaC
|
||||||
|
A4AaQu+CAkLpgBqCA0LvgBpC8YIDgBpC1IIDgBpCqIIDgBtC3IIBQqGAvkjEiAFI+IAbiANI
|
||||||
|
woARSJqAB4gESImAFEK+ggSAC0KoAoALQrKCBIALQocCgAtCnIIEgAwCgAyCBIAMAoAMggRC
|
||||||
|
gYALQvOADIIEQo8AQodChgBCj4AGQteADIISgAyCEoAMghKADIISgAyCBELeQpFCoEKYQotC
|
||||||
|
mUKrQq5CvkK3QqxCrUKsQp+ADEL3ggNC44AZQuSCA0LYgBlC74IDQuyAGYIEQtCAGYIEQrCA
|
||||||
|
GYIEQqqAGYIEQpGAGYIEgBqCBIAaggRCjoAZggRCuoAZggRCpIAZQpSCA4AcQrNCoICASMRI
|
||||||
|
2UiTgBuIA0iwgBlIxogEgBBIu0j5SNaABUjRiARI5oAIAAAAAAAAAAAAAAABgP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4AHSJaACEjnSPVI9Ei3gBBIv0jwSM6ABkiKSN1I1UjxSOlIhYAPSM1I90j6SLeA
|
||||||
|
BUiZSO9I5kjXSPRIyYAPSLZI5Uj6SNyABUitSPdI4ki1SOpI6EidgA5Iwkj6SOtI9EiegARI
|
||||||
|
vEj7SNkASNtI7kjNgA5Iz0j8SMdI9kjdgARIz0j4SL8ASKRI80jiSLSADUjZSPtIu0jfSO9I
|
||||||
|
toADSNdI6EisgAFIuEj6SNtIloAMSN1I6kiZSMlI8EjXSIKAAkjbSO1In4ABSIVIxkj8SM+A
|
||||||
|
DEjbSOhIl0iHSOpI8EitgAFIm0jzSOxIioACSKRI10j6SLuACkicSPNI7EiIAEi3SPtI3IAB
|
||||||
|
SLBI8kjUgARIuUjjSPNIuYAJSJZI6kjggAFIi0jYSPhItwBIxUj6SMyABUjMSPZI6Ui4gAhI
|
||||||
|
k0jmSNyAAkjASONI4EiCSNZI/Ei/gAZIxUj5SOZIrYAHSKJI9UjpSIKAAUiNSOdI5Ei1SNlI
|
||||||
|
8kirgAdI4Uj8SOlIn4AGSJhI6EjZgANIv0j6SOFI7EjwSKCAB0ieSOFI70ilgAZInEjsSN2A
|
||||||
|
A0iDSOBI8Uj3SOWACUiESJeACEiSSIWABEioSO5I+kjXgBxItUjbSLuA/4DzSIyIAkixgAWI
|
||||||
|
BEj8gA5I+IgDSJmAA0iTiAVIqoANiARI6IADSKKIBoANSOaIBIADSMKIBkivgAxI64gESNyA
|
||||||
|
AkjeiAeADIgGSIGAAYgDSOyIA0j3gAuIBkjdgAGIA0jTiARIyIADSIKABYgHSIgAiANIsEih
|
||||||
|
iARInYACSKuABYgHSPBIoogDSIUASM+IBEiBgAEIgARIpIgDSP6IA0jNiAOAAkj5iASAAQiA
|
||||||
|
BEifiANIp4gDSPOIA4ACSH+IBEjxAEi6gARInIgDAIgHSOeAA0iniARI+UiTgARIrogDAEiR
|
||||||
|
iAZIw4AESKSIBEizgARIp4gDgAFI74gFSLiABUjdiANIuYAESKqIA4ABSKaIBYAHSOiIAoAG
|
||||||
|
iAJI04ACSOGIBIAISItInoAISJZIiYAEiANI+4AbSPOIAUiCgP+A0kjqiAOABEjOiAVIloAN
|
||||||
|
iARI+IADSPGIBoAMSIOIBYADiAdIqoAMiAVI1IACiAiADIgGgAKICEjOgAuIBkjdAEiGiAlI
|
||||||
|
kIADSIaABEiciAcASLiICoADSN6ABEjGiAdI5UjTiApI/YACCIAESNqIDUjhAIgFSN0ASIII
|
||||||
|
gASIDkiwAEitiAVI2QAIgASIDkiVgAFI24gFSMAIgARI/IgDSMuICIADiAZI8oAEiARI00jv
|
||||||
|
iAeABIgGgASIBEi/SJWIB4AFiAWABIgESMIAiAZI2oAFSKWIA0jAgARIrogDgAKIBUiZgAdI
|
||||||
|
6Ej+SLKABkikSPVI5oADSMSIBIAaSNGIAkjegBxIpUiGgP+ArQAA/wAA/wAA/wAB/oD/gP+A
|
||||||
|
q0KuggFC1oAaQoqCA0LKgA1C3oAKQsyCBIAMggGACkK0ggSAC0LaggGACkKfggSAC0LdggGA
|
||||||
|
CkKAggSAC0KvggGAC4IEQo+AC4IBgAuCBEKrgAuCAYALggRCvYALggGAC4IEQt+AC4IBgAtC
|
||||||
|
3YIEgAtCzgKA/4D/gKxCvELJgBxC9YICgA5Cg4ALggNCsoAMQt0CgAuCA0LIgAtCgIIBgAuC
|
||||||
|
A0LRgAtCgoIBgAuCA0L2gAyCAYALQueCA4AMggGAC0LLggOADELgAoALQr6CA4AMQsgCgAtC
|
||||||
|
poIDQoSAC0KkAoALQoOCA0KmgAwCgP+A/4DMQqVCsoAcQoFC6kL4QqaADkKGgAxC0kLwQq2A
|
||||||
|
DUKFQuWADELYQvVCsoANQodC54AMQtMCQsuADkLjgAxCwwJC2IAOQtCADEKoQu9C2YAOQrGA
|
||||||
|
DEKpQvNC3IAOQq6ADEKgQvdC70KMgA1CnoAMQopC70L3QqCADUKCgP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/wAAAAAAAAAAAAAAAYALQr6CBIALQqkCgAtCs4IEgAtCiAKAC0KdggSADAKADIIEgAwCgAyC
|
||||||
|
BEKCgAtC9IAMggRC20LKQuNC4kLUQuxC0UK7QrhCyULXQtJCy0LYgAyCEoAMghKADIISgAyC
|
||||||
|
EoAMggVC7gJC9kLnQveCBkL+gAxC+IIDQuSAGULlggNC2YAZQu+CA0LtgBmCBELRgBmCBEKx
|
||||||
|
gBmCBEKrgBmCBEKSgBmCBIAaggSAGoIEQo+AGYIEQruAGYIEQqWAGUKVggOAHEKzQqCAgEjF
|
||||||
|
SNpIlIAbiANIsYAZSMeIBIAQSLxI+kjXgAVI0ogESOeAFYIDQreADAKADIIDQr6ADAKADIID
|
||||||
|
Qt2ADELrgAyCA0L4gAxCwIAMQuSCA4AMQpeADELgggNC20LKQuNC4kLUQuxC0UK7QrhCyULX
|
||||||
|
QtJCy0K+gAxC0IIRgAxCtYIRgAxCooIRgAxCpYIRgAxCpoIEQu4CQvZC50L3ggZC/oAMQpqC
|
||||||
|
A0KJgBlCioIDQn+AGUKTggNCkYAZQrGCA4AaQryCA4AaQseCA4AaQuiCA4AaQvGCAkLsgBqC
|
||||||
|
A0LygBpC84IDgBpC1oIDgBpCqoIDgBtC3oIBQqSAoEiAgBxIx4gBSPuAG4gDSMSAEUidgAeI
|
||||||
|
BEiMgBZC20LwQqWAHELcQvFCpoAcQt0CQr6AHELSAkLLgBxCu0L1Qs2AHEK6QvRCzABCgABC
|
||||||
|
h0KGAEKPgBVCt0L9QuFC84INgA1CqUL6QuuCDoANQplC7ELggg6ADUKbQu9C44IOgA1CoEL4
|
||||||
|
QvBCjEKgQpFCoEKYQotCmUKrQq5CvkK3QqxCrUKsQp+ADUKYQvJC7kKNgBtCh0LfQtxCgYAb
|
||||||
|
QpPC8AFCkoAbQqZC+ULsQoSAG0KlQutC0oAcQrBC90LdgBxCxAJC2oAcQr1C6EK0gBxC0EL9
|
||||||
|
QseAHELIQv5C1YAcQrsCQuWAHEKZQuJCzoDhSIiAHUjcSO1IpYAbSIRI7Ej5SNuA3EKGAEKM
|
||||||
|
QooAQpFCgoACQoZCgoASQptC6ULYQu5C6kLcQvBC6ELRQuBC6ELsQulC5ELXgBBCokLwQt9C
|
||||||
|
9ELuQuBC80L0QuVC9UL4QvdC9ULyQuSAEUKZQopCm0KUQohCl0KhQptCqkKowqIBQqBCk4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4C/AAAAAAAAAAAAAAABgAVI64gDgARIz4gFSJeADYgESPmAA0jyiAaADEiE
|
||||||
|
iAWAA4gHSKuADIgFSNWAAogIgAyIBoACiAhIz4ALiAZI3gBIh4gJSJGAA0iHgARInYgHAEi5
|
||||||
|
iAqAA0jfgARIx4gHSOZI1IgKSP6AAgiABEjbiA1I4gCIBUjeAEiDCIAEiA5IsQBIrogFSNoA
|
||||||
|
CIAEiA5IloABSNyIBUjBCIAESP2IA0jMiAiAA4gGSPOABIgESNRI8IgHgASIBoAEiARIwEiW
|
||||||
|
iAeABYgFgASIBEjDAIgGSNuABUimiANIwYAESK+IA4ACiAVImoAHSOkISLOABkilSPZI54AD
|
||||||
|
SMWIBEiAgBlI0ogCSN+AHEimSIeA/4CzSI+IAkizgAWIBYAOSPuIA0icgANIlYgFSK2ADYgE
|
||||||
|
SOuAA0iliAaADUjpiASAA0jEiAZIsYAMSO6IBEjfgAJI4IgHgAyIBkiEgAGIA0jviANI+oAL
|
||||||
|
iAZI4IABiANI1ogESMuAA0iFgAWIB0iLAIgDSLNIo4gESKCAAkiugARIgYgHSPNIpIgDSIcA
|
||||||
|
SNKIBEiEgAEIgARIpogISNCIA4ACSPyIBEiAAAiABEiiiANIqYgDSPaIA4ACSIKIBEjzAEi+
|
||||||
|
gARIn4gDAIgHSOqAA0ipiARI/EiXgARIsYgDAEiTiAZIxoAESKeIBEi2gARIqYgDgAFI8YgF
|
||||||
|
SLuABUjfiANIvIAESK2IA4ABSKiIBUiBgAZI64gCgAaIAkjWgAJI5IgEgAhIjUiggAhImUiM
|
||||||
|
gASIA0j+gBtI9ogBSISA/4DUSJqAB0iDSOxI+kj5SLyAEEjDSPVI0kiCgAVIjkjiSNpI9kjt
|
||||||
|
SImAD0jSSPwISLuABUieSPRI60jcSPlIzYAPSLpI6ghI4YAFSLFI/EjmSLpI70jtSKGADkjG
|
||||||
|
CEjwSPlIooAESMAISN4ASOBI80jSgA5I0whIzEj7SOGABEjUSP1IxABIqUj4SOdIuIANSN4I
|
||||||
|
SMBI40j0SLqAA0jcSO1IsIABSLwISOBImoAMSOJI70idSM1I9UjcSIaAAkjgSPJIpIABSIlI
|
||||||
|
ywhI00iCgAtI4EjtSJxIjEjuSPVIsoABSJ9I+EjxSI6AAkioSNsISL+ACkigSPhI8EiMAEi8
|
||||||
|
CEjhgAFItEj3SNiABEi+SOhI+Ei9gAlImkjuSOVIgABIj0jcSP1IuwBIyghI0YAFSNBI+0jt
|
||||||
|
SL2ACEiXSOtI4YACSMRI6EjlSIZI2whIxIAGSMpI/kjqSLKAB0inSPpI7kiGgAFIkUjsSOlI
|
||||||
|
ukjeSPdIsIAGSIJI5QhI7UijgAZInUjtSN6AA0jDCEjmSPFI9UikgAdIokjmSPRIqYAGSKBI
|
||||||
|
8EjigANIh0jlSPZI/EjqSH+ACEiJSJuACEiWSImABEitSPMISNyAHEi6SOBIv4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4DtAP//AP//AP//Af/+gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+AlkKAQs5CwYAc
|
||||||
|
Qs9C9kLoQoCAGkKIQuxC80K7gAVChoAVQtBC2EKFgAVC5EKMgB1C50KTgB1C+EKygB1C+0LJ
|
||||||
|
gB1C70LSgB1C7ELQgB1C8ULqQoaAHELnQvZCpID/gP+Ak0K2AkL9QpKAGkKyggOAGoIEgARC
|
||||||
|
hYATQoKCBIAEAkLngBOCA0KOgASCAUKRgBJCsYIBQsmABYIBQqyAHIIBQsuAHIIBQvmAHIIC
|
||||||
|
gByCAoAcggJCgYAbggJCs4D/gP+Ac0KIgB2CAkLwgBqCBEKqgBhCsoIEQs+AA0LhQomAEkLe
|
||||||
|
ggRCmIADggFCj4ARQsGCA0LrgASCAULvgBKCA4AFggKAE0KjQquABoICgByCAoAcggJCnoAb
|
||||||
|
ggJCwoAbggJC3YAbggOAGwAAAAAAAAAAAAAAAYD/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP9Cz0LzQraAHELH
|
||||||
|
QupCuoAcQr9C+ELQgBxCqkL3QuSAFEKiQp6ABUKJQuhC60KQgBJClELtQulCiIAFQtpC4kKc
|
||||||
|
gBJCl0LlQtaABkLbQvRCrIASQp5C7ULegAZCzkL8QsiAEkKyQvhC3oAGQrRC9kLXgBJCvUL6
|
||||||
|
QtWABkKiQuhC3YASQsFC80LEgAZClkLoQt5CiIARQrtC7EK+gAZCg0LnQu9CmoARQtBC+EK+
|
||||||
|
gAdC3UL6QrWAEULcQvpCtoAHQsxC/ELKgBFC00L2QriAB0K2QvhC2IARQsJC6EKwgAdCn0Lt
|
||||||
|
QuGAEULNQvVCvIAHQpNC5ELjQo6AEELOQvxCyIAHQoFC40LpQpyAEELGQvlCyoAIQttC9UKv
|
||||||
|
gBBCv0L2QsuACELOQvtCxoAQQrdC8kLMgAhCvUL7QtmAEEK0QvNC0YAIQpRC0EKvgBBCsUL0
|
||||||
|
QtaAHEKlQvJC6UKEgBxCsEKngGFItkimgBxIpkj1SORIgoAbSMdI90j5SMSAA0iJSKhIvUjF
|
||||||
|
SLZIn0iLgBBIy0jkSPNI6UiNgAJI3kj1SPtI/Ej3SN5I6kjgSM9IsEiVgAtIhkjdSPNI2Ej7
|
||||||
|
SLyAAkjXSOdI10jQSNhI1kjtSPhI+0j3SOlI10ifgAlIp0jtSOdIrEjtSPCCAkLZgBuCAkLz
|
||||||
|
gBuCA4ATQrZCsoAFggOAEoICQvqABIIDQpOAEEKZggNChYADggNCs4AQQqaCA4AEggNCx4AQ
|
||||||
|
Qq2CA4AEggNC94AQQsuCA4AEQvaCA4AQQuKCA4AEQsCCA4AQQvCCAkL3gARCoYIDQpGAD0L1
|
||||||
|
ggJC8YAFggNCrIAPggNC5oAFggNC0YAPggNC1IAFggNC+oAPggNC2oAFQtWCA4APggNC14AF
|
||||||
|
QryCA4APggNC5IAFQp6CA0KVgA6CA0L2gAaCA0K0gA5C9YICQv6ABoIDQs+ADkLqggOABoID
|
||||||
|
QvSADkLdggOABkLhggOADkLXggOABkKzggJC74AOQs+CA4AHQscCQuWAD0LCggOAG4IDgBxC
|
||||||
|
zULEgCBIi0jXSMaAHIgCSPaAGki3iANIq4ACSJBIu0jhSPFI1Ui9SIqAD0j4iASAAUjYiAhI
|
||||||
|
3EitgAuIBYABiAxIy4AISIyIBYABiA6AB0jIiAWCA4AbggOAG4IDQpCAEUK7ggFCr4AEggNC
|
||||||
|
wYAQQq2CA0KYgAOCA0LygBBC+YIDQuKAA4IEgBCCBELOgAOCBIAQggRCwoADggRCl4APggRC
|
||||||
|
roADggRCq4APggRCk4ADggRCyoAPggSABIIEQu+AD4IEgARC14IEgA5CiIIEgARCqYIEgA5C
|
||||||
|
p4IEgAWCBIAOQpSCBIAFggRCn4ANQoSCBIAFggRCy4ANQoWCBIAFQv6CA0LzgA6CBIAFQteC
|
||||||
|
BIAOggSABUKsggSADoIEQn+ABYIEgA6CBEKIgAWCBEKbgA2CBEKTgAWCBIAOggRCvIAFQo2C
|
||||||
|
AkLFgA6CBELZgAdCgoAQQsKCA0KZgBpC14IBQr2AH0joiAFIuIAaSNiIA0iKgBmIBYABSIVI
|
||||||
|
74gESOhItUiBgA2IBYABiAtI0oAJSKSIBQBIxIgNSKWAB0jqiAUASL6IDkjEgAaIBgAAAAAA
|
||||||
|
AAAAAAAAAYD/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+AA0iDAEjUyOwBSJJIr0jGSN1I7Ej8SOtIqYAISL9I
|
||||||
|
9UjTAEjISPeABEjUSOdI7kikgANIm0jSSPJI24AISNNI90i5AEiYSNuAA0jTSOZI70ihgAVI
|
||||||
|
nMjpAUiNgAZIkEjpSPBImYABSN6AAkjRSOpI70ijgAZIgEjbSOdIpYAGSK1I9kjggAJIuIAB
|
||||||
|
SM5I7kjvSKmACEjVSPJIwIAGSOBI+UixgAJIlQBIy0jxSO5IroAJSL5I9EjXgAVIsUj2SNtI
|
||||||
|
iIAESMlI7EiygApIukj4SNSABUjYSOtIxIAESJ5I9EjqSIWACUiQSNJI+0jDgARIo0jhSOpI
|
||||||
|
n4AESMpI8ki5gAlImUjNSPpI0EicgARIvkj2SNaABUjESOtIv4AGSIJInkiuSNdI+UjaSKeA
|
||||||
|
BEiESOdI9UikgAVIqEj2SOSAAkiSSJ9Iu0jYSOZI7UjlSPdI2UidgAVIvkj6SNSABkiRSO1I
|
||||||
|
60iySMJI4EjqSOBI+Uj4SO5I3kjWSMxIhIAGSKBI2Ei0gAdI30j2SPhI90j5SOVI20jVSLdI
|
||||||
|
nkiJgBRIwkjqSN1IykiwSIiAGkiGgP+A/4A+SMOIDUjUgAZI/ogFgAJIuIgFSMZI84gFgAaI
|
||||||
|
A0jdiAGAAUi1iAWAA0jNiANIj4AESKWIA0igiAEASLGIBYAESICIA0jCgARI9ogDAEjbCEit
|
||||||
|
iAWABogDSPKAA0iHiANI6gBIs4gGgAdI74gDgANIzIgDSJ6AAYgFgAhI3YgDgAOIBIACSNeI
|
||||||
|
A4AISMKIA0j8gAJIwogDSLGAAkiFiAOABkitSNiIBEjDgAKIBIAEiAOAAUiXSMFI34gHSNOA
|
||||||
|
AkiniANIy4AEiANI9ogKSOiAA0jliANIgIAEiA5I3IAESMSIAkjwgAWIDUi4gAZI3ghI9YAG
|
||||||
|
iAhI10i9SJGAE0iSiANIyEiegBpIf4D/gP+AHogPgAVIgIgGgAKIDkiygARIxIgGgAGIBki9
|
||||||
|
gAFIr4gESO2ABIgHAIgGSLuAA0jciASAA0iDiARIuYgISMCABEigiASAA0jkiAQAiAdIx4AG
|
||||||
|
iARIooACiAUASLaIBUjOgAZIh4gESJWAAUi2iARIlIABiARI2YAGSJmIBYACiAWAAkjhiANI
|
||||||
|
pYADSJ1I14gHgAFIpogESLGAA4gDSJ9ItEj3iApInYABiAWABIgQSLWAAogESNyABIgPSKGA
|
||||||
|
A4gEgAWIDoAFSKaIAkjQgAWICkjwSLtIgIAISJyAB0jxiAVI00iVgBdIq0jbSK6A/4D/gBsA
|
||||||
|
AP8AAP8AAP8AAf6A/4D/gFdCiIAdggJC8YAaggRCq4AYQrKCBELQgANC4kKKgBJC34IEQpmA
|
||||||
|
A4IBQpCAEULCggNC7IAEggFC8IASggOABYICgBNCo0KrgAaCAoAcggKAHIICQp+AG4ICQsOA
|
||||||
|
G4ICQt6AG4IDgP+A/4CSQrmCAUKVgBpCtIIDgBqCBIAEQoeAE0KFggSABAJC6oATggNCkIAE
|
||||||
|
ggFClIASQrOCAULMgAWCAUKugByCAULOgByCAUL8gByCAoAcggKAHIICQoSAG4ICQrWA/4D/
|
||||||
|
gLJChELTQsaAHELUQvtC7UKEgBpCjELxQvhCv4AFQoqAFULUQt1CiYAFQulCkYAdQuxCmIAd
|
||||||
|
Qv1CtoAdAkLOgB1C9ELXgB1C8ULUgB1C9kLvQouAHELsQvtCqYD/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
HAAAAAAAAAAAAAAAAYIDgBuCA4AbggNCkYARQryCAUKwgASCA0LCgBBCroIDQpmAA4IDQvOA
|
||||||
|
EEL6ggNC44ADggSAEIIEQs+AA4IEQoOAD4IEQsSAA4IEQvWAD4IEQq+AA4IFgA+CBEKUgAOC
|
||||||
|
BELLgA+CBIAEggRC8IAPggSABELYggSADkKJggSABEKpggSADkKoggSABYIEgA5ClYIEgAWC
|
||||||
|
BEKggA1ChYIEgAWCBELMgA1ChoIEgAWCBEL0gA6CBIAFQtiCBIAOggSABUKtggSADoIEQoCA
|
||||||
|
BYIEgA6CBEKJgAWCBEKcgA2CBEKUgAWCBIAOggRCvYAFQo6CAkLGgA6CBELagAdCg4AQQsSC
|
||||||
|
A0KagBpC2IIBQr6AH0jqiAFIuYAaSNmIA0iLgBmIBYABSIZI8IgESOlItkiCgA2IBYABiAtI
|
||||||
|
1IAJSKWIBQBIxYgNSKaAB0jriAUASL+IDkjFgAaIBoICQtyAG4ICQveAG4IDgBNCuUK1gAWC
|
||||||
|
A4ASggJC/YAEggNCloAQQpyCA0KIgAOCA0K2gBBCqYIDgASCBEKDgA9CsIIDgASCBEL1gA9C
|
||||||
|
zoIDgASCBYAPQuWCA4AEggRCv4APQvSCAkL7gASCBEKTgA9C+YICQvSABYIDQq+AD4IDQuqA
|
||||||
|
BYIDQtSAD4IDQteABYIDQv2AD4IDQt6ABULYggOAD4IDQtuABUK/ggOAD4IDQueABUKhggNC
|
||||||
|
l4AOggNC+YAGggNCt4AOQvmCA4AGggNC0oAOQu2CA4AGggNC94AOQuCCA4AGQuSCA4AOQtqC
|
||||||
|
A4AGQraCAkLygA5C0oIDgAdCygJC6IAPQsWCA0KAgBqCA4AcQtBCx4AgSI5I2kjKgBtIf4gC
|
||||||
|
SPqAGki6iANIroACSJNIvkjlSPVI2UjASI2AD0j8iASAAUjbiAhI4EiwgAuIBYABiAxIzoAI
|
||||||
|
SI+IBYABiA6AB0jLiAVC1EL4QruAHELMQu9Cv4AcQsRC/kLVgBxCr0L9QumAFEKnQqOABUKO
|
||||||
|
Qu1C8EKVgBJCmULzQu5CjYAEQoJC30LnQqGAEkKcQutC3IAFggNC04ARQqNC80LjgAWCBEKX
|
||||||
|
gBBCt0L+QuSABYIEQquAEELDAkLbgAWCBIARQsZC+ELJgAVCp0KaQu5C40KNgBFCwELyQsOA
|
||||||
|
BkKHQuxC9UKegBFC1UL9QsOAB0LiAkK6gBFC4gJCu4AHQtECQs6AEULZQvxCvYAHQrtC/ULd
|
||||||
|
gBFCx0LuQrWAB0KjQvJC5kJ/gBBC0kL6QsGAB0KXQulC6EKSgBBC0wJCzYAHQoVC6ELvQqCA
|
||||||
|
EELLQv5Cz4AIQuBC+0K0gBBCxEL7QtGACELTAkLLgBBCvEL3QtGACELCAkLegBBCuUL5QtaA
|
||||||
|
CEKYQtRCtIAQQrZC+ULbgBxCqkL3Qu5CiYAcQrVCrIBhSLtIq4AcSKxI+0jqSIeAG0jMSP0I
|
||||||
|
SMmAA0iOSK5Iw0jLSLtIpEiRgBBI0EjqSPlI70iSgAJI5Ej8iAFI/UjkSPFI5kjVSLVImoAL
|
||||||
|
SItI40j5SN4ISMGAAkjdSO1I3UjWSN1I3EjzSP4ISP1I70jcSKSACUisSPNI7UixSPNI9oC/
|
||||||
|
QonChQGAHELtwuQBQt5CjIAaQvZC6ML0AUKggBpCn0KOQqxCqoD/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4DbAAAA
|
||||||
|
AAAAAAAAAAABgAGID4AFSIGIBoACiA5ItIAESMWIBoABiAZIvoABSLCIBEjugASIBwCIBki8
|
||||||
|
gANI3YgEgANIhIgESLqICEjBgARIoYgEgANI5YgEAIgHSMiABogESKOAAogFAEi3iAVIz4AG
|
||||||
|
SIiIBEiWgAFIt4gESJWAAYgESNqABkiaiAVIgIABiAWAAkjiiANIpoADSJ9I2IgHgAFIp4gE
|
||||||
|
SLKAA4gDSKBItUj4iApInoABiAWABIgQSLeAAogESN2ABIgPSKKAA4gEgAWIDoAFSKeIAkjR
|
||||||
|
gAWICkjxSLxIgYAISJ2AB0jyiAVI1EiWgBdIrEjdSK+A/4D/gB1Ix4gNSNeABogGgAJIvIgF
|
||||||
|
SMpI94gFgAaIA0jgiAGAAUi5iAWAA0jQiANIkoAESKiIA0ijiAEASLWIBYAESIOIA0jFgARI
|
||||||
|
+ogDAEjfCEiwiAWABogDSPWAA0iKiANI7gBItogGgAdI84gDgANIz4gDSKKAAYgFgAhI4IgD
|
||||||
|
gAOIBIACSNqIA0iAgAdIxYgEgAJIxogDSLSAAkiIiAOABkiwSNyIBEjHgAKIBIAEiAOAAUib
|
||||||
|
SMVI44gHSNeAAkiqiANIzoAEiANI+ogKSOuAA0joiANIg4AEiA5I4IAESMeIAkjzgAWIDUi7
|
||||||
|
gAZI4ghI+IAGiAhI2kjASJSAE0iWiANIy0ihgBpIg4D/gP+AIEiIAEjayPIBSJhItUjMSONI
|
||||||
|
8ghI8UivgAhIxEj7SNkASM1I/YAESNpI7Uj0SKqAA0igSNdI+EjhgAhI2Uj9SL8ASJ1I4YAD
|
||||||
|
SNhI7Ej1SKeABUihyO8BSJKABkiVSO9I9kiegAFI5IACSNZI8Ej1SKiABkiFSOFI7kirgAZI
|
||||||
|
s0j8SOaAAki+gAFI1Ej0SPVIroAISNtI+EjGgAZI5ghItoACSJoASNFI90j0SLOACUjDSPpI
|
||||||
|
3YAFSLZI/EjgSI2ABEjOSPJIuIAKSL9I/kjagAVI3kjxSMmABEikSPpI8EiKgAlIlUjXCEjJ
|
||||||
|
gARIqEjnSPBIpIAESNBI+Ei/gAlInkjTCEjWSKGABEjDSPxI24AFSMpI8kjEgAZIh0ijSLNI
|
||||||
|
3QhI30itgARIiUjtSPtIqYAFSK5I/EjqgAJIl0ilSMFI3UjsSPNI60j9SN9IooAFSMQISNqA
|
||||||
|
BkiWSPNI8Ui4SMhI5kjwSOYISP5I9EjkSNxI0kiKgAZIpUjeSLmAB0jlSPxI/kj9CEjrSOFI
|
||||||
|
20i8SKRIjoAUSMdI8EjjSNBItkiNSIGAGUiLgP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+APAD//wD/
|
||||||
|
/wD//wH//4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+AZ0jJSNhIi4AbSIxI7Uj0SKyAG0iSSOVI
|
||||||
|
30jwSLWAGkibSOtI4EjuSOtIr4ASSJqABUilSPBI3EjOSPFI5kiogP+A/4D/gFhIoogBSM6A
|
||||||
|
G4gDSJqAGUiJiARIgYASSKyABEiciAWAEgiABEiqiAVI+4ARCEjegANIuIgGSNuA/4D/gP+A
|
||||||
|
OEiYSKaAHIgDSIOAGUi8iANI+oATSJ6ABEjmiARI3YASCIAESPuIBUjNgBEISL6AA4gHSLyA
|
||||||
|
EIgBgAOICEiDgA8AAAAAAAAAAAAAAAGA/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/SNyABUixSPNI1QBI00j0
|
||||||
|
SOBIhoAQSOJIl4AESLxI9UjMAEiISOZI7EjPgBBI8kimgARIz0jtSMCAAUisSO5I80i2gA9I
|
||||||
|
+kjagARI2UjuSKyAAkjFSOtI7UingA5I6kjzSJ2AAkiUSOhI60iRgANI00j4SN9In4ANSMpI
|
||||||
|
+0jKgAJIvEj7SNiABEiNSNFI/EjjSJuADEinSPJI6kiGgAFI3Ej3SLCABUibSNtI8kjpSKCA
|
||||||
|
DEjPSO9IvwBIpkjpSNtIl4AGSI1I20jxSOdIqIALSL9I8EjOAEi8SPFI1YAISIZI2Uj1SLaA
|
||||||
|
C0iFSOpI80i+SOdI9kilgAlIhUikgA1IuUj4SOVI8EjdgBtI3EjwSORI0YAbSIpI3kj8SMyA
|
||||||
|
HEifSM5IoYD/gP+AWIgBgANIz4gHSLKAD4gBSKqAAkjliAhIiYAOiAFI4oACiANI+kjtiASA
|
||||||
|
DogCgAKIA0jKAIgESO+ADYgCSMAASLWIA0iVAEibiARI7IAMiAMASN+IA4ACSLqIBEj4gAuI
|
||||||
|
A0iTiANI4YADSM2IBEj7gAqIA0jxiANIsIAESNWIBEjKgAlI8IgHgAZIz4gDSNiACUiTiAZI
|
||||||
|
woAHSMyIAkiKgAqIBkiDgAhIk0iygAxIlogFgBlI1IgEgBpI2YgCSNKAG0jRCEjTgP+A/4A4
|
||||||
|
iAFIqoACiAmAD4gCgAKICUjmgA6IAoABSJmICki3gA2IAkjKAEjViARIzIgFSKOADIgDAIgE
|
||||||
|
SPMASPuIBUiogAuIA0ihiARIpIABiAZIr4AKiANI8YgEgAJIgogGSL2ACYgJgANIm4gGgAmI
|
||||||
|
CEihgARIiIgFgAlI8ogHgAeIA0jngAlIoIgGSOCACEjyCEjUgAtI9YgFSLCAGIgFgBlIhIgE
|
||||||
|
gBpIoogCSKeA/4D/gDcAAP8AAP8AAP8AAf+A/4D/gP+AJ0iaSKiAHIgDSISAGUi9iANI+4AT
|
||||||
|
SJ+ABEjniARI3oASCIAESP2IBUjOgBEISL+AA4gHSL2AEIgBgAOICEiEgP+A/4D/gFZIpYgB
|
||||||
|
SNGAG4gDSJ2AGUiMiARIhIASSLCABEifiAWAEgiABEitiAaAEQhI4YADSLuIBkjegP+A/4D/
|
||||||
|
gHhIz0jeSJCAG0iRSPNI+kixgBtIl0jrSOVI9ki6gBpIoUjxSOVI80jxSLSAEkifgAVIqkj2
|
||||||
|
SOJI1Ej3SOxIrYD/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/
|
||||||
|
gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+AEQAAAAAAAAAAAAAAAYgBSKuAAogJgA+IAoAC
|
||||||
|
iAlI54AOiAKAAUiaiApIuIANiAJIzABI1ogESM2IBUikgAyIAwCIBEj1AEj8iAVIqYALiANI
|
||||||
|
oogESKWAAYgGSLCACogDSPKIBIACSIOIBki+gAmICYADSJyIBoAJiAhIooAESImIBYAJSPOI
|
||||||
|
B4AHiANI6YAJSKGIBkjhgAhI8whI1YALSPaIBUiygBiIBYAZSIWIBIAaSKOIAkipgP+A/4A3
|
||||||
|
iAGAA0jSiAdItoAPiAFIrYACSOiICEiMgA6IAUjlgAKIA0j+SPCIBIAOiAKAAogDSM0AiARI
|
||||||
|
84ANiAJIwwBIuIgDSJgASJ6IBEjwgAyIAwBI4ogDgAJIvogESPuAC4gDSJaIA0jlgANI0IgF
|
||||||
|
gAqIA0j1iANIs4AESNiIBEjNgAlI9IgHgAZI0ogDSNuACUiXiAZIxYAHSM+IAkiNgAqIBkiG
|
||||||
|
gAhIlki1gAxImYgFgBlI14gEgBpI3YgCSNWAG0jUCEjXgP+A/4A4SOGABUi2SPlI2gBI2Ej6
|
||||||
|
SOVIi4AQSOhInYAESMJI+0jSAEiNSOtI8kjVgBBI90irgARI1UjzSMWAAUixSPRI+Ui8gA8I
|
||||||
|
SN+AA0iASN5I9EiygAJIy0jxSPNIrIAOSPBI+UiigAJImUjuSPFIloADSNlI/kjlSKSADUjP
|
||||||
|
CEjQgAJIwQhI3oAESJJI1whI6UihgAxIrUj4SPBIi4ABSOJI/Ui2gAVIoEjhSPhI70ilgAtI
|
||||||
|
gUjVSPVIxQBIq0juSOFInIAGSJJI4Uj2SO1IroALSMVI9kjTSIFIwUj3SNqACEiMSN5I+ki7
|
||||||
|
gAtIikjvSPlIw0jsSPxIqoAJSIpIqYANSL5I/kjrSPZI44AbSOFI9kjpSNeAG0iPSOQISNKA
|
||||||
|
HEikSNNIpoD/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A
|
||||||
|
/4D/gP+A/4D/gP+A/4D/gP+A/4D/gP+A/4D/gFg=]]></BinaryString>
|
||||||
|
<BinaryString name="Tags"></BinaryString>
|
||||||
|
<float name="TopParamA">-0.5</float>
|
||||||
|
<float name="TopParamB">0.5</float>
|
||||||
|
<token name="TopSurface">3</token>
|
||||||
|
<token name="TopSurfaceInput">0</token>
|
||||||
|
<float name="Transparency">0</float>
|
||||||
|
<Vector3 name="Velocity">
|
||||||
|
<X>0</X>
|
||||||
|
<Y>0</Y>
|
||||||
|
<Z>0</Z>
|
||||||
|
</Vector3>
|
||||||
|
<Color3 name="WaterColor">
|
||||||
|
<R>0.0470588244</R>
|
||||||
|
<G>0.329411775</G>
|
||||||
|
<B>0.360784322</B>
|
||||||
|
</Color3>
|
||||||
|
<float name="WaterReflectance">1</float>
|
||||||
|
<float name="WaterTransparency">0.300000012</float>
|
||||||
|
<float name="WaterWaveSize">0.150000006</float>
|
||||||
|
<float name="WaterWaveSpeed">10</float>
|
||||||
|
<Vector3 name="size">
|
||||||
|
<X>2044</X>
|
||||||
|
<Y>252</Y>
|
||||||
|
<Z>2044</Z>
|
||||||
|
</Vector3>
|
||||||
|
</Properties>
|
||||||
|
</Item>
|
||||||
|
</roblox>
|
||||||
13
test-projects/terrain/default.project.json
Normal file
13
test-projects/terrain/default.project.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "terrain",
|
||||||
|
"tree": {
|
||||||
|
"$className": "DataModel",
|
||||||
|
"Workspace": {
|
||||||
|
"$className": "Workspace",
|
||||||
|
|
||||||
|
"Terrain": {
|
||||||
|
"$path": "Terrain.rbxmx"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user