• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EDT 13:29
CEST 19:29
KST 02:29
  • Home
  • Forum
  • Calendar
  • Streams
  • Liquipedia
  • Features
  • Store
  • EPT
  • TL+
  • StarCraft 2
  • Brood War
  • Smash
  • Heroes
  • Counter-Strike
  • Overwatch
  • Liquibet
  • Fantasy StarCraft
  • TLPD
  • StarCraft 2
  • Brood War
  • Blogs
Forum Sidebar
Events/Features
News
Featured News
ByuL, and the Limitations of Standard Play1Team Liquid Map Contest #22: Results and Winners7Code S Season 2 (2026): RO4 and Finals Preview12TL.net Map Contest #22 - Voting & Ladder Map Selection7Code S Season 2 (2026) - RO8 Preview8
Community News
[TLMC] Summer 2026 Ladder Map Rotation05.0.16 patch for SC2 goes live (8 worker start)68ZeroSpace at Steam NextFest - Last free demo31Weekly Cups (June 8-14): Clem and Solar double, PTR tested0RSL: S6 Finals played at BlizzCon 202611
StarCraft 2
General
5.0.16 patch for SC2 goes live (8 worker start) Is the larve respawn broken? The Death of Cheese: From a Professional Cheeser Mizenhauer's Douyu Cup Preview ByuL, and the Limitations of Standard Play
Tourneys
Douyu Cup 2026: $20,000 Legends Event (June 26-28) RSL Revival: Season 6 - Qualifiers and Main Event INu's Battles#17 <BO.9> Sparkling Tuna Cup - Weekly Open Tournament GSL CK #4 20-21th June
Strategy
[G] Having the right mentality to improve
Custom Maps
New Map Maker - Looking for Advice - Love or Hate Work In Progress Melee Maps [D]RTS in all its shapes and glory <3
External Content
The PondCast: SC2 News & Results Mutation # 531 Experimental Artillery Mutation # 530 One For All Mutation # 529 Opportunities Unleashed
Brood War
General
ASL 22 Proposed Map Pool BW General Discussion Farewell Beloved Starcraft (Youtube Videos) vespene.gg — BW replays in browser Quality of life changes in BW that you will like ?
Tourneys
[ASL21] Grand Finals [Megathread] Daily Proleagues The Casual Games of the Week Thread [BSL22] GosuLeague Casts - Tue & Thu 22:00 CEST
Strategy
Creating a full chart of Zerg builds Relatively freeroll strategies Why doesn't anyone use restoration? Simple Questions, Simple Answers
Other Games
General Games
Path of Exile Stormgate/Frost Giant Megathread Beyond All Reason Nintendo Switch Thread ZeroSpace at Steam NextFest - Last free demo
Dota 2
Looking for a Dota Mentor Official 'what is Dota anymore' discussion
League of Legends
Heroes of the Storm
Simple Questions, Simple Answers Heroes of the Storm 2.0
Hearthstone
Deck construction bug
TL Mafia
TL Mafia Community Thread Vanilla Mini Mafia
Community
General
US Politics Mega-thread Canadian Politics Mega-thread Things Aren’t Peaceful in Palestine Russo-Ukrainian War Thread [H]Internet/Gaming Cafe Tips and Tricks
Fan Clubs
The HerO Fan Club! The herO Fan Club!
Media & Entertainment
Movie Discussion! Series you have seen recently... [Req][Books] Good Fantasy/SciFi books [TV/BOOK] *SPOILERS* Game of Thrones Discussion
Sports
2024 - 2026 Football Thread TeamLiquid Health and Fitness Initiative For 2023 McBoner: A hockey love story Formula 1 Discussion Cricket [SPORT]
World Cup 2022
Tech Support
Computer Build, Upgrade & Buying Resource Thread Facing Challenges in Mobile App Development
TL Community
The Automated Ban List
Blogs
Listen To The Coaches!
TrAiDoS
An Exploration of th…
waywardstrategy
I'm an arrogant trash talke…
FlaShFTW
Gauntlet SC2: A Retrospectiv…
Ctone23
ramps on octagon
StaticNine
StarCraft improvement
iopq
Customize Sidebar...

Website Feedback

Closed Threads



Active: 9086 users

Custom map/ UMS creators wanted

Forum Index > BW General
Post a Reply
1 2 3 4 5 Next All
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-04-27 01:08:11
April 25 2017 00:30 GMT
#1
+ Show Spoiler +
I'm a programmer (not a pro-gamer) working on a new tool which will drastically expand the capabilities of UMS maps as well as make authoring way easier (no more trigger bullshit). It doesn't use EUD, doesn't require client mods and can't be patched out. The tool is quickly becoming usable and I need someone to help me with testing and feedback. Let me know in this thread if you're interested to help. Experience with SCMDraft 2 and/ or the Blizzard editor as well as (really) basic programming skills are required.


EDIT: Initial version has been released. Check out this post for info - http://www.teamliquid.net/forum/brood-war/521681-custom-map-ums-creators-wanted#19
biryusky
Profile Joined September 2012
70 Posts
April 25 2017 01:57 GMT
#2
if you have source code on on a github repository (either private or public) maybe i can take a look. What language did you write this tool with?
integral
Profile Blog Joined February 2009
United States3161 Posts
April 25 2017 04:24 GMT
#3
I'm curious but skeptical, especially of claims that you can "drastically expand the capabilities of UMS maps". We at staredit.net have pretty well pushed UMS mapping to its limits already. That said, if you can back up your claims, I'll help with both testing and feedback.
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-04-25 13:40:39
April 25 2017 11:33 GMT
#4
On April 25 2017 13:24 integral wrote:
I'm curious but skeptical, especially of claims that you can "drastically expand the capabilities of UMS maps". We at staredit.net have pretty well pushed UMS mapping to its limits already. That said, if you can back up your claims, I'll help with both testing and feedback.


I've created a programming language, IR and a compiler. It takes the source code + a .scx and produces a new .scx. In its essence it's a virtual machine running on triggers. It doesn't offer any new features per se (like EUDs) but you can create much more complicated behaviors and logic than with hand-made triggers as it's a real programming language with variables, expressions, loops, functions, etc.

Here is a simple example I can compile and run right now (image because the forum software messes up the formatting):
[image loading]

And by the way the resources on staredit.net (especially the wiki) have been absolutely essential for creating this, I am so grateful to your community!

On April 25 2017 10:57 biryusky wrote:
if you have source code on on a github repository (either private or public) maybe i can take a look. What language did you write this tool with?


Give me your GitHub username and I'll add you to the repo. The compiler is written in modern C++.

As a sidenote, I will open source everything in the coming weeks (days), as soon as it's in a semi-finished state.
BlueStar
Profile Blog Joined August 2005
Bulgaria1171 Posts
April 25 2017 11:42 GMT
#5
Looking forward to this !!
Please, make poker defense on steroids
Leader of the Bulgarian National SCBW/SC2 team and team pSi.SCBW/SC2
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-04-26 12:38:23
April 25 2017 22:10 GMT
#6
After some more work today stuff like this works now:

global allowedSwaps = 3;

bring(Player1, AtLeast, 1, TerranMarine, "TestLocation2") => {
if (allowedSwaps == 2) {
print("Sorry, you have no more swaps left.");
return;
}

allowedSwaps--;
kill(TerranMarine, Player1, 1, "TestLocation2");
spawn(ProtossZealot, Player1, 1, "TestLocation");

print("Here is your zealot.");
}

bring(Player1, AtLeast, 1, ProtossZealot, "TestLocation2") => {
if (allowedSwaps == 2) {
print("Sorry, you have no more swaps left.");
return;
}

allowedSwaps--;
kill(ProtossZealot, Player1, 1, "TestLocation2");
spawn(TerranMarine, Player1, 1, "TestLocation");

print("Here is your marine.");
}

fn main() {
spawn(TerranMarine, Player1, 1, "TestLocation");

while (true) {
poll_events();
}
}
biryusky
Profile Joined September 2012
70 Posts
April 25 2017 23:30 GMT
#7
check your pm, ive mailed you my github username
Psyda
Profile Joined April 2017
1 Post
April 26 2017 01:50 GMT
#8
Sounds interesting. I'd like to be apart of this.
integral
Profile Blog Joined February 2009
United States3161 Posts
Last Edited: 2017-04-26 01:54:20
April 26 2017 01:52 GMT
#9
Interesting. A lot of that code looks very similar to current triggers. I'm also concerned about how flexible those functions are, I change conditions and actions constantly when I'm making a map. Adding a single condition and action to a particular function seems like it's going to be the same as writing triggers, correct me if I am wrong. A programmatic approach is helpful still, maybe even required for modern maps, so anyone who isn't using something like that will benefit tremendously. I'm currently using a simple string generator, but I suspect with similar results:

[image loading]

One thing I haven't done yet though is write macros to generate the triggers necessary for complex math between two death counts. Multiplication, division, comparison, etc. Currently I'm generating each calculation separately. If you do something like this in your program, I'm sold. This alone is useful enough to make it all worth it.

Another thing I need to do but haven't done yet is figure out how to use death counts as memory for multiple values/variables. Not having any form of memory without death counts sucks and I'm already low on death counts for a lot of maps. I'm not excited trying to think about how to store multiple values in a death count and then extract those values with addition and subtraction. Maybe you're a genius and can do this easily, here's hoping.
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-04-26 02:54:23
April 26 2017 02:36 GMT
#10
The code similarity to current triggers is intentional (to ease the transition for map creators). Don't be mistaken though, this is a full-blown programming language.

I'm very sleepy now (5 am here) so forgive me if I miss some important detail but here's a short explanation of how it works:

- You write your code in a high level language not unlike C++ or JavaScript. It supports local & global variables, arithmetic, complex expressions, function calls with arguments and return value, event callbacks, you name it. This all goes into a handwritten parser which outputs an AST.
- From the AST linearized IR code (basically a list of low level instructions) is generated.
- The IR language has all the instructions you'd expect to be able to implement the higher level one. Stuff like push, pop, call, ret, set, add, sub, etc + integration with the game like spawning/ killing units, checking locations, setting resources. So a piece of code gets translated to something like:

[image loading]

- This list of instructions is fed into the compiler backend which produces a bunch of triggers and creates the new map file. The actual codegen was the hard part of all this but I have it working properly (and pretty efficiently) now.

- For map makers this means calling the .exe with the map and code file which "combines" them into the final map which you can run in the game.

I feel like I'll be able to release something in a few days or a week tops with the progress I'm making. For the future there is a lot of work that can be done on optimizing the AST and IR once I'm done with all the major features.

To answer your questions specifically:

I'm also concerned about how flexible those functions are, I change conditions and actions constantly when I'm making a map


Everything can be changed instantly, recompilation takes milliseconds. You can go from code to testing in the game in 10 seconds. Also there are preprocessor macros (#define for C/ C++ people) and global variables so you can change stuff in a lot of places at once.

Adding a single condition and action to a particular function seems like it's going to be the same as writing triggers, correct me if I am wrong

Well, kind of. With the exception that you can write most stuff once and then reuse it. You can even have multiple code files so you can make a library of common functions for all your maps. Also I'm considering some kind of meta-programming (template) support in the language to make managing a lot of event handlers even less painful.

Multiplication, division, comparison, etc. Currently I'm generating each calculation separately. If you do something like this in your program, I'm sold

Yeah, you can do stuff like ((x + 15) * foo()). You can go crazy with the expressions until you blow the stack.

Another thing I need to do but haven't done yet is figure out how to use death counts as memory for multiple values/variables.

I use the death counts for player 8 as general purpose memory. It would be possible to pack more than one value into a single "register" to save on memory, though I'm not sure if you'd need that many registers (there are ~220 available) if you're not doing the triggers by hand. The compiler is pretty good at figuring out what to throw out when it's not necessary anymore. We'll have to test the tool with a non-trivial map and see what happens and figure it out from there.

I'll be back tomorrow to talk more. Anyone PM me GitHub username if you want access to the work in progress stuff.
integral
Profile Blog Joined February 2009
United States3161 Posts
Last Edited: 2017-04-26 03:31:14
April 26 2017 03:18 GMT
#11
Sounds good.

Yeah, you can do stuff like ((x + 15) * foo()). You can go crazy with the expressions until you blow the stack.

Just to be 100% clear, because this is sounding slightly too good to be true, I need the triggers themselves to do the calculating. As in, I need a function that generates the entire subtract/add trees necessary to multiply numbers using triggers. Using complex expressions to generate triggers is nice, but using your program to generate complex expressions *as calculated by triggers* is where the money is.

+ Show Spoiler +

Trigger("All players"){
Conditions:
Deaths("Current Player", "Left Wall Flame Trap", At least, 1024);

Actions:
Set Deaths("Current Player", "Right Wall Missile Trap", Add, 1024);
Set Deaths("Current Player", "Left Wall Flame Trap", Subtract, 1024);
Preserve Trigger();
}

//-----------------------------------------------------------------//
Trigger("All players"){
Conditions:
Deaths("Current Player", "Left Wall Flame Trap", At least, 512);

Actions:
Set Deaths("Current Player", "Right Wall Missile Trap", Add, 512);
Set Deaths("Current Player", "Left Wall Flame Trap", Subtract, 512);
Preserve Trigger();
}


etc. until 0, then take result (right wall missile trap) and subtract it back into left wall flame trap while multiplying or dividing by another value somewhere else, usually hardcoded since you can't exactly have a condition for every possibility without exceeding trigger limit. This is the sort of thing I haven't coded a way to cleanly generate yet, and until I see evidence (as in trigger output) of this function existing in your program I won't believe you've done it either.

I use the death counts for player 8 as general purpose memory. It would be possible to pack more than one value into a single "register" to save on memory, though I'm not sure if you'd need that many registers (there are ~220 available) if you're not doing the triggers by hand. The compiler is pretty good at figuring out what to throw out when it's not necessary anymore. We'll have to test the tool with a non-trivial map and see what happens and figure it out from there.


I'm using almost all already in most of my maps, to the point where I need to start recycling them sometimes where possible. If I had the ability to use more per register I would be able to do some pretty neat stuff with triggers that no one has done before. As an example, I have plans for a primitive AI that would be able to make attack/retreat decisions on the basis of counting non-arbitrary units per non-arbitrary location. I would use ~40 death counts per location, with calculations to extract those values and compare them, if this weren't prohibitively difficult to code.
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-04-26 12:31:29
April 26 2017 12:08 GMT
#12
Just to be 100% clear, because this is sounding slightly too good to be true, I need the triggers themselves to do the calculating. As in, I need a function that generates the entire subtract/add trees necessary to multiply numbers using triggers.


Exactly what I've done. The expressions are emitted as trigger chains and evaluated at runtime inside the game (as in your example). And you can do much more than just multiply two numbers. Here is the result of compiling one of my examples from the previous posts opened in SCMDraft (you don't actually need a map editor for writing the triggers, the compiler reads/ writes to the map file directly).

[image loading]

I would use ~40 death counts per location, with calculations to extract those values and compare them, if this weren't prohibitively difficult to code.


This would be quite possible to code, especially after I implement arrays which is more or less next on my list.

I'm using almost all already in most of my maps, to the point where I need to start recycling them sometimes where possible.

That's possibly because you use a register (death count) only for one thing. The language I'm making is block scoped and reuses "dead" values, so you can do more with less registers. Also temporaries from expression calculations are reused.
2Pacalypse-
Profile Joined October 2006
Croatia9540 Posts
April 26 2017 12:33 GMT
#13
This looks pretty interesting. Good work!

Btw, you can use
[code]some code here[./code]
(without a dot) to post code here in the forum, which preserves formatting.
Moderator"We're a community of geniuses because we've found how to extract 95% of the feeling of doing something amazing without actually doing anything." - Chill
integral
Profile Blog Joined February 2009
United States3161 Posts
Last Edited: 2017-04-26 13:37:05
April 26 2017 13:19 GMT
#14
The expressions are emitted as trigger chains and evaluated at runtime inside the game (as in your example).


k you're a genius, I'm sold

And you can do much more than just multiply two numbers.


keep going I'm close

That's possibly because you use a register (death count) only for one thing. The language I'm making is block scoped and reuses "dead" values, so you can do more with less registers. Also temporaries from expression calculations are reused.


Ok, I was skeptical of you, so you can be skeptical of me! Totally fair. Most are in continual use, actually, and I'm using a lot of the heroes and buildings in the map so I just can't use those. I'm more or less at the limit on everything - ccmu, strings, death counts, locations, switches, death counts, even # of triggers that can run without lag. So yeah I'm definitely at the point where I'd be needing to reuse death counts if I want to add things. What I want to do is probably an edge case though, so probably not where you'll want to focus when you're still in development.

This would be quite possible to code, especially after I implement arrays which is more or less next on my list.

One value per unit type per location and I get ~5 locations without having to reuse stuff, so I haven't even tried to mess with this. Plus I run out of triggers doing a count for every unit type. Until recently I've been pretty sure what I wanted to do is just outside the range of what's possible with the current engine, but if I (we?) can figure out a clever way to store multiple values, I can do some really neat things.
integral
Profile Blog Joined February 2009
United States3161 Posts
Last Edited: 2017-04-26 13:55:53
April 26 2017 13:27 GMT
#15
accidental double post. I'll use it to ask some more questions:

Who are you? Where did you come from? (Who the fuck writes a programming language for triggers?) Why are you doing this? What help do you need?
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-04-26 14:36:36
April 26 2017 14:32 GMT
#16
Who are you?

I'm Alex, I ... mod games I guess. I've participated in many modding communities and started some myself.

Where did you come from?

I used to make UMS maps with the blizzard editor when I was like 10. I think it may have helped me become a programmer. Also I played a lot of competitive SC2 a few years ago, now I'm back to Brood War.

Who the fuck writes a programming language for triggers?

People who should be working for their job instead. Also it just happens I had to write a bunch of code parsers recently so the knowledge is still fresh in my mind. The IR + codegen part is new to me so don't expect LLVM or GCC levels of sophistication, at least to start.

Why are you doing this?

I love modding and I love writing tools so it was a natural consequence. The actual decision to make this came a few days ago after I got annoyed at the limitations of a UMS map I play a lot.

What help do you need?


Testing, feedback and writing documentation. I'll setup avenues for all of this as soon as I decide to release the initial version in a few days.
nlight
Profile Joined October 2011
Bulgaria58 Posts
April 26 2017 16:19 GMT
#17
Some new stuff to show. This code compiles and runs now.

global foo = 15;

fn do_some_stuff() {
return 42;
}

fn main() {
var bar = do_some_stuff();

if (bar == 42) {
set_resource(Player1, Minerals, foo + bar);
}
}
quirinus
Profile Blog Joined May 2007
Croatia2489 Posts
April 26 2017 17:50 GMT
#18
Looks sick. Hopefully, you'll figure out a way to go past the limitations.
All candles lit within him, and there was purity. | First auto-promoted BW LP editor.
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-04-27 01:08:38
April 26 2017 18:18 GMT
#19
I've decided to release my current version so I can work together with all of you to make it better.

The source code is available at https://github.com/AlexanderDzhoganov/langums under the MIT license. Compileable with any modern C++ compiler, doesn't have any external dependencies.

You can get the whole repo in a .zip file from https://github.com/AlexanderDzhoganov/langums/archive/master.zip

If you don't care about the source code and want just the tool you can get the latest .exe from https://github.com/AlexanderDzhoganov/langums/blob/master/langums.exe?raw=true

Check out the README for usage instructions + language how-to - https://github.com/AlexanderDzhoganov/langums/blob/master/README.md

Some code examples you can find in the test/ folder of the repo - https://github.com/AlexanderDzhoganov/langums/tree/master/test

As you'll see there is plenty missing at the moment, but I'm adding stuff all the time. The readme will also get updated with more info and examples as we go. I'm here to answer any questions.
RWLabs
Profile Joined March 2017
Korea (South)273 Posts
April 26 2017 22:17 GMT
#20
Awesome. I will give it a shot.
Aldaris was the good guy of Brood War.
1 2 3 4 5 Next All
Please log in or register to reply.
Live Events Refresh
Big Brain Bouts
16:00
#120
Jumy vs eGGz
Harstem vs sebesdes
TriGGeR vs HeRoMaRinE
RotterdaM711
IndyStarCraft 152
Liquipedia
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
RotterdaM 711
LamboSC2 475
IndyStarCraft 152
ProTech151
trigger 73
BRAT_OK 46
MindelVK 22
EmSc Tv 8
StarCraft: Brood War
Britney 22820
EffOrt 1413
Shuttle 877
Jaedong 701
Soulkey 508
ggaemo 318
Snow 192
firebathero 177
actioN 120
Mong 100
[ Show more ]
Sea.KH 62
Dewaltoss 46
Pusan 36
Hm[arnc] 27
Rock 17
GoRush 17
ajuk12(nOOB) 13
Dota 2
Gorgc9868
qojqva1834
420jenkins198
League of Legends
JimRising 487
Counter-Strike
fl0m2540
zeus701
Heroes of the Storm
Grubby1802
Other Games
FrodaN2576
singsing1374
DeMusliM365
KnowMe119
ArmadaUGS84
Trikslyr62
Mew2King54
Organizations
Dota 2
PGL Dota 2 - Main Stream10214
StarCraft 2
TaKeTV 475
EmSc Tv 8
EmSc2Tv 8
Blizzard YouTube
StarCraft: Brood War
BSLTrovo
[ Show 15 non-featured ]
StarCraft 2
• mYiSmile134
• AfreecaTV YouTube
• intothetv
• Kozan
• IndyKCrew
• LaughNgamezSOOP
• Migwel
• sooper7s
StarCraft: Brood War
• FirePhoenix10
• BSLYoutube
• STPLYoutube
• ZZZeroYoutube
Dota 2
• WagamamaTV229
League of Legends
• Nemesis4894
Other Games
• Shiphtur333
Upcoming Events
Douyu Cup 2020
11h 31m
Maestros of the Game
19h 1m
herO vs Classic
Maru vs Serral
BSL22 NKC (BSL vs China)
20h 31m
Douyu Cup 2020
1d 11h
BSL22 NKC (BSL vs China)
1d 20h
Online Event
1d 21h
RSL Revival
2 days
WardiTV Weekly
2 days
RSL Revival
3 days
RSL Revival
3 days
[ Show More ]
Bombastic Starleague
4 days
Kung Fu Cup
4 days
OSC
5 days
CrankTV Team League
5 days
Bombastic Starleague
6 days
Replay Cast
6 days
The PondCast
6 days
Liquipedia Results

Completed

CSCL: Masked Kings S4
WardiTV Spring 2026
Heroes Pulsing #2

Ongoing

IPSL Spring 2026
Acropolis #4
YSL S3
BSL 22 Non-Korean Championship
CSL Season 21: Qualifier 1
CSL Season 21: Qualifier 2
SCTL 2026 Spring
Douyu Cup 2026
Maestros of the Game 2
Murky Cup 2026
IEM Cologne Major 2026
Stake Ranked Episode 2
CS Asia Championships 2026
Asian Champions League 2026
IEM Atlanta 2026
PGL Astana 2026
BLAST Rivals Spring 2026
IEM Rio 2026

Upcoming

CSL 2026 Summer (S21)
CSLAN 4
Blizzard Classic Cup 2026
Kung Fu Cup 2026 Grand Finals
RSL Revival: Season 6
CranK Gathers Season 4: BW vs SC2 Team League
HSC XXIX
BCC 2026
Light Tournament 2026
Eternal Conflict S2 Finale
Eternal Conflict S2 E1
Heroes Pulsing #3
FISSURE Playground #5
BLAST Open Fall 2026
Esports World Cup 2026
BLAST Bounty Summer 2026
BLAST Bounty Summer Qual
Stake Ranked Episode 3
XSE Pro League 2026
TLPD

1. ByuN
2. TY
3. Dark
4. Solar
5. Stats
6. Nerchio
7. sOs
8. soO
9. INnoVation
10. Elazer
1. Rain
2. Flash
3. EffOrt
4. Last
5. Bisu
6. Soulkey
7. Mini
8. Sharp
Sidebar Settings...

Advertising | Privacy Policy | Terms Of Use | Contact Us

Original banner artwork: Jim Warren
The contents of this webpage are copyright © 2026 TLnet. All Rights Reserved.