Browse Source

new files

Nicolas Petton 12 years ago
parent
commit
d720c44bc4
3 changed files with 989 additions and 0 deletions
  1. 352 0
      bin/amberc
  2. 531 0
      css/amber.css
  3. 106 0
      js/amber.js

+ 352 - 0
bin/amberc

@@ -0,0 +1,352 @@
+#!/bin/bash
+#
+# This is a "compiler" for Amber code. Run without arguments for help.
+
+# Get Amber root directory from the location of this script so that
+# we can find the st and js directories etc.
+
+# Earlier we used this but it does not work on Mac
+# Amber=$(readlink -f `dirname ${0}`/..)
+TARGET=`dirname ${0}`/..
+pushd . >/dev/null
+cd $TARGET
+AMBER="`\pwd -P`"
+popd >/dev/null
+
+function usage {
+	cat <<ENDOFHELP
+Usage: $0 [-l lib1,lib2...] [-i file] [-m class] [-M file]
+          [-o] [-O|-A] [-d] [-s suffix] [-S suffix] [file1 [file2 ...]] [Program]
+
+   Will compile Amber files - either separately or into a runnable complete
+   program. If no .st files are listed only a linking stage is performed.
+   Files listed will be handled using these rules:
+
+   *.js
+     Files are linked (concatenated) in listed order.
+     If not found we look in $AMBER/js
+
+   *.st
+     Files are compiled into .js files before concatenated.
+     If not found we look in $AMBER/st.
+
+     NOTE: Each file is currently considered to be a fileout of a single class
+     category of the same name as the file!
+
+   If no Program is specified each given .st file will be compiled into
+   a .js file. Otherwise a <Program>.js file is linked together based on
+   the options:
+
+  -l library1,library2
+     Additionally add listed libraries (no spaces or .js) in listed order.
+
+  -i file
+     Add library initializer <file> instead of default $AMBER/js/init.js 
+
+  -m class
+     Add at end a call to #main in class <class>. 
+
+  -M file
+     Add at end javascript file <file> acting as main.
+        
+  -o
+     Optimize each js file using the Google closure compiler.
+     Using Closure compiler found at ~/compiler.jar    
+
+  -O
+     Optimize final <Program>.js using the Google closure compiler.
+     Using Closure compiler found at ~/compiler.jar
+
+  -A Same as -O but use --compilation_level ADVANCED_OPTIMIZATIONS
+
+  -d
+     Additionally export code for deploy - stripped from source etc.
+     Uses suffix ".deploy.js" in addition to any explicit given suffic using -s.
+
+  -s suffix
+     Add <suffix> to compiled js files so that File.st is compiled into
+     File.<suffix>.js.
+
+  -S suffix
+     Use <suffix> for all libraries accessed using -L or -l. This makes it possible
+     to have multiple flavors of Amber and libraries in the same place.
+
+
+     Example invocations:
+
+     Just compile Kernel.st to Kernel.js:
+
+        amberc Kernel.st
+
+     Compile Hello.st to Hello.js and create complete program called
+     Program.js and adding a call to class method #main in class Hello:
+
+        amberc -m Hello Hello.st Program
+
+     Compile two .st files into corresponding .js files,
+     and link with specific myboot.js, myKernel.js, myinit.js
+     and main.js and create complete program called Program.js:
+
+        amberc -M main.js myinit.js myboot.js myKernel.js Cat1.st Cat2.st Program
+
+ENDOFHELP
+	exit 1;
+}
+
+# Check we at least got one argument
+if [ -z $1 ] ; then
+   usage
+fi
+
+# Define our predefined library combinations
+KERNEL="boot Kernel"
+COMPILER="$KERNEL parser Compiler"
+
+# Predefined initializer
+INITIALIZER="$AMBER/js/init.js"
+
+# Default values
+ENV=
+INIT=$INITIALIZER
+MAIN=
+MAINFILE=
+BASE=$KERNEL
+LOAD=
+CLOSUREOPTS=
+# Ok, bad coding practice but hey, who would use such a suffix?
+SUFFIX=no-silly-suffix
+SUFFIXUSED=
+DEPLOY=false
+NODECOMPILE=nodecompile
+
+# Read options and shift them away
+while getopts "l:i:m:M:oOAds:S:h?" o; do
+case "$o" in
+   l) LOAD=$OPTARG;;
+   i) INIT=$OPTARG;;
+   m) MAIN=$OPTARG;;
+   M) MAINFILE=$OPTARG;;
+   o) CLOSURE=true
+      CLOSUREPARTS=true;;
+   O) CLOSURE=true
+      CLOSUREFULL=true;;
+   A) CLOSURE=true
+      CLOSUREOPTS="$CLOSUREOPTS --compilation_level ADVANCED_OPTIMIZATIONS"
+      CLOSUREFULL=true;;
+   d) DEPLOY=true;;
+   s) SUFFIX=$OPTARG
+      SUFFIXUSED=$SUFFIX;;
+   S) LOADSUFFIX=$OPTARG
+      SUFFIXUSED=$SUFFIX;;
+   h) usage;;
+   [?])  usage;;
+   esac
+done
+shift $(($OPTIND - 1))
+
+# Check for Closure compiler and Java
+if [ ! -z $CLOSURE ]; then
+  java > /dev/null
+  if [ $? -eq 0 ]; then 
+    if [ ! -f ~/compiler.jar ]; then
+      echo "Can not find Closure compiler at ~/compiler.jar"
+      exit 1
+    fi
+  else
+   echo "java is not installed and is needed for -O, -A or -o (Closure compiler)."
+   exit 1
+  fi
+fi
+
+# Function for looking up listed js files
+function resolvejs {
+  FNAME="$1$LOADSUFFIX.js"
+  if [ -f $FNAME ]; then
+    RESOLVED="$FNAME" 
+  else
+    if [ -f $AMBER/js/$FNAME ]; then
+      RESOLVED="$AMBER/js/$FNAME"
+    else
+      echo "Javascript file not found: $FNAME"
+      exit 1
+    fi
+  fi
+}
+
+# Resolve listed libraries in $BASE deparated by spaces
+for FILE in $BASE
+do
+   resolvejs $FILE
+   TOBASE="$TOBASE $RESOLVED"
+done
+
+# Resolve listed libraries in $LOAD separated by ,
+LOAD=${LOAD//,/\ }
+for FILE in $LOAD
+do
+   resolvejs $FILE
+   TOLOAD="$TOLOAD $RESOLVED"
+done
+
+# Resolve COMPILER
+for FILE in $COMPILER
+do
+   resolvejs $FILE
+   TOCOMPILER="$TOCOMPILER $RESOLVED"
+done
+
+# Add supplied libraries we have not already loaded (they are already resolved)
+#for FILE in $EXTRA
+#do
+#   resolvejs $FILE
+#   TOEXTRA="$TOEXTRA $RESOLVED"
+#done
+
+TOCOMPILER="$TOCOMPILER$TOLOAD"
+
+# Resolve init and nodecompile
+THEREST="init $AMBER/bin/$NODECOMPILE"
+for FILE in $THEREST
+do
+   resolvejs $FILE
+   TOCOMPILER="$TOCOMPILER $RESOLVED"
+done
+
+# Add supplied libraries
+LIBS="$TOBASE $TOLOAD"
+
+# Get a unique tempdir and make it get auto removed on exit
+TMPDIR=`mktemp -d amberc.XXXXXX`
+trap "rm -rf $TMPDIR" EXIT
+
+
+# --------------------------------------------------
+# Collect libraries and Smalltalk files looking
+# both locally and in $AMBER/js and $AMBER/st 
+# --------------------------------------------------
+PROGRAM=
+until [ "$*" = "" ]
+do
+  case $1 in
+     *.st)
+        CATEGORY=`basename $1 .st`
+        if [ -f "$1" ]; then
+           COMPILE="$COMPILE $1 $CATEGORY"
+           COMPILED="$COMPILED $CATEGORY$SUFFIXUSED.js"
+        else
+           if [ -f $AMBER/st/$1 ]; then
+             COMPILE="$COMPILE $AMBER/st/$1 $CATEGORY"
+             COMPILED="$COMPILED $CATEGORY$SUFFIXUSED.js"
+           else
+             echo "Amber file not found: $1"
+             exit 1
+           fi
+        fi
+        ;;
+
+     *.js)
+        resolvejs $1
+	LIBS="$LIBS $RESOLVED" 
+        ;;
+      *)
+        # Will end up being the last non js/st argument
+        PROGRAM=$1
+        ;;
+  esac
+  shift
+done
+
+# --------------------------------------------------
+# Actual compilation phase of collected .st files
+# --------------------------------------------------
+
+# Create compiler dynamically
+cat $TOCOMPILER > $TMPDIR/compiler.js
+ 
+# Compile all collected .st files to .js
+echo "Loading libraries$TOCOMPILER and compiling ..."
+node $TMPDIR/compiler.js $DEPLOY $SUFFIX $COMPILE
+
+# Verify all .js files corresponding to .st files were created, otherwise exit
+IFS=" "
+for FILE in $COMPILED
+do
+  if [ ! -f "$FILE" ]; then
+    echo "Failed compilation of $FILE, exiting."
+    exit 1
+  fi 
+done
+
+if [ ! -z $CLOSUREPARTS ]; then
+  echo "Compiling all js files using Google closure compiler."
+
+  ALLJSFILES="$COMPILED $LIBS"
+  for FILE in $ALLJSFILES
+  do
+    mv $FILE $FILE.original
+    java -jar ~/compiler.jar $CLOSUREOPTS --js $FILE.original --js_output_file $FILE
+    rm $FILE.original
+  done
+fi
+
+
+if [ -z $PROGRAM ]; then
+  echo "Done."
+  exit 0
+fi
+
+# --------------------------------------------------
+# Now we start composing resulting javascript file.
+# --------------------------------------------------
+
+# Add collected libraries to libs.js file.
+if [ ! -z "$LIBS" ]; then
+  echo "Adding libraries $LIBS ..."
+  cat $LIBS > $TMPDIR/libs.js
+  LIBS=$TMPDIR/libs.js
+fi
+
+echo "Adding Amber code$COMPILED ..."
+
+# Check for init file
+if [ ! -z "$INIT" ]; then
+   if [ -f "$INIT" ]; then
+      echo "Adding initializer $INIT ..."
+   else
+      echo "Can not find init file $INIT, exiting."
+      exit 1
+   fi 
+fi
+
+# Check for adding main
+if [ ! -z "$MAIN" ]; then
+  echo "Adding call to $MAIN class >> main ..."
+  echo "smalltalk.$MAIN._main()" > $TMPDIR/main.js
+  MAIN=$TMPDIR/main.js
+fi
+
+# Check for adding main file
+if [ ! -z "$MAINFILE" ]; then
+   if [ -f "$MAINFILE" ]; then
+      echo "Adding main as $MAINFILE ..."
+   else
+      echo "Can not find main file $MAINFILE, exiting."
+      exit 1
+   fi 
+   MAIN=$MAINFILE
+fi
+
+# And finally concatenate Program.js
+echo "Writing $PROGRAM.js ..."
+cat $LIBS $COMPILED $INIT $MAIN > $PROGRAM.js
+echo "Done."
+
+
+if [ ! -z $CLOSUREFULL ]; then
+  echo "Compiling $PROGRAM.js file using Google closure compiler."
+  mv $PROGRAM.js $PROGRAM.js.original
+  java -jar ~/compiler.jar $CLOSUREOPTS --js $PROGRAM.js.original --js_output_file $PROGRAM.js
+  rm $PROGRAM.js.original
+  echo "Done."
+fi
+

+ 531 - 0
css/amber.css

@@ -0,0 +1,531 @@
+body.jtalkBody {
+    margin-bottom: 350px;
+}
+
+#jtalkTabs, #jtalk .jt_tabs {
+    margin: 0;
+    padding: 0;
+    background: url("../images/sprite.png") #DBD9C9 0 -27px;
+    height: 22px;
+    width: 100%;
+    list-style: none;
+    font-weight: bold;
+}
+
+#jtalkTabs li, #jtalk .jt_tabs li {
+    padding: 0 1px;
+    cursor: pointer;
+    color: #565656;
+}
+
+#jtalk .ltab, #jtalk .rtab, #jtalk .mtab {
+    height: 22px;
+    float: left;
+}
+
+#jtalk .ltab, #jtalk .rtab {
+    width: 8px;
+}
+
+#jtalk .rtab {
+    margin-right: 1px;
+}
+
+#jtalk .mtab {
+    line-height: 20px;
+}
+
+#jtalkTabs li:hover .ltab,
+#jtalk .jt_tabs li:hover .ltab {
+    background: url("../images/sprite.png") -16px -96px;
+}
+
+#jtalkTabs li:hover .mtab,
+#jtalk .jt_tabs li:hover .mtab {
+    background: url("../images/sprite.png") 0 -73px;
+}
+
+#jtalkTabs li:hover .rtab,
+#jtalk .jt_tabs li:hover .rtab {
+    background: url("../images/sprite.png") -24px -96px;
+}
+
+#jtalkTabs li.selected,
+#jtalk .jt_tabs li.selected {
+    color: #111;
+}
+
+#jtalkTabs li.selected .ltab,
+#jtalk .jt_tabs li.selected .ltab {
+    background: url("../images/sprite.png") 0px -96px;
+}
+
+#jtalkTabs li.selected .mtab,
+#jtalk .jt_tabs li.selected .mtab {
+    background: url("../images/sprite.png") 0 -50px;
+}
+
+#jtalkTabs li.selected .rtab,
+#jtalk .jt_tabs li.selected .rtab {
+    background: url("../images/sprite.png") -8px -96px;
+}
+
+#jtalkTabs li .close {
+    margin-right: 5px;
+    color: #aaa;
+}
+
+#jtalk {
+       position: fixed;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       height: 330px;
+       z-index: 1000;
+}
+
+#jtalk, #jtalk button, #jtalk input, #jtalk select {
+       font-family: Lucida Grande, Tahoma, sans-serif;
+       font-size: 11px;
+}
+
+#jtalk #logo {
+    position: absolute;
+    top: 3px;
+    left: 8px;
+    width: 22px;
+    height: 20px;
+    background: url("../images/tinylogo.png") top left no-repeat;
+}
+
+#jtalk #jt_toolbar {
+    height: 27px;
+    background: url("../images/sprite.png") 0 0;
+}
+
+#jtalk #jt_toolbar input {
+    margin-left: 50px;
+    width: 250px;
+    margin-top: 5px;
+}
+
+#jtalk #jt_toolbar #jt_close {
+    position: absolute;
+    right: 4px;
+    top: 6px;
+    width: 16px;
+    height: 16px;
+    background: url('../images/off.png');
+    cursor: pointer;
+}
+
+#jtalk #jt_toolbar #jt_close:hover {
+    background: url('../images/offHover.png');
+}
+
+
+#jtalk .ui-resizable-handle {
+    background-color: transparent;
+    top: 0;
+    cursor: row-resize;
+    height: 5px;
+    left: 0;
+    position: absolute;
+    right: 0;
+    width: auto !important;
+}
+
+.jtalkTool {
+    width: 100%;
+    color: #333;
+    line-height: 1.3em;
+    padding: 0;
+    margin: 0;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    top: 49px;
+    z-index: 1000;
+    background: white;
+}
+
+.jtalkTool .jt_box {
+    width: 100%;
+    margin: 0;
+    position: absolute;
+    top: 0;
+    bottom: 27px;
+}
+
+.jtalkTool .jt_buttons {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 27px;
+    line-height: 27px;
+    background: url("../images/sprite.png") 0 0 repeat;
+}
+
+.jtalkTool .jt_buttons .right {
+    float: right;
+}
+
+.jtalkTool .important {
+    font-weight: bold;
+}
+
+
+.jtalkTool button {
+    border: 1px solid transparent;
+    background: transparent;
+    padding: 2px 4px;
+    margin-left: 4px;
+    cursor: pointer;
+}
+
+.jtalkTool button:hover {
+    border-top: 1px solid #fff;
+    border-left: 1px solid #fff;
+    border-right: 1px solid #bbb;
+    border-bottom: 1px solid #bbb;
+}
+
+.jtalkTool  button:active {
+    border-top: 1px solid #bbb;
+    border-left: 1px solid #bbb;
+    border-right: 1px solid #fff;
+    border-bottom: 1px solid #fff;
+    background: #ddd;
+}
+
+.jtalkTool select, #jtalk input {
+    border-top: 1px solid #bbb;
+    border-left: 1px solid #bbb;
+    border-right: 1px solid #fff;
+    border-bottom: 1px solid #fff;
+    background: #fff;
+    margin-top: 0;
+    margin-bottom: 0;
+    padding-top: 0;
+    padding-bottom: 0;
+}
+
+.jtalkTool li {
+    margin: 0;
+    padding: 0;
+}
+    
+.jtalkTool .source {
+    height: 100%;
+}
+
+.jtalkTool textarea,
+.jtalkTool input {
+    border: 0 none;
+    font-family: Arial, Helvetica, sans;
+    line-height: 1.3em;
+    font-size: 12px;
+    position: relative;
+    padding: 0;
+}
+
+.jtalkTool .CodeMirror {
+    border: 0 none;
+    font-family: Arial, Helvetica, sans;
+    font-size: 12px;
+    line-height: 1.3em;
+    height: 100%;
+    background: white;
+}
+
+.jtalkTool .CodeMirror-scroll {
+    height: 100%;
+}
+
+.talkTool .CodeMirror-scroll pre {
+    font-family: Arial, Helvetica, sans;
+}
+
+.jtalkTool .jt_clear {	 
+    clear: both;
+}
+
+.jtalkTool .jt_transcript,
+.jtalkTool .jt_workspace {
+    width: 100%;
+    height: 100%;
+}
+
+.jtalkTool .jt_commit {
+    position: absolute;
+    top: 129px;
+    left: 0;
+    z-index: 1;
+}
+
+.jtalkTool .jt_rename {
+    position: absolute;
+    top: 129px;
+    left: 90px;
+    z-index: 1;
+}
+
+.jtalkTool .jt_delete {
+    position: absolute;
+    top: 129px;
+    left: 185px;
+    z-index: 1;
+}
+
+.jtalkTool .jt_column {
+    width: 25%;
+    padding: 0;
+    margin: 0;
+    float: left;
+    outline: 1px solid #aaa;
+    border: 0 none;
+    height: 130px;
+    overflow-y: auto;
+    background: #fff;
+    color: #111;
+    position: absolute;
+    top: 0;
+}
+
+.jtalkTool .jt_column.classes {
+    left: 25%
+}
+
+.jtalkTool .jt_column.classes ul {
+    margin-left: 0;
+}
+
+.jtalkTool .jt_column.classes ul li {
+    padding-left: 10px;
+    margin-left: 0;
+}
+
+.jtalkTool .jt_column.protocols {
+    left: 50%
+}
+
+.jtalkTool .jt_column.methods {
+    left: 75%
+}
+
+.jtalkTool .jt_column li {
+    list-style-type: none;
+    padding-left: 5px;
+    cursor: pointer;
+    color: #111;
+    font-weight: bold;
+}
+
+.jtalkTool .jt_column li.selected {
+	background: #e3e3e3;
+	color: #222;
+}
+
+.jtalkTool .jt_column li:hover {
+    background: #08c;
+    color: white;
+}
+
+#jtalk .jtalkTool .jt_tabs {
+    top: 130px;
+    position: absolute;
+}
+
+#jtalk .jtalkTool .jt_tabs.jt_browser {
+    padding-left: 25%;
+}
+
+.jtalkTool .jt_sourceCode {
+    position: absolute;
+    top: 152px;
+    bottom: 0;
+    left: 0;
+    right: 0;
+}
+
+.jtalkTool .jt_sourceCode textarea.source {
+    width: 100%;
+    height: 100%;
+}
+
+/* Debugger & inspector */
+
+.jtalkTool .jt_box .label {
+	width: 100%;
+	font-weight: bold;
+	text-align: center;
+	position: absolute;
+	line-height: 1.5em;
+	font-size: 16px;
+	color: red;
+	background: url("../images/sprite.png") top left repeat;
+	height: 27px;
+}
+
+.jtalkTool .jt_box .jt_column.debugger {
+    top: 158px;
+}
+
+.jtalkTool .jt_box .jt_column.debugger.contexts {
+    top: 27px;
+    width: 100%;
+}
+
+.jtalkTool .jt_sourceCode.debugger {
+    width: 60%;
+    top: 158px;
+}
+
+.jtalkTool .jt_box .jt_column.debugger.variables {
+    width: 10%;
+    left: 60%;
+    bottom: 0;
+    position: absolute;
+    height: auto;
+}
+
+.jtalkTool .jt_box .jt_column.debugger.inspector {
+    width: 30%;
+    left: 70%;
+    bottom: 0;
+    position: absolute;
+    height: auto;
+}
+
+.jtalkTool .jt_button.debugger.inspect {
+    position: absolute;
+    left: 60%;
+}
+
+.jtalkTool .jt_column.value {
+    left: 25%;
+    width: 75%;
+}
+
+.jtalkTool .jt_buttons.inspector {
+    position: absolute;
+    top: 130px;
+}
+
+
+/* ReferencesBrowser */
+
+.jtalkTool .jt_box .implementors {
+	width: 100%
+}
+
+.jtalkTool .jt_box .jt_column.implementors,
+.jtalkTool .jt_box .jt_column.senders,
+.jtalkTool .jt_box .jt_column.referenced_classes {
+	top: 20px;
+	height: auto;
+	bottom: 0;
+	width: 33.333%;
+}
+
+.jtalkTool .jt_box .jt_column.senders {
+	left: 33.333%
+}
+
+.jtalkTool .jt_box .jt_column.referenced_classes {
+        left: 66.67%
+}
+
+.jtalkTool .jt_box .jt_column.implementors .column_label, 
+.jtalkTool .jt_box .jt_column.senders .column_label,
+.jtalkTool .jt_box .jt_column.referenced_classes .column_label {
+	background: #dbdbdb
+}
+
+.jtalkTool .jt_box .jt_column.implementors .column_label:hover,
+.jtalkTool .jt_box .jt_column.senders .column_label:hover,
+.jtalkTool .jt_box .jt_column.referenced_classes .column_label:hover {
+	font-weight: bold;
+	color: #000;
+	cursor: default
+}
+
+
+.jtalkTool .classes .commented {
+		color: #33337F;
+}
+
+
+/* SUnit TestRunner  */
+
+.jtalkTool .jt_column.sunit.categories,
+.jtalkTool .jt_column.sunit.classes {
+	height: 100%
+}
+
+.jtalkTool .jt_column.sunit.classes li.all,
+.jtalkTool .jt_column.sunit.categories li.all {
+	background: #e3e3e3;
+	font-weight: bold
+}
+
+.jtalkTool .jt_column.sunit.classes li.all:hover ,
+.jtalkTool .jt_column.sunit.categories li.all:hover {
+	background: #0088CC;
+	font-weight: bold
+}
+
+.jtalkTool .sunit.status {
+	position: absolute;
+	left: 50%;
+	width: 50%;
+	outline: 1px solid #aaa;
+	background: white;
+	height: 40px
+}
+
+
+.jtalkTool .sunit.status.success {
+	background: #43d443;
+}
+
+
+.jtalkTool .sunit.status.failure {
+	background: #ecd443;
+}
+
+
+.jtalkTool .sunit.status.error {
+	background: #e56f3b;
+}
+
+.jtalkTool .progress_bar {
+	position: absolute;
+	left: 50%;
+	width: 50%;
+	top: 40px;
+	background: white;
+	outline: 1px solid #aaa;
+	min-height: 20px
+}
+
+.jtalkTool .progress_bar div {
+	background: #0088CC;
+	min-height: 20px;
+}
+
+.jtalkTool .jt_column.results.sunit {
+	left: 50%;
+	height: auto;
+        width: 50%;
+        top: 62px;
+        bottom: 0;
+}
+
+.jtalkTool .jt_column.sunit.results .errors {
+    color: red;
+}
+
+/*.jtalkTool .jt_column.sunit.results ul {padding: 0; margin: 0}*/
+

+ 106 - 0
js/amber.js

@@ -0,0 +1,106 @@
+/* Adapted from Clamato by Avi Bryant. http://www.clamato.net */
+
+(function() {
+    var scripts = document.getElementsByTagName("script");
+    var src = scripts[ scripts.length - 1 ].src;
+    var home = src.split("/").slice(0, -2).join("/") + "/";
+    var nocache = '?' + (new Date()).getTime();
+    var deploy = false;
+
+    function loadJS(name, prefix) {
+	var prefix = prefix || 'js';
+	var name = name;
+	if(!deploy) {
+	    name = name + nocache;
+	}
+	document.write('<script src="' + home + prefix + '/' + name + '" type="text/javascript"></script>');
+    }
+    
+    function loadCSS(name, prefix) {
+	var prefix = prefix || 'css';
+	var name = name;
+	if(!deploy) {
+	    name = name + nocache;
+	}
+	var link = document.createElement("link")
+  	link.setAttribute("rel", "stylesheet")
+  	link.setAttribute("type", "text/css")
+  	link.setAttribute("href", home + prefix + '/' + name)
+	document.getElementsByTagName("head")[0].appendChild(link);
+    }
+
+    function loadDependencies() {
+	loadJS('lib/jQuery/jquery-1.6.2.min.js');
+	loadJS('lib/jQuery/jquery-ui-1.8.9.custom.min.js');
+    }
+
+    function loadIDEDependencies() {
+	loadJS('lib/jQuery/jquery.textarea.js');
+	loadJS('lib/CodeMirror/lib/codemirror.js');
+	loadCSS('lib/CodeMirror/lib/codemirror.css', 'js');
+	loadJS('lib/CodeMirror/mode/smalltalk/smalltalk.js');
+	loadCSS('lib/CodeMirror/theme/amber.css', 'js');
+    }
+
+    window.loadAmber = function(spec) {
+	/* 
+	 example: 
+	 loadAmber({
+	   files: ['MyCategory1.js', 'MyCategory2.js'], 
+	   ready: function() {smalltalk.Browser._open()}
+	 })
+	*/
+
+	var spec = spec || {};
+
+	// In deployment mode, only the compressed version of Kernel 
+	// and Canvas are loaded
+	deploy = spec.deploy || false;
+
+	// Specify a version string to avoid wrong browser caching
+	if(spec.version) {
+	    nocache = '?' + spec.version;
+	}
+
+	loadDependencies();
+	if(deploy) {
+	    loadJS("boot.js");
+	    loadJS("Kernel.deploy.js");
+	    loadJS("Canvas.deploy.js");
+	    loadJS("JQuery.deploy.js");
+	} else {
+	    loadIDEDependencies();
+	    loadCSS('amber.css');
+	    loadJS("boot.js");
+	    loadJS("Kernel.js");
+	    loadJS("Canvas.js");
+	    loadJS("JQuery.js");
+	    loadJS("Compiler.js");
+	    loadJS("parser.js");
+	    loadJS("IDE.js");
+	    loadJS("SUnit.js");
+	    loadJS("Examples.js");
+	    loadJS("Benchfib.js");
+	    loadJS("Kernel-Tests.js");
+	    loadJS("JQuery-Tests.js");
+	}
+
+	// Load other files, possibly with another directory prefix than 'js'
+	if(spec.files) {
+	    for(var i=0; i < spec.files.length; i++) {
+		loadJS(spec.files[i], spec.prefix);
+	    }
+	}
+
+	smalltalkReady = function() {
+	    if(spec.ready) {
+		spec.ready();
+	    }
+	    if(deploy) {smalltalk.setDeploymentMode()}
+	}
+
+	// Be sure to setup & initialize smalltalk classes
+	loadJS("init.js");
+    }
+
+})();