Added scrolling to lists of available and scriptable presences.

(function()
 {

     /**
      @param {std.ScriptingGui.Controller}

      @param {object: <String(visibleId):visible object>} nearbyVisMap
      -- all the visible objects that satisfy scripter's proximity
      query.

      @param {object: <String(visibleId):
      std.FileManager.FileManagerElement> scriptedVisMap -- A record
      of all visibles that we have scripted at some point.

      @param {object: <int:std.ScriptingGui.Action> actionMap -- Which
      actions are selectable by scripter.

      @param {std.ScriptingGui.Console} console -- has several
      scripting events.
      */
     std.ScriptingGui =
         function(controller,nearbyVisMap,scriptedVisMap,actionMap,console)
     {
         if (typeof(simulator) == 'undefined')
         {
             throw new Error('Cannot initialize scripting gui without ' +
                             'simulator graphics.');
         }

         this.controller       = controller;
         this.nearbyVisMap     = nearbyVisMap;
         this.scriptedVisMap   = scriptedVisMap;
         this.actionMap        = actionMap;
         this.console          = console;

         this.guiMod = simulator._simulator.addGUITextModule(
             guiName(),
             getGuiText(),
             std.core.bind(guiInitFunc,undefined,this));
         this.hasInited = false;
     };

     system.require('scriptingGuiUtil.em');

     std.ScriptingGui.prototype.redraw = function()
     {
         if (!this.hasInited)
             return;

         //trigger redraw call
         this.guiMod.call(
             'ishmaelRedraw',toHtmlNearbyMap(this),toHtmlScriptedMap(this));

     };

     /**
      @param {String} visId -- Id of visible.
      */
     //called by html to add the visible with id
     std.ScriptingGui.prototype.hAddVisible = function(visId)
     {
         //already can script the visible.
         if (visId in this.scriptedVisMap)
         {
             this.console.guiEvent();
             return;
         }

         if (!(visId in this.nearbyVisMap))
         {
             //visible is no longer available.
             this.console.guiEvent();
             return;
         }

         this.controller.addVisible(this.nearbyVisMap[visId]);
     };

     std.ScriptingGui.prototype.hRemoveVisible = function(visId)
     {
         //FIXME: should finish this call
         throw new Error('FIXME: must finish hRemoveVisible call ' +
                         'in scriptingGui');
     };

     /**
      @param {std.ScriptingGui}
      */
     function guiInitFunc(scriptingGui)
     {
         scriptingGui.hasInited = true;

         //when a user clicks on any of the nearby visibles to script
         //them, want that object to move into scripted objects.
         scriptingGui.guiMod.bind(
             'addVisible',
             std.core.bind(scriptingGui.hAddVisible,scriptingGui));

         //when a user clicks to remove any of the scripted visibles
         //from scripted map, then destroy it.
         scriptingGui.guiMod.bind(
             'removeVisible',
             std.core.bind(scriptingGui.hRemoveVisible,scriptingGui));

         scriptingGui.redraw();
     }

     /**
      @returns {object: <string (visibleId): string (visibleId)>}
      scriptingGui -- Takes the list of nearby objects and turns it
      into an object that (for now) maps visibleIds to visibleIds.

      @see ishmaelRedraw
      */
     function toHtmlNearbyMap(scriptingGui)
     {
         var returner = { };
         for (var s in scriptingGui.nearbyVisMap)
             returner[s] = s;
         return returner;
     }

     /**
      @returns {object: <string (visibleId): string (visibleId)>}
      scriptingGui -- Takes the list of nearby objects and turns it
      into an object that (for now) maps visibleIds to visibleIds.

      @see ishmaelRedraw
      */
     function toHtmlScriptedMap(scriptingGui)
     {
         var returner = { };
         for (var s in scriptingGui.scriptedVisMap)
             returner[s] = s;
         return returner;
     }

     function guiName()
     {
         return 'ishmaelEditor';
     }

     function getGuiText()
     {

         var returner = "sirikata.ui('" + guiName() + "',";
         returner += 'function(){ ';

         returner += @

         function ishmaelWindowId()
         {
             return 'ishmael__windowID_';
         }

         //the div that surrounds all the nearby objects.
         function nearbyListId()
         {
             return 'ishmael__nearbyListID__';
         }

         //the div that surrounds all the scripted objects.
         function scriptedListId()
         {
             return 'ishmael__scriptedListID__';
         }

         /**
          \param {String} nearbyObj (id of visible that we are
          communicating with).
          gives the div for each nearby object.
          */
         function generateNearbyDivId(nearbyObj)
         {
             var visIdDivable = divizeVisibleId(nearbyObj);
             return 'ishmael__nearbyDivID___' + visIdDivable;
         }

         /**
          \param {String} scriptedObj (id of visible that we are
          communicating with).
          gives the div for each scripted object.
          */
         function generateScriptedDivId(scriptedObj)
         {
             var visIdDivable = divizeVisibleId(scriptedObj);
             return 'ishmael__scriptedDivID___' + visIdDivable;
         }

         function divizeVisibleId(visId)
         {
             return visId.replace(':','');
         }

         $('
'   +

           '
'   +
           '
'  +

           '
'   +
           '
'  +

           '
' //end div at top.
          ).attr({id:ishmaelWindowId(),title:'ishmael'}).appendTo('body');

         var inputWindow = new sirikata.ui.window(
             '#' + ishmaelWindowId(),
                 {
	             autoOpen: true,
	             height: 'auto',
	             width: 300,
                     height: 600,
                     position: 'right'
                 }
             );
         inputWindow.show();

         ishmaelRedraw = function(nearbyObjs,scriptedObjs)
         {
             redrawNearby(nearbyObjs);
             redrawScriptedObjs(scriptedObjs);
         };

         /**
          \param {object: <string (visibleId): string (visibleId)>}
          nearbyObjs -- all objects that are in vicinity.
          */
         function redrawNearby(nearbyObjs)
         {
             var newHtml = 'Nearby presences
';
             for (var s in nearbyObjs)
             {
                 newHtml += '
';
                 newHtml += s;
                 newHtml += '
';
             }
             $('#' + nearbyListId()).html(newHtml);

             for (var s in nearbyObjs)
             {
                 $('#' + generateNearbyDivId(s)).click(
                     function()
                     {
                         sirikata.event('addVisible',s);
                     });
             }
         }

         /**
          \param {object: <string (visibleId): string(visibleId)>}
          scriptedObjs -- all objects that we have a scripting
          relationship with.
          */
         function redrawScriptedObjs(scriptedObjs)
         {
             var newHtml = 'Scripted presences
';
             for (var s in scriptedObjs)
             {
                 newHtml += '
';
                 newHtml += s;
                 newHtml += '
';
             }
             $('#' + scriptedListId()).html(newHtml);

             for (var s in scriptedObjs)
             {
                 $('#' + generateScriptedDivId(s)).click(
                     function()
                     {
                         sirikata.log('error','\\\n\\\nClicked on scripted\\\n\\\n');
                     });
             }
         }

         @;

         returner += '});';
         return returner;
     }
 })();

//do all further imports for file and gui control.
system.require('controller.em');
system.require('action.em');
system.require('console.em');
system.require('fileManagerElement.em');

(function()
 {

     /**
      @param {std.ScriptingGui.Controller}

      @param {object: <String(visibleId):visible object>} nearbyVisMap
      -- all the visible objects that satisfy scripter's proximity
      query.

      @param {object: <String(visibleId):
      std.FileManager.FileManagerElement> scriptedVisMap -- A record
      of all visibles that we have scripted at some point.

      @param {object: <int:std.ScriptingGui.Action> actionMap -- Which
      actions are selectable by scripter.

      @param {std.ScriptingGui.Console} console -- has several
      scripting events.
      */
     std.ScriptingGui =
         function(controller,nearbyVisMap,scriptedVisMap,actionMap,console)
     {
         if (typeof(simulator) == 'undefined')
         {
             throw new Error('Cannot initialize scripting gui without ' +
                             'simulator graphics.');
         }

         this.controller       = controller;
         this.nearbyVisMap     = nearbyVisMap;
         this.scriptedVisMap   = scriptedVisMap;
         this.actionMap        = actionMap;
         this.console          = console;

         this.guiMod = simulator._simulator.addGUITextModule(
             guiName(),
             getGuiText(),
             std.core.bind(guiInitFunc,undefined,this));
         this.hasInited = false;
     };

     system.require('scriptingGuiUtil.em');

     std.ScriptingGui.prototype.redraw = function()
     {
         if (!this.hasInited)
             return;

         //trigger redraw call
         this.guiMod.call(
             'ishmaelRedraw',toHtmlNearbyMap(this),toHtmlScriptedMap(this));

     };

     /**
      @param {String} visId -- Id of visible.
      */
     //called by html to add the visible with id
     std.ScriptingGui.prototype.hAddVisible = function(visId)
     {
         //already can script the visible.
         if (visId in this.scriptedVisMap)
         {
             this.console.guiEvent();
             return;
         }

         if (!(visId in this.nearbyVisMap))
         {
             //visible is no longer available.
             this.console.guiEvent();
             return;
         }

         this.controller.addVisible(this.nearbyVisMap[visId]);
     };

     std.ScriptingGui.prototype.hRemoveVisible = function(visId)
     {
         //FIXME: should finish this call
         throw new Error('FIXME: must finish hRemoveVisible call ' +
                         'in scriptingGui');
     };

     /**
      @param {std.ScriptingGui}
      */
     function guiInitFunc(scriptingGui)
     {
         scriptingGui.hasInited = true;

         //when a user clicks on any of the nearby visibles to script
         //them, want that object to move into scripted objects.
         scriptingGui.guiMod.bind(
             'addVisible',
             std.core.bind(scriptingGui.hAddVisible,scriptingGui));

         //when a user clicks to remove any of the scripted visibles
         //from scripted map, then destroy it.
         scriptingGui.guiMod.bind(
             'removeVisible',
             std.core.bind(scriptingGui.hRemoveVisible,scriptingGui));

         scriptingGui.redraw();
     }

     /**
      @returns {object: <string (visibleId): string (visibleId)>}
      scriptingGui -- Takes the list of nearby objects and turns it
      into an object that (for now) maps visibleIds to visibleIds.

      @see ishmaelRedraw
      */
     function toHtmlNearbyMap(scriptingGui)
     {
         var returner = { };
         for (var s in scriptingGui.nearbyVisMap)
             returner[s] = s;
         return returner;
     }

     /**
      @returns {object: <string (visibleId): string (visibleId)>}
      scriptingGui -- Takes the list of nearby objects and turns it
      into an object that (for now) maps visibleIds to visibleIds.

      @see ishmaelRedraw
      */
     function toHtmlScriptedMap(scriptingGui)
     {
         var returner = { };
         for (var s in scriptingGui.scriptedVisMap)
             returner[s] = s;
         return returner;
     }

     function guiName()
     {
         return 'ishmaelEditor';
     }

     function getGuiText()
     {

         var returner = "sirikata.ui('" + guiName() + "',";
         returner += 'function(){ ';

         returner += @

         function ishmaelWindowId()
         {
             return 'ishmael__windowID_';
         }

         //the div that surrounds all the nearby objects.
         function nearbyListId()
         {
             return 'ishmael__nearbyListID__';
         }

         //the div that surrounds all the scripted objects.
         function scriptedListId()
         {
             return 'ishmael__scriptedListID__';
         }

         /**
          \param {String} nearbyObj (id of visible that we are
          communicating with).
          gives the div for each nearby object.
          */
         function generateNearbyDivId(nearbyObj)
         {
             var visIdDivable = divizeVisibleId(nearbyObj);
             return 'ishmael__nearbyDivID___' + visIdDivable;
         }

         /**
          \param {String} scriptedObj (id of visible that we are
          communicating with).
          gives the div for each scripted object.
          */
         function generateScriptedDivId(scriptedObj)
         {
             var visIdDivable = divizeVisibleId(scriptedObj);
             return 'ishmael__scriptedDivID___' + visIdDivable;
         }

         function divizeVisibleId(visId)
         {
             return visId.replace(':','');
         }

         $('
'   +

           '
'   +
           '
'  +

           '
'   +
           '
'  +

           '
' //end div at top.
          ).attr({id:ishmaelWindowId(),title:'ishmael'}).appendTo('body');

         var inputWindow = new sirikata.ui.window(
             '#' + ishmaelWindowId(),
                 {
	             autoOpen: true,
	             height: 'auto',
	             width: 300,
                     height: 300,
                     position: 'right'
                 }
             );
         inputWindow.show();

         ishmaelRedraw = function(nearbyObjs,scriptedObjs)
         {
             redrawNearby(nearbyObjs);
             redrawScriptedObjs(scriptedObjs);
         };

         /**
          \param {object: <string (visibleId): string (visibleId)>}
          nearbyObjs -- all objects that are in vicinity.
          */
         function redrawNearby(nearbyObjs)
         {
             var newHtml = 'Nearby presences
';
             for (var s in nearbyObjs)
             {
                 newHtml += '
';
                 newHtml += s;
                 newHtml += '
';
             }
             $('#' + nearbyListId()).html(newHtml);

             for (var s in nearbyObjs)
             {
                 $('#' + generateNearbyDivId(s)).click(
                     function()
                     {
                         sirikata.event('addVisible',s);
                     });
             }
         }

         /**
          \param {object: <string (visibleId): string(visibleId)>}
          scriptedObjs -- all objects that we have a scripting
          relationship with.
          */
         function redrawScriptedObjs(scriptedObjs)
         {
             var newHtml = 'Scripted presences
';
             for (var s in scriptedObjs)
             {
                 newHtml += '
';
                 newHtml += s;
                 newHtml += '
';
             }
             $('#' + scriptedListId()).html(newHtml);

             for (var s in scriptedObjs)
             {
                 $('#' + generateScriptedDivId(s)).click(
                     function()
                     {
                         sirikata.log('error','\\\n\\\nClicked on scripted\\\n\\\n');
                     });
             }
         }

         @;

         returner += '});';
         return returner;
     }
 })();

//do all further imports for file and gui control.
system.require('controller.em');
system.require('action.em');
system.require('console.em');
system.require('fileManagerElement.em');


cmake: only copy files to devel space if new

@[if DEVELSPACE]@
set(_xacro_py
  @(CMAKE_CURRENT_SOURCE_DIR)/scripts/xacro
  )
@[else]@
set(_xacro_py
  ${xacro_DIR}/../../../@(CATKIN_PACKAGE_BIN_DESTINATION)/xacro
  )
@[end if]@

add_custom_target(${PROJECT_NAME}_xacro_generated_to_devel_space_ ALL)

## xacro_add_xacro_file(<input> [<output>] [INORDER] [REMAP <arg> <arg> ...]
##                      [OUTPUT <variable>])
##
## Creates a command run xacro on <input> like so:
## xacro [--inorder] -o <output> <input> [<remap args>]
##
## If <output> was not specified, it is determined from <input> removing the suffix .xacro
## The absolute output file name is returned in variable <output>, which defaults to
## XACRO_OUTPUT_FILE.
##
## In order to actually build and install, you need to provide a custom target:
## foreach(xacro_file ${MY_XACRO_FILES})
##   xacro_add_xacro_file(${xacro_file} INORDER REMAP bar:=foo foo:=bar)
##   list(APPEND xacro_outputs ${XACRO_OUTPUT_FILE})
## endforeach()
## add_custom_target(xacro_target ALL DEPENDS ${xacro_outputs})
## xacro_install(xacro_target ${xacro_outputs} DESTINATION xml)
##
## Be aware, that xacro_install() is required to install into both, install and devel space.
## Normal install() only installs into install space!
##
## For conveniency, you might want to use xacro_add_files(), which does the same:
## xacro_add_files(${MY_XACRO_FILES} INORDER REMAP bar:=foo foo:=bar
##                 TARGET xacro_target INSTALL DESTINATION xml)
function(xacro_add_xacro_file input)
  # parse arguments
  set(options INORDER)
  set(oneValueArgs OUTPUT)
  set(multiValueArgs REMAP)
  cmake_parse_arguments(_XACRO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

  ## process arguments
  # retrieve output file name
  if(_XACRO_UNPARSED_ARGUMENTS)
    # output file explicitly specified
    list(GET _XACRO_UNPARSED_ARGUMENTS 0 output)
    list(REMOVE_AT _XACRO_UNPARSED_ARGUMENTS 0)
    # any remaining unparsed args?
    if(_XACRO_UNPARSED_ARGUMENTS)
      message(WARNING "unknown arguments: ${_XACRO_UNPARSED_ARGUMENTS}")
    endif(_XACRO_UNPARSED_ARGUMENTS)
  else()
    # implicitly determine output file from input
    if(${input} MATCHES "(.*)[.]xacro$")
      set(output ${CMAKE_MATCH_1})
    else()
      message(FATAL_ERROR "no <output> specified for: " ${input})
    endif()
  endif()
  # message(STATUS "output: ${output}")

  # transform _XACRO_INORDER's BOOL value
  if(_XACRO_INORDER)
    set(_XACRO_INORDER "--inorder")
  else()
    unset(_XACRO_INORDER)
  endif()

  ## determine absolute output target location
  if(IS_ABSOLUTE ${output})
    set(abs_output ${output})
  else()
    set(abs_output ${CMAKE_CURRENT_BINARY_DIR}/${output})
  endif()
  # message(STATUS "abs_output: ${abs_output}")

  ## export abs_output to parent scope in variable ${_XACRO_OUTPUT}
  if(NOT _XACRO_OUTPUT)
    set(_XACRO_OUTPUT XACRO_OUTPUT_FILE)
  endif()
  set(${_XACRO_OUTPUT} ${abs_output} PARENT_SCOPE)

  ## Call out to xacro to determine dependencies
  message(STATUS "xacro: determining deps for: " ${input} " ...")
  execute_process(COMMAND ${_xacro_py} --deps ${input} ${_XACRO_REMAP}
    WORKING_DIRECTORY $(CMAKE_CURRENT_SOURCE_DIR)
    ERROR_VARIABLE _xacro_err
    OUTPUT_VARIABLE _xacro_deps_result
    OUTPUT_STRIP_TRAILING_WHITESPACE)
  if(_xacro_err)
    message(WARNING "failed to determine deps for: ${input}
${_xacro_err}")
  endif(_xacro_err)

  separate_arguments(_xacro_deps_result)

  ## command to actually call xacro
  add_custom_command(OUTPUT ${output}
    COMMAND ${CATKIN_ENV} ${_xacro_py} ${_XACRO_INORDER} -o ${abs_output} ${input} ${_XACRO_REMAP}
    DEPENDS ${input} ${_xacro_deps_result}
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMMENT "xacro: generating ${output} from ${input}"
    )
endfunction(xacro_add_xacro_file)

## xacro_install(<target> <output> [<output> ...] DESTINATION <path>)
##
## installs xacro-generated files both to devel and input space
## into ${CATKIN_PACKAGE_SHARE_DESTINATION}/<path>
function(xacro_install target)
  # parse arguments
  set(oneValueArgs DESTINATION)
  cmake_parse_arguments(_XACRO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  set(outputs ${_XACRO_UNPARSED_ARGUMENTS})

  ## rule to create target dir
  file(TO_CMAKE_PATH ${CATKIN_PACKAGE_SHARE_DESTINATION}/${_XACRO_DESTINATION} dest)
  file(TO_CMAKE_PATH ${CATKIN_DEVEL_PREFIX}/${dest} TARGET_DIR)
  add_custom_command(OUTPUT ${TARGET_DIR}
    COMMAND ${CMAKE_COMMAND} -E make_directory ${TARGET_DIR}
    COMMENT "creating dir ${TARGET_DIR}")

  ## process list of outputs
  foreach(output ${outputs})
    get_filename_component(tgt ${output} NAME)
    file(TO_CMAKE_PATH ${TARGET_DIR}/${tgt} tgt)
    list(APPEND tgts ${tgt})

    # rule to create devel space tgt
    add_custom_command(OUTPUT ${tgt}
      COMMAND ${CMAKE_COMMAND} -E copy_if_different ${output} ${tgt}
      DEPENDS ${TARGET_DIR} ${output}
      COMMENT "Copying to devel space: ${tgt}"
      )
  endforeach()

  ## rule to create devel space tgts
  add_custom_target(${PROJECT_NAME}_${target}_to_devel_space_ DEPENDS ${tgts})
  # add to main target _xacro_generated_to_devel_space_
  add_dependencies(${PROJECT_NAME}_xacro_generated_to_devel_space_
                   ${PROJECT_NAME}_${target}_to_devel_space_)

  ## normal install
  install(FILES ${outputs} DESTINATION ${dest})
endfunction(xacro_install)

## xacro_add_files(<file> [<file> ...] [INORDER] [REMAP <arg> <arg> ...]
##                 [TARGET <target>] [INSTALL [DESTINATION <path>]])
##
## create make <target> to generate xacro files
## and optionally install to ${CATKIN_PACKAGE_SHARE_DESTINATION}/<path>
## in devel and install space.
function(xacro_add_files)
  # parse arguments
  set(options INORDER INSTALL)
  set(oneValueArgs OUTPUT TARGET DESTINATION)
  set(multiValueArgs REMAP)
  cmake_parse_arguments(_XACRO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

  ## process arguments
  # transform _XACRO_INORDER's BOOL value
  if(_XACRO_INORDER)
    set(_XACRO_INORDER "INORDER")
  else()
    unset(_XACRO_INORDER)
  endif()

  # prepare REMAP args (prepending REMAP)
  if(_XACRO_REMAP)
    set(_XACRO_REMAP REMAP ${_XACRO_REMAP})
  endif()

  # have INSTALL option, but no TARGET: fallback to default target
  if(_XACRO_INSTALL AND NOT _XACRO_TARGET)
    # message(STATUS "xacro: no TARGET specified, using default")
    set(_XACRO_TARGET _xacro_auto_generate)
  endif()

  foreach(input ${_XACRO_UNPARSED_ARGUMENTS})
    # call to main function
    xacro_add_xacro_file(${input} ${_XACRO_OUTPUT} ${_XACRO_INORDER} ${_XACRO_REMAP})
    list(APPEND outputs ${XACRO_OUTPUT_FILE})
  endforeach()

  if(outputs)
    # link to target
    add_custom_target(${PROJECT_NAME}_${_XACRO_TARGET} ALL DEPENDS ${outputs})

    # install?
    if(_XACRO_INSTALL)
      xacro_install(${_XACRO_TARGET} ${outputs} DESTINATION ${_XACRO_DESTINATION})
    endif(_XACRO_INSTALL)
  endif()
endfunction(xacro_add_files)

@[if DEVELSPACE]@
set(_xacro_py
  @(CMAKE_CURRENT_SOURCE_DIR)/scripts/xacro
  )
@[else]@
set(_xacro_py
  ${xacro_DIR}/../../../@(CATKIN_PACKAGE_BIN_DESTINATION)/xacro
  )
@[end if]@

add_custom_target(${PROJECT_NAME}_xacro_generated_to_devel_space_ ALL)

## xacro_add_xacro_file(<input> [<output>] [INORDER] [REMAP <arg> <arg> ...]
##                      [OUTPUT <variable>])
##
## Creates a command run xacro on <input> like so:
## xacro [--inorder] -o <output> <input> [<remap args>]
##
## If <output> was not specified, it is determined from <input> removing the suffix .xacro
## The absolute output file name is returned in variable <output>, which defaults to
## XACRO_OUTPUT_FILE.
##
## In order to actually build and install, you need to provide a custom target:
## foreach(xacro_file ${MY_XACRO_FILES})
##   xacro_add_xacro_file(${xacro_file} INORDER REMAP bar:=foo foo:=bar)
##   list(APPEND xacro_outputs ${XACRO_OUTPUT_FILE})
## endforeach()
## add_custom_target(xacro_target ALL DEPENDS ${xacro_outputs})
## xacro_install(xacro_target ${xacro_outputs} DESTINATION xml)
##
## Be aware, that xacro_install() is required to install into both, install and devel space.
## Normal install() only installs into install space!
##
## For conveniency, you might want to use xacro_add_files(), which does the same:
## xacro_add_files(${MY_XACRO_FILES} INORDER REMAP bar:=foo foo:=bar
##                 TARGET xacro_target INSTALL DESTINATION xml)
function(xacro_add_xacro_file input)
  # parse arguments
  set(options INORDER)
  set(oneValueArgs OUTPUT)
  set(multiValueArgs REMAP)
  cmake_parse_arguments(_XACRO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

  ## process arguments
  # retrieve output file name
  if(_XACRO_UNPARSED_ARGUMENTS)
    # output file explicitly specified
    list(GET _XACRO_UNPARSED_ARGUMENTS 0 output)
    list(REMOVE_AT _XACRO_UNPARSED_ARGUMENTS 0)
    # any remaining unparsed args?
    if(_XACRO_UNPARSED_ARGUMENTS)
      message(WARNING "unknown arguments: ${_XACRO_UNPARSED_ARGUMENTS}")
    endif(_XACRO_UNPARSED_ARGUMENTS)
  else()
    # implicitly determine output file from input
    if(${input} MATCHES "(.*)[.]xacro$")
      set(output ${CMAKE_MATCH_1})
    else()
      message(FATAL_ERROR "no <output> specified for: " ${input})
    endif()
  endif()
  # message(STATUS "output: ${output}")

  # transform _XACRO_INORDER's BOOL value
  if(_XACRO_INORDER)
    set(_XACRO_INORDER "--inorder")
  else()
    unset(_XACRO_INORDER)
  endif()

  ## determine absolute output target location
  if(IS_ABSOLUTE ${output})
    set(abs_output ${output})
  else()
    set(abs_output ${CMAKE_CURRENT_BINARY_DIR}/${output})
  endif()
  # message(STATUS "abs_output: ${abs_output}")

  ## export abs_output to parent scope in variable ${_XACRO_OUTPUT}
  if(NOT _XACRO_OUTPUT)
    set(_XACRO_OUTPUT XACRO_OUTPUT_FILE)
  endif()
  set(${_XACRO_OUTPUT} ${abs_output} PARENT_SCOPE)

  ## Call out to xacro to determine dependencies
  message(STATUS "xacro: determining deps for: " ${input} " ...")
  execute_process(COMMAND ${_xacro_py} --deps ${input} ${_XACRO_REMAP}
    WORKING_DIRECTORY $(CMAKE_CURRENT_SOURCE_DIR)
    ERROR_VARIABLE _xacro_err
    OUTPUT_VARIABLE _xacro_deps_result
    OUTPUT_STRIP_TRAILING_WHITESPACE)
  if(_xacro_err)
    message(WARNING "failed to determine deps for: ${input}
${_xacro_err}")
  endif(_xacro_err)

  separate_arguments(_xacro_deps_result)

  ## command to actually call xacro
  add_custom_command(OUTPUT ${output}
    COMMAND ${CATKIN_ENV} ${_xacro_py} ${_XACRO_INORDER} -o ${abs_output} ${input} ${_XACRO_REMAP}
    DEPENDS ${input} ${_xacro_deps_result}
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMMENT "xacro: generating ${output} from ${input}"
    )
endfunction(xacro_add_xacro_file)

## xacro_install(<target> <output> [<output> ...] DESTINATION <path>)
##
## installs xacro-generated files both to devel and input space
## into ${CATKIN_PACKAGE_SHARE_DESTINATION}/<path>
function(xacro_install target)
  # parse arguments
  set(oneValueArgs DESTINATION)
  cmake_parse_arguments(_XACRO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  set(outputs ${_XACRO_UNPARSED_ARGUMENTS})

  ## rule to create target dir
  file(TO_CMAKE_PATH ${CATKIN_PACKAGE_SHARE_DESTINATION}/${_XACRO_DESTINATION} dest)
  file(TO_CMAKE_PATH ${CATKIN_DEVEL_PREFIX}/${dest} TARGET_DIR)
  add_custom_command(OUTPUT ${TARGET_DIR}
    COMMAND ${CMAKE_COMMAND} -E make_directory ${TARGET_DIR}
    COMMENT "creating dir ${TARGET_DIR}")

  ## process list of outputs
  foreach(output ${outputs})
    get_filename_component(tgt ${output} NAME)
    file(TO_CMAKE_PATH ${TARGET_DIR}/${tgt} tgt)
    list(APPEND tgts ${tgt})

    # rule to create devel space tgt
    add_custom_command(OUTPUT ${tgt}
      COMMAND ${CMAKE_COMMAND} -E copy ${output} ${tgt}
      DEPENDS ${TARGET_DIR} ${output}
      COMMENT "Copying to devel space: ${tgt}"
      )
  endforeach()

  ## rule to create devel space tgts
  add_custom_target(${PROJECT_NAME}_${target}_to_devel_space_ DEPENDS ${tgts})
  # add to main target _xacro_generated_to_devel_space_
  add_dependencies(${PROJECT_NAME}_xacro_generated_to_devel_space_
                   ${PROJECT_NAME}_${target}_to_devel_space_)

  ## normal install
  install(FILES ${outputs} DESTINATION ${dest})
endfunction(xacro_install)

## xacro_add_files(<file> [<file> ...] [INORDER] [REMAP <arg> <arg> ...]
##                 [TARGET <target>] [INSTALL [DESTINATION <path>]])
##
## create make <target> to generate xacro files
## and optionally install to ${CATKIN_PACKAGE_SHARE_DESTINATION}/<path>
## in devel and install space.
function(xacro_add_files)
  # parse arguments
  set(options INORDER INSTALL)
  set(oneValueArgs OUTPUT TARGET DESTINATION)
  set(multiValueArgs REMAP)
  cmake_parse_arguments(_XACRO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

  ## process arguments
  # transform _XACRO_INORDER's BOOL value
  if(_XACRO_INORDER)
    set(_XACRO_INORDER "INORDER")
  else()
    unset(_XACRO_INORDER)
  endif()

  # prepare REMAP args (prepending REMAP)
  if(_XACRO_REMAP)
    set(_XACRO_REMAP REMAP ${_XACRO_REMAP})
  endif()

  # have INSTALL option, but no TARGET: fallback to default target
  if(_XACRO_INSTALL AND NOT _XACRO_TARGET)
    # message(STATUS "xacro: no TARGET specified, using default")
    set(_XACRO_TARGET _xacro_auto_generate)
  endif()

  foreach(input ${_XACRO_UNPARSED_ARGUMENTS})
    # call to main function
    xacro_add_xacro_file(${input} ${_XACRO_OUTPUT} ${_XACRO_INORDER} ${_XACRO_REMAP})
    list(APPEND outputs ${XACRO_OUTPUT_FILE})
  endforeach()

  if(outputs)
    # link to target
    add_custom_target(${PROJECT_NAME}_${_XACRO_TARGET} ALL DEPENDS ${outputs})

    # install?
    if(_XACRO_INSTALL)
      xacro_install(${_XACRO_TARGET} ${outputs} DESTINATION ${_XACRO_DESTINATION})
    endif(_XACRO_INSTALL)
  endif()
endfunction(xacro_add_files)


fix generated order_packages.cmake to contain path with forward slashes only (ros-infrastructure/catkin_pkg#35)

# generated from catkin/cmake/em/order_packages.cmake.em
@{
import os
try:
    from catkin_pkg.cmake import get_metapackage_cmake_template_path
except ImportError as e:
    raise RuntimeError('ImportError: "from catkin_pkg.cmake import get_metapackage_cmake_template_path" failed: %s\nMake sure that you have installed "catkin_pkg", it is up to date and on the PYTHONPATH.' % e)
try:
    from catkin_pkg.topological_order import topological_order
except ImportError as e:
    raise RuntimeError('ImportError: "from catkin_pkg.topological_order import topological_order" failed: %s\nMake sure that you have installed "catkin_pkg", it is up to date and on the PYTHONPATH.' % e)
# vars defined in order_packages.context.py.in
ordered_packages = topological_order(os.path.normpath(source_root_dir), whitelisted_packages, blacklisted_packages)
fatal_error = False
}@

set(CATKIN_ORDERED_PACKAGES "")
set(CATKIN_ORDERED_PACKAGE_PATHS "")
set(CATKIN_ORDERED_PACKAGES_IS_META "")
set(CATKIN_ORDERED_PACKAGES_BUILD_TYPE "")
@[for path, package in ordered_packages]@
@[if path is None]@
message(FATAL_ERROR "Circular dependency in subset of packages:\n@package")
@{
fatal_error = True
}@
@[elif package.name != 'catkin']@
list(APPEND CATKIN_ORDERED_PACKAGES "@(package.name)")
list(APPEND CATKIN_ORDERED_PACKAGE_PATHS "@(path.replace('\\','/'))")
list(APPEND CATKIN_ORDERED_PACKAGES_IS_META "@(str('metapackage' in [e.tagname for e in package.exports]))")
list(APPEND CATKIN_ORDERED_PACKAGES_BUILD_TYPE "@(str([e.content for e in package.exports if e.tagname == 'build_type'][0]) if 'build_type' in [e.tagname for e in package.exports] else 'catkin')")
@{
deprecated = [e for e in package.exports if e.tagname == 'deprecated']
}@
@[if deprecated]@
message("WARNING: Package '@(package.name)' is deprecated@(' (%s)' % deprecated[0].content if deprecated[0].content else '')")
@[end if]@
@[end if]@
@[end for]@

@[if not fatal_error]@
@{
message_generators = [package.name for (_, package) in ordered_packages if 'message_generator' in [e.tagname for e in package.exports]]
}@
set(CATKIN_MESSAGE_GENERATORS @(' '.join(message_generators)))
@[end if]@

set(CATKIN_METAPACKAGE_CMAKE_TEMPLATE "@(get_metapackage_cmake_template_path().replace('\\','/'))")

# generated from catkin/cmake/em/order_packages.cmake.em
@{
import os
try:
    from catkin_pkg.cmake import get_metapackage_cmake_template_path
except ImportError as e:
    raise RuntimeError('ImportError: "from catkin_pkg.cmake import get_metapackage_cmake_template_path" failed: %s\nMake sure that you have installed "catkin_pkg", it is up to date and on the PYTHONPATH.' % e)
try:
    from catkin_pkg.topological_order import topological_order
except ImportError as e:
    raise RuntimeError('ImportError: "from catkin_pkg.topological_order import topological_order" failed: %s\nMake sure that you have installed "catkin_pkg", it is up to date and on the PYTHONPATH.' % e)
# vars defined in order_packages.context.py.in
ordered_packages = topological_order(os.path.normpath(source_root_dir), whitelisted_packages, blacklisted_packages)
fatal_error = False
}@

set(CATKIN_ORDERED_PACKAGES "")
set(CATKIN_ORDERED_PACKAGE_PATHS "")
set(CATKIN_ORDERED_PACKAGES_IS_META "")
set(CATKIN_ORDERED_PACKAGES_BUILD_TYPE "")
@[for path, package in ordered_packages]@
@[if path is None]@
message(FATAL_ERROR "Circular dependency in subset of packages:\n@package")
@{
fatal_error = True
}@
@[elif package.name != 'catkin']@
list(APPEND CATKIN_ORDERED_PACKAGES "@(package.name)")
list(APPEND CATKIN_ORDERED_PACKAGE_PATHS "@(path.replace('\\','/'))")
list(APPEND CATKIN_ORDERED_PACKAGES_IS_META "@(str('metapackage' in [e.tagname for e in package.exports]))")
list(APPEND CATKIN_ORDERED_PACKAGES_BUILD_TYPE "@(str([e.content for e in package.exports if e.tagname == 'build_type'][0]) if 'build_type' in [e.tagname for e in package.exports] else 'catkin')")
@{
deprecated = [e for e in package.exports if e.tagname == 'deprecated']
}@
@[if deprecated]@
message("WARNING: Package '@(package.name)' is deprecated@(' (%s)' % deprecated[0].content if deprecated[0].content else '')")
@[end if]@
@[end if]@
@[end for]@

@[if not fatal_error]@
@{
message_generators = [package.name for (_, package) in ordered_packages if 'message_generator' in [e.tagname for e in package.exports]]
}@
set(CATKIN_MESSAGE_GENERATORS @(' '.join(message_generators)))
@[end if]@

set(CATKIN_METAPACKAGE_CMAKE_TEMPLATE "@(get_metapackage_cmake_template_path())")


Fix the workaround for combobox menus which got lost.

${
import math

def my_floor(num):
    return int(math.floor(num))

def my_ceil(num):
    return int(math.ceil(num))

# Should we set the line width in the engine to 2.25, and draw non pixel aligned lines?
# Are these already the correct sizes for the XO?

# These sizes need to be sanity checked ...
if theme == "sugar-xo":
    xo = True
    line_width = 2.25       # 2.25
    thick_line_width = 3.5  # 3.5
    subcell_size = 15
    bullet_size = 9.5
    font_height = 24
    default_padding = 6
else: # About 50% smaller
    xo = False
    line_width = 1.125
    thick_line_width = 1.75
    subcell_size = 7
    bullet_size = 5
    font_height = 12
    default_padding = 3

radio_size = my_floor(subcell_size + bullet_size + line_width)
scale_slider_width = my_floor(2 * subcell_size + line_width)
thickness = my_ceil(line_width)

# Colors:

black = '"#000000"'
toolbar_grey = '"#404040"'
button_grey = '"#808080"'
selection_grey = '"#A6A6A6"'
panel_grey = '"#C0C0C0"'
text_field_grey = '"#E5E5E5"'
white = '"#FFFFFF"'

}
style "default"
{
    # Will be overriden in some widgets
    color["focus_line"] = $white

    bg[NORMAL] = $button_grey
    bg[PRELIGHT] = $button_grey
    bg[ACTIVE] = $white
    bg[SELECTED] = $text_field_grey

    fg[NORMAL]        = $black
    fg[ACTIVE]        = $black
    fg[SELECTED]      = $white
    fg[PRELIGHT]      = $white

    text[NORMAL] = $black # button_grey? 1. need to patch GTK+ to use ACTIVE when focused, 2. what color should this really be?
    text[ACTIVE] = $black
    text[SELECTED] = $black
    text[PRELIGHT] = $black

    base[NORMAL] = $text_field_grey
    base[ACTIVE] = $white
    base[SELECTED] = $selection_grey
    base[PRELIGHT] = $white

    fg[INSENSITIVE] = $button_grey
    text[INSENSITIVE] = $button_grey

    xthickness = $thickness
    ythickness = $thickness

    # A lot of these will probably need to be changed, but this has to
    # be done when the exact sizes are known
    GtkWidget::interior-focus = 0
    GtkWidget::focus-line-width = 1   # This does not do anything really
    GtkWidget::focus-padding = 0
    # 0.05 works good for both the sugar and sugar-xo themes
    GtkWidget::cursor-aspect-ratio = 0.05

    GtkWidget::wide-separators = 0
    GtkWidget::separator-height = $thickness
    GtkWidget::separator-width = $thickness

    GtkRange::activate-slider = 1
    GtkButton::inner-border = { 6, 6, 6, 6 }           # ??

    GtkButton::default-border = { 1, 1, 1, 1 }         # line_width - focus-line-width
    GtkButton::default-outside-border = { 2, 2, 2, 2 } # focus-line-width

    GtkScrolledWindow::scrollbar-spacing = 0

    GtkExpander::expander-size = 24
    GtkExpander::expander-spacing = 2     # XXX

    GtkTreeView::expander-size = 24

    GtkArrow::arrow-size = 1.0

    GtkToolbar::shadow-type = GTK_SHADOW_NONE

    GtkProgressBar::min-horizontal-bar-height = $subcell_size
    GtkProgressBar::min-vertical-bar-width = $subcell_size

    engine "sugar" {
        line_width = $line_width
        thick_line_width = $thick_line_width

        # Not sure about this one, but it is not that important
        max_radius = $( 2*subcell_size )
    }
}

#############################################################
# Styles that set default background/foreground colors
#
#  We almost always need two styles because of the X windows.
#  For example bg[NORMAL] of a window (or eventbox) needs to
#  be set to be the correct window color so that X fills the
#  window correctly from the beginning, and it does not
#  flash in the wrong color.
#############################################################

style "window"
{
    bg[NORMAL] = $panel_grey
}

style "window-child"
{
    bg[INSENSITIVE] = $panel_grey
    base[INSENSITIVE] = $panel_grey

    fg[NORMAL] = $black

    engine "sugar" {
        label_fg_color = $black
    }
}

style "groupbox-panel"
{
    bg[NORMAL] = $selection_grey
}

style "groupbox-panel-child"
{
    bg[INSENSITIVE] = $selection_grey
    base[INSENSITIVE] = $selection_grey

    fg[NORMAL] = $white

    engine "sugar" {
        label_fg_color = $white
    }
}

style "groupbox-palette"
{
    bg[NORMAL] = $toolbar_grey
}

style "groupbox-palette-child"
{
    bg[INSENSITIVE] = $toolbar_grey
    base[INSENSITIVE] = $toolbar_grey

    fg[NORMAL] = $white

    engine "sugar" {
        label_fg_color = $white
    }
}

style "menu"
{
    bg[NORMAL] = $black
    bg[ACTIVE] = $button_grey

    GtkMenu::horizontal-padding = 0
    GtkMenu::vertical-padding   = 0

    xthickness = 0
    ythickness = 0
}

# Can this all be moved in the menuitem style?
style "menu-child"
{
    color["bg_color"] = $black

    fg[NORMAL]   = $white
    fg[PRELIGHT] = $white

    # Work around bug #382646
    text[NORMAL]   = $white
    text[PRELIGHT] = $white

    bg[NORMAL] = $button_grey

    bg[INSENSITIVE] = $black
    base[INSENSITIVE] = $black

    engine "sugar" {
        label_fg_color = $white
    }
}

#########################################################
#########################################################

style "scrollbar"
{
    GtkScrollbar::slider-width = 16    # ?
    GtkScrollbar::trough-border = 0
    GtkScrollbar::stepper-spacing = 0
    GtkScrollbar::min-slider-length = 30    # ?
    GtkScrollbar::has-forward-stepper = 0
    GtkScrollbar::has-backward-stepper = 0
    GtkScrollbar::has-secondary-forward-stepper = 0
    GtkScrollbar::has-secondary-backward-stepper = 0

    # Hack for mozilla as it does not obey the above style properties ...
    # Really, mozilla should be fixed ...
    GtkScrollbar::stepper-size = 1
}

# hints for the trough padding hacks
# We cannot go trough GTK+, as we don't want a padding on all sides, but only one
# If we wanted padding on all sides, trough-border would work great.
style "hscrollbar" = "scrollbar"
{
    engine "sugar" {
        hint = "hscrollbar"
        # Rounded, not floating point value. maybe change this?
        scrollbar_border = $thickness
    }
}

style "vscrollbar" = "scrollbar"
{
    engine "sugar" {
        hint = "vscrollbar"
        scrollbar_border = $thickness
    }
}

style "scale"
{
    GtkWidget::focus-line-width = 0

    bg[NORMAL] = "#808080"

    # "square" slider (really round of course)
    # Same as indicator-size?
    GtkRange::slider-width = $scale_slider_width
    GtkScale::slider-length = $scale_slider_width
    GtkRange::trough-border = 0
    GtkRange::stepper-spacing = 0
    GtkRange::trough-side-details = 1
}

# hints for the trough sizing hacks
style "hscale" = "scale"
{
    engine "sugar" {
        hint = "hscale"
    }
}

style "vscale" = "scale"
{
    engine "sugar" {
        hint = "vscale"
    }
}

style "spinbutton"
{
    bg[NORMAL]  = $button_grey
    bg[ACTIVE]  = $white
    fg[NORMAL]  = $white
    fg[ACTIVE]  = $black

    engine "sugar" {
        hint = "spinbutton"
    }
}

style "comboboxentry"
{
    # Copied from the "default" style. Part of the workaround for bug #382646.
    text[NORMAL] = $black
    text[ACTIVE] = $black
    text[SELECTED] = $black
    text[PRELIGHT] = $black

    engine "sugar" {
        hint = "comboboxentry"
    }
}

style "frame"
{
    bg[NORMAL] = $toolbar_grey
}

style "notebook"
{
    GtkNotebook::tab-overlap = -2

    xthickness = 0
    ythickness = 0

    bg[ACTIVE] = $button_grey
}

style "toolbutton"
{
    color["focus_line"] = $black

    bg[PRELIGHT] = $black
    bg[ACTIVE] = $button_grey

    fg[NORMAL] = $white
    fg[ACTIVE] = $white
    fg[PRELIGHT] = $white

    engine "sugar" {
        max_radius = 5.0
	fake_padding = $default_padding
    }
}

style "toolbox"
{
    fg[NORMAL] = $white
    fg[ACTIVE] = $white

    bg[NORMAL] = $toolbar_grey
    bg[INSENSITIVE] = $toolbar_grey
    base[INSENSITIVE] = $toolbar_grey
}

style "panel"
{
    bg[NORMAL] = $panel_grey
    fg[NORMAL] = $black
}

style "entry"
{
    # small inner border and a large x/ythickness for entries
    # to reduce the number of hacks needed :-)
    xthickness = $(thickness*3)
    ythickness = $(thickness*3)

    # This tries to get a height of exactly 45 pixel for the entry.
    GtkEntry::inner-border = { $(max(subcell_size - thickness*3, 0)), $(max(subcell_size - thickness*3, 0)),
                               $(max(my_floor((3*subcell_size - font_height - thickness*3*2)/2),0)), $(max(my_ceil((3*subcell_size - font_height - thickness*3*2)/2), 0)) }

    GtkWidget::focus-line-width = 0
}

style "button"
{
    fg[NORMAL]  = $white

    bg[NORMAL] = $button_grey
}

style "combobox"
{
    # Work around GTK+ bug #382646
    text[NORMAL]      = $white
    text[ACTIVE]      = $white
    text[PRELIGHT]    = $white
}

style "checkbutton"
{
    base[NORMAL]      = $white
    base[PRELIGHT]    = $white
    base[ACTIVE]      = $text_field_grey

    text[PRELIGHT]    = $toolbar_grey
    text[NORMAL]      = $toolbar_grey
    text[ACTIVE]      = $toolbar_grey

    # I won't get the exact sizing, but this should be pretty close
    GtkCheckButton::indicator-size = $radio_size
    GtkCheckButton::indicator-spacing = 3
    GtkWidget::focus-padding = 3

    engine "sugar" {
        # Reset the colors to the normal color again
        # as they were overriden by the button style
        fg[NORMAL]        = label_fg_color
        fg[PRELIGHT]      = label_fg_color
        fg[ACTIVE]        = label_fg_color
    }
}

style "progressbar"
{
    xthickness = 0
    ythickness = 0
}

style "menuitem"
{
    GtkCheckMenuItem::indicator-size = $radio_size

    bg[PRELIGHT] = $button_grey

    text[PRELIGHT]    = $white
    text[NORMAL]      = $white
    text[ACTIVE]      = $white

    GtkMenuItem::horizontal-padding = $line_width
    xthickness = $(my_ceil(line_width * 2))
    ythickness = $thickness
}

style "checkmenuitem"
{
    # This style is only there because of bug #382646 ...
    base[NORMAL]      = $white
    base[PRELIGHT]    = $white
    base[ACTIVE]      = $text_field_grey

    text[PRELIGHT]    = $toolbar_grey
    text[NORMAL]      = $toolbar_grey
    text[ACTIVE]      = $toolbar_grey
}

style "separatormenuitem"
{
    GtkMenuItem::horizontal-padding = 0
    xthickness = 0
}

####################################################################
# Default style, setting some generic options and style properties
####################################################################
class "GtkWidget" style "default"

####################################################################
# Styles that apply the different background (and foreground) colors
####################################################################

# This one should probably be the default (ie. no window-child style)
widget_class "<GtkWindow>"               style "window"
widget_class "<GtkWindow>*<GtkEventBox>" style "window"
widget_class "<GtkWindow>*"              style "window-child"

# SugarToolbox
#widget_class "*<SugarToolbox>" style "toolbox"
#widget_class "*<SugarToolbox>*" style "toolbox-child"
#widget_class "*<SugarToolbox>*<GtkEventBox>" style "toolbox"
widget_class "*<SugarToolbox>*"        style "toolbox"
widget_class "*<GtkToolbar>*"          style "toolbox"

# SugarPalette
widget_class "<SugarPalette>"          style "menu"
widget_class "<SugarPalette>.*"        style "menu-child"

# SugarFrameWindow
widget_class "*<SugarFrameWindow>*"    style "frame"

# SugarPanel
widget_class "*<SugarPanel>*"          style "panel"

# GroupBoxes (don't set bg[NORMAL] on the widget itself)
widget_class "<GtkWindow>*<SugarGroupBox>*<GtkEventBox>" style "groupbox-panel"
widget_class "<GtkWindow>*<SugarGroupBox>*"   style "groupbox-panel-child"

widget_class "<SugarPalette>*<SugarGroupBox>*<GtkEventBox>" style "groupbox-palette"
widget_class "<SugarPalette>*<SugarGroupBox>*"   style "groupbox-palette-child"

####################################################################
# Normal widget styles, using the above things
####################################################################
# The following only uses widget_class matches to get the priority
# right. An alternative would be to lower the priority of the
# background matches (which need widget_class) to eg. "application"

# Toolbar
widget_class "*<GtkToolButton>*"          style "toolbutton"

# Menu
widget_class "*<GtkMenuShell>"            style "menu"               # Why is this menu shell?
widget_class "*<GtkMenuShell>.*"          style "menu-child"         # Why is this menu shell?
widget_class "*<GtkMenuItem>*"            style "menuitem"
widget_class "*<GtkCheckMenuItem>"        style "checkmenuitem"
widget_class "*<GtkSeparatorMenuItem>*"   style "separatormenuitem"

# Buttons and Combos
widget_class "*<GtkComboBox>*"         style "combobox"
widget_class "*<GtkComboBoxEntry>*"    style "comboboxentry"
widget_class "*<GtkCombo>*"            style "comboboxentry"
widget_class "*<GtkButton>*"           style "button"
widget_class "*<GtkCheckButton>*"      style "checkbutton"

# Entries
widget_class "*<GtkEntry>"       style "entry"
widget_class "*<GtkSpinButton>"  style "spinbutton"

# Misc widgets
widget_class "*<GtkNotebook>"    style "notebook"
widget_class "*<GtkHScrollbar>"  style "hscrollbar"
widget_class "*<GtkVScrollbar>"  style "vscrollbar"
widget_class "*<GtkHScale>"      style "hscale"
widget_class "*<GtkVScale>"      style "vscale"
widget_class "*<GtkProgressBar>" style "progressbar"

${
import math

def my_floor(num):
    return int(math.floor(num))

def my_ceil(num):
    return int(math.ceil(num))

# Should we set the line width in the engine to 2.25, and draw non pixel aligned lines?
# Are these already the correct sizes for the XO?

# These sizes need to be sanity checked ...
if theme == "sugar-xo":
    xo = True
    line_width = 2.25       # 2.25
    thick_line_width = 3.5  # 3.5
    subcell_size = 15
    bullet_size = 9.5
    font_height = 24
    default_padding = 6
else: # About 50% smaller
    xo = False
    line_width = 1.125
    thick_line_width = 1.75
    subcell_size = 7
    bullet_size = 5
    font_height = 12
    default_padding = 3

radio_size = my_floor(subcell_size + bullet_size + line_width)
scale_slider_width = my_floor(2 * subcell_size + line_width)
thickness = my_ceil(line_width)

# Colors:

black = '"#000000"'
toolbar_grey = '"#404040"'
button_grey = '"#808080"'
selection_grey = '"#A6A6A6"'
panel_grey = '"#C0C0C0"'
text_field_grey = '"#E5E5E5"'
white = '"#FFFFFF"'

}
style "default"
{
    # Will be overriden in some widgets
    color["focus_line"] = $white

    bg[NORMAL] = $button_grey
    bg[PRELIGHT] = $button_grey
    bg[ACTIVE] = $white
    bg[SELECTED] = $text_field_grey

    fg[NORMAL]        = $black
    fg[ACTIVE]        = $black
    fg[SELECTED]      = $white
    fg[PRELIGHT]      = $white

    text[NORMAL] = $black # button_grey? 1. need to patch GTK+ to use ACTIVE when focused, 2. what color should this really be?
    text[ACTIVE] = $black
    text[SELECTED] = $black
    text[PRELIGHT] = $black

    base[NORMAL] = $text_field_grey
    base[ACTIVE] = $white
    base[SELECTED] = $selection_grey
    base[PRELIGHT] = $white

    fg[INSENSITIVE] = $button_grey
    text[INSENSITIVE] = $button_grey

    xthickness = $thickness
    ythickness = $thickness

    # A lot of these will probably need to be changed, but this has to
    # be done when the exact sizes are known
    GtkWidget::interior-focus = 0
    GtkWidget::focus-line-width = 1   # This does not do anything really
    GtkWidget::focus-padding = 0
    # 0.05 works good for both the sugar and sugar-xo themes
    GtkWidget::cursor-aspect-ratio = 0.05

    GtkWidget::wide-separators = 0
    GtkWidget::separator-height = $thickness
    GtkWidget::separator-width = $thickness

    GtkRange::activate-slider = 1
    GtkButton::inner-border = { 6, 6, 6, 6 }           # ??

    GtkButton::default-border = { 1, 1, 1, 1 }         # line_width - focus-line-width
    GtkButton::default-outside-border = { 2, 2, 2, 2 } # focus-line-width

    GtkScrolledWindow::scrollbar-spacing = 0

    GtkExpander::expander-size = 24
    GtkExpander::expander-spacing = 2     # XXX

    GtkTreeView::expander-size = 24

    GtkArrow::arrow-size = 1.0

    GtkToolbar::shadow-type = GTK_SHADOW_NONE

    GtkProgressBar::min-horizontal-bar-height = $subcell_size
    GtkProgressBar::min-vertical-bar-width = $subcell_size

    engine "sugar" {
        line_width = $line_width
        thick_line_width = $thick_line_width

        # Not sure about this one, but it is not that important
        max_radius = $( 2*subcell_size )
    }
}

#############################################################
# Styles that set default background/foreground colors
#
#  We almost always need two styles because of the X windows.
#  For example bg[NORMAL] of a window (or eventbox) needs to
#  be set to be the correct window color so that X fills the
#  window correctly from the beginning, and it does not
#  flash in the wrong color.
#############################################################

style "window"
{
    bg[NORMAL] = $panel_grey
}

style "window-child"
{
    bg[INSENSITIVE] = $panel_grey
    base[INSENSITIVE] = $panel_grey

    fg[NORMAL] = $black

    engine "sugar" {
        label_fg_color = $black
    }
}

style "groupbox-panel"
{
    bg[NORMAL] = $selection_grey
}

style "groupbox-panel-child"
{
    bg[INSENSITIVE] = $selection_grey
    base[INSENSITIVE] = $selection_grey

    fg[NORMAL] = $white

    engine "sugar" {
        label_fg_color = $white
    }
}

style "groupbox-palette"
{
    bg[NORMAL] = $toolbar_grey
}

style "groupbox-palette-child"
{
    bg[INSENSITIVE] = $toolbar_grey
    base[INSENSITIVE] = $toolbar_grey

    fg[NORMAL] = $white

    engine "sugar" {
        label_fg_color = $white
    }
}

style "menu"
{
    bg[NORMAL] = $black
    bg[ACTIVE] = $button_grey

    GtkMenu::horizontal-padding = 0
    GtkMenu::vertical-padding   = 0

    xthickness = 0
    ythickness = 0
}

# Can this all be moved in the menuitem style?
style "menu-child"
{
    color["bg_color"] = $black

    fg[NORMAL]   = $white
    fg[PRELIGHT] = $white
    bg[NORMAL] = $button_grey

    bg[INSENSITIVE] = $black
    base[INSENSITIVE] = $black

    engine "sugar" {
        label_fg_color = $white
    }
}

#########################################################
#########################################################

style "scrollbar"
{
    GtkScrollbar::slider-width = 16    # ?
    GtkScrollbar::trough-border = 0
    GtkScrollbar::stepper-spacing = 0
    GtkScrollbar::min-slider-length = 30    # ?
    GtkScrollbar::has-forward-stepper = 0
    GtkScrollbar::has-backward-stepper = 0
    GtkScrollbar::has-secondary-forward-stepper = 0
    GtkScrollbar::has-secondary-backward-stepper = 0

    # Hack for mozilla as it does not obey the above style properties ...
    # Really, mozilla should be fixed ...
    GtkScrollbar::stepper-size = 1
}

# hints for the trough padding hacks
# We cannot go trough GTK+, as we don't want a padding on all sides, but only one
# If we wanted padding on all sides, trough-border would work great.
style "hscrollbar" = "scrollbar"
{
    engine "sugar" {
        hint = "hscrollbar"
        # Rounded, not floating point value. maybe change this?
        scrollbar_border = $thickness
    }
}

style "vscrollbar" = "scrollbar"
{
    engine "sugar" {
        hint = "vscrollbar"
        scrollbar_border = $thickness
    }
}

style "scale"
{
    GtkWidget::focus-line-width = 0

    bg[NORMAL] = "#808080"

    # "square" slider (really round of course)
    # Same as indicator-size?
    GtkRange::slider-width = $scale_slider_width
    GtkScale::slider-length = $scale_slider_width
    GtkRange::trough-border = 0
    GtkRange::stepper-spacing = 0
    GtkRange::trough-side-details = 1
}

# hints for the trough sizing hacks
style "hscale" = "scale"
{
    engine "sugar" {
        hint = "hscale"
    }
}

style "vscale" = "scale"
{
    engine "sugar" {
        hint = "vscale"
    }
}

style "spinbutton"
{
    bg[NORMAL]  = $button_grey
    bg[ACTIVE]  = $white
    fg[NORMAL]  = $white
    fg[ACTIVE]  = $black

    engine "sugar" {
        hint = "spinbutton"
    }
}

style "comboboxentry"
{
    # Copied from the "default" style. Part of the workaround for bug #382646.
    text[NORMAL] = $black
    text[ACTIVE] = $black
    text[SELECTED] = $black
    text[PRELIGHT] = $black

    engine "sugar" {
        hint = "comboboxentry"
    }
}

style "frame"
{
    bg[NORMAL] = $toolbar_grey
}

style "notebook"
{
    GtkNotebook::tab-overlap = -2

    xthickness = 0
    ythickness = 0

    bg[ACTIVE] = $button_grey
}

style "toolbutton"
{
    color["focus_line"] = $black

    bg[PRELIGHT] = $black
    bg[ACTIVE] = $button_grey

    fg[NORMAL] = $white
    fg[ACTIVE] = $white
    fg[PRELIGHT] = $white

    engine "sugar" {
        max_radius = 5.0
	fake_padding = $default_padding
    }
}

style "toolbox"
{
    fg[NORMAL] = $white
    fg[ACTIVE] = $white

    bg[NORMAL] = $toolbar_grey
    bg[INSENSITIVE] = $toolbar_grey
    base[INSENSITIVE] = $toolbar_grey
}

style "panel"
{
    bg[NORMAL] = $panel_grey
    fg[NORMAL] = $black
}

style "entry"
{
    # small inner border and a large x/ythickness for entries
    # to reduce the number of hacks needed :-)
    xthickness = $(thickness*3)
    ythickness = $(thickness*3)

    # This tries to get a height of exactly 45 pixel for the entry.
    GtkEntry::inner-border = { $(max(subcell_size - thickness*3, 0)), $(max(subcell_size - thickness*3, 0)),
                               $(max(my_floor((3*subcell_size - font_height - thickness*3*2)/2),0)), $(max(my_ceil((3*subcell_size - font_height - thickness*3*2)/2), 0)) }

    GtkWidget::focus-line-width = 0
}

style "button"
{
    fg[NORMAL]  = $white

    bg[NORMAL] = $button_grey
}

style "combobox"
{
    # Work around GTK+ bug #382646
    text[NORMAL]      = $white
    text[ACTIVE]      = $white
    text[PRELIGHT]    = $white
}

style "checkbutton"
{
    base[NORMAL]      = $white
    base[PRELIGHT]    = $white
    base[ACTIVE]      = $text_field_grey

    text[PRELIGHT]    = $toolbar_grey
    text[NORMAL]      = $toolbar_grey
    text[ACTIVE]      = $toolbar_grey

    # I won't get the exact sizing, but this should be pretty close
    GtkCheckButton::indicator-size = $radio_size
    GtkCheckButton::indicator-spacing = 3
    GtkWidget::focus-padding = 3

    engine "sugar" {
        # Reset the colors to the normal color again
        # as they were overriden by the button style
        fg[NORMAL]        = label_fg_color
        fg[PRELIGHT]      = label_fg_color
        fg[ACTIVE]        = label_fg_color
    }
}

style "progressbar"
{
    xthickness = 0
    ythickness = 0
}

style "menuitem"
{
    GtkCheckMenuItem::indicator-size = $radio_size

    bg[PRELIGHT] = $button_grey

    # The following colors are for the check and radio menu items
    base[NORMAL]      = $white
    base[PRELIGHT]    = $white
    base[ACTIVE]      = $text_field_grey

    text[PRELIGHT]    = $toolbar_grey
    text[NORMAL]      = $toolbar_grey
    text[ACTIVE]      = $toolbar_grey

    GtkMenuItem::horizontal-padding = $line_width
    xthickness = $(my_ceil(line_width * 2))
    ythickness = $thickness
}

style "separatormenuitem"
{
    GtkMenuItem::horizontal-padding = 0
    xthickness = 0
}

####################################################################
# Default style, setting some generic options and style properties
####################################################################
class "GtkWidget" style "default"

####################################################################
# Styles that apply the different background (and foreground) colors
####################################################################

# This one should probably be the default (ie. no window-child style)
widget_class "<GtkWindow>"               style "window"
widget_class "<GtkWindow>*<GtkEventBox>" style "window"
widget_class "<GtkWindow>*"              style "window-child"

# SugarToolbox
#widget_class "*<SugarToolbox>" style "toolbox"
#widget_class "*<SugarToolbox>*" style "toolbox-child"
#widget_class "*<SugarToolbox>*<GtkEventBox>" style "toolbox"
widget_class "*<SugarToolbox>*"        style "toolbox"
widget_class "*<GtkToolbar>*"          style "toolbox"

# SugarPalette
widget_class "<SugarPalette>"          style "menu"
widget_class "<SugarPalette>.*"        style "menu-child"

# SugarFrameWindow
widget_class "*<SugarFrameWindow>*"    style "frame"

# SugarPanel
widget_class "*<SugarPanel>*"          style "panel"

# GroupBoxes (don't set bg[NORMAL] on the widget itself)
widget_class "<GtkWindow>*<SugarGroupBox>*<GtkEventBox>" style "groupbox-panel"
widget_class "<GtkWindow>*<SugarGroupBox>*"   style "groupbox-panel-child"

widget_class "<SugarPalette>*<SugarGroupBox>*<GtkEventBox>" style "groupbox-palette"
widget_class "<SugarPalette>*<SugarGroupBox>*"   style "groupbox-palette-child"

####################################################################
# Normal widget styles, using the above things
####################################################################
# The following only uses widget_class matches to get the priority
# right. An alternative would be to lower the priority of the
# background matches (which need widget_class) to eg. "application"

# Toolbar
widget_class "*<GtkToolButton>*"          style "toolbutton"

# Menu
widget_class "*<GtkMenuShell>"            style "menu"               # Why is this menu shell?
widget_class "*<GtkMenuShell>.*"          style "menu-child"         # Why is this menu shell?
widget_class "*<GtkMenuItem>*"            style "menuitem"
widget_class "*<GtkSeparatorMenuItem>*"   style "separatormenuitem"

# Buttons and Combos
widget_class "*<GtkComboBox>*"         style "combobox"
widget_class "*<GtkComboBoxEntry>*"    style "comboboxentry"
widget_class "*<GtkCombo>*"            style "comboboxentry"
widget_class "*<GtkButton>*"           style "button"
widget_class "*<GtkCheckButton>*"      style "checkbutton"

# Entries
widget_class "*<GtkEntry>"       style "entry"
widget_class "*<GtkSpinButton>"  style "spinbutton"

# Misc widgets
widget_class "*<GtkNotebook>"    style "notebook"
widget_class "*<GtkHScrollbar>"  style "hscrollbar"
widget_class "*<GtkVScrollbar>"  style "vscrollbar"
widget_class "*<GtkHScale>"      style "hscale"
widget_class "*<GtkVScale>"      style "vscale"
widget_class "*<GtkProgressBar>" style "progressbar"


ROS apt repo only has ubuntu url hard coding ubuntu in URL path

@(TEMPLATE(
    'snippet/add_generated_comment.Dockerfile.em',
    user_name=user_name,
    tag_name=tag_name,
    source_template_name=template_name,
))@
@(TEMPLATE(
    'snippet/from_base_image.Dockerfile.em',
    template_packages=template_packages,
    os_name=os_name,
    os_code_name=os_code_name,
    arch=arch,
    base_image=base_image,
    maintainer_name=maintainer_name,
))@

@[if 'packages' in locals()]@
@[if packages]@

# install packages
RUN apt-get update && apt-get install -y \
    @(' \\\n    '.join(packages))@  \
    && rm -rf /var/lib/apt/lists/*

@[end if]@
@[end if]@
# setup keys
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 421C365BD9FF1F717815A3895523BAEEB01FA116

# setup sources.list
RUN echo "deb http://packages.ros.org/ros/ubuntu @os_code_name main" > /etc/apt/sources.list.d/ros-latest.list

# install bootstrap tools
RUN apt-get update && apt-get install --no-install-recommends -y \
    python-rosdep \
    python-rosinstall \
    python-vcstools \
    && rm -rf /var/lib/apt/lists/*

# setup environment
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8

# bootstrap rosdep
RUN rosdep init \
    && rosdep update

# install ros packages
ENV ROS_DISTRO @rosdistro_name
RUN apt-get update && apt-get install -y \
    @(' \\\n    '.join(ros_packages))@  \
    && rm -rf /var/lib/apt/lists/*

# setup entrypoint
COPY ./ros_entrypoint.sh /

@[if 'entrypoint_name' in locals()]@
@[if entrypoint_name]@
@{
entrypoint_file = entrypoint_name.split('/')[-1]
}@
ENTRYPOINT ["/@entrypoint_file"]
@[end if]@
@[end if]@
@{
cmds = [
'bash',
]
}@
CMD ["@(' && '.join(cmds))"]

@(TEMPLATE(
    'snippet/add_generated_comment.Dockerfile.em',
    user_name=user_name,
    tag_name=tag_name,
    source_template_name=template_name,
))@
@(TEMPLATE(
    'snippet/from_base_image.Dockerfile.em',
    template_packages=template_packages,
    os_name=os_name,
    os_code_name=os_code_name,
    arch=arch,
    base_image=base_image,
    maintainer_name=maintainer_name,
))@

@[if 'packages' in locals()]@
@[if packages]@

# install packages
RUN apt-get update && apt-get install -y \
    @(' \\\n    '.join(packages))@  \
    && rm -rf /var/lib/apt/lists/*

@[end if]@
@[end if]@
# setup keys
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 421C365BD9FF1F717815A3895523BAEEB01FA116

# setup sources.list
RUN echo "deb http://packages.ros.org/ros/@os_name @os_code_name main" > /etc/apt/sources.list.d/ros-latest.list

# install bootstrap tools
RUN apt-get update && apt-get install --no-install-recommends -y \
    python-rosdep \
    python-rosinstall \
    python-vcstools \
    && rm -rf /var/lib/apt/lists/*

# setup environment
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8

# bootstrap rosdep
RUN rosdep init \
    && rosdep update

# install ros packages
ENV ROS_DISTRO @rosdistro_name
RUN apt-get update && apt-get install -y \
    @(' \\\n    '.join(ros_packages))@  \
    && rm -rf /var/lib/apt/lists/*

# setup entrypoint
COPY ./ros_entrypoint.sh /

@[if 'entrypoint_name' in locals()]@
@[if entrypoint_name]@
@{
entrypoint_file = entrypoint_name.split('/')[-1]
}@
ENTRYPOINT ["/@entrypoint_file"]
@[end if]@
@[end if]@
@{
cmds = [
'bash',
]
}@
CMD ["@(' && '.join(cmds))"]


removed explicit returns

removed explicit returns

Herd.AssetContainerComponent = Ember.Component.extend
  asset: null
  t: null
  transform: null
  child: null
  bg: true

  +computed options
  optionsHash: ->
    return unless @t
    yaml = @t.split('|').join("\n")
    hash = jsyaml.load yaml
    sorted = {}
    for k in Object.keys(hash).sort()
      sorted[k] = hash[k]

    sorted

  +computed options
  sortedOptionsSegment: ->
    yaml = jsyaml.dump @optionsHash
    encodeURIComponent yaml.split("\n").join('|')

  +computed asset, transform, child.url
  assetUrl: ->

    if @child and @child.url
      return @child.url

    else if @asset and @t

      @child = @asset.t @t
      return @assetUrl if @child?.url

      if !@child?.url
        debugger if @transform
        @child = @asset.store.createRecord 'asset',
          parentAsset: @asset
          transform: @transform || @asset.store.createRecord 'transform',
            options: @t
            type: 'Herd::MiniMagick'

        @child.save()

      "https://d13yacurqjgara.cloudfront.net/users/82092/screenshots/1073359/spinner.gif"
    else if @asset
      @asset.url
    else
      "http://www.york.ac.uk/media/environment/images/staff/NoImageAvailableFemale.jpg"

  actions:
    metaUpdate: ->
      @asset.save()

Herd.AssetContainerComponent = Ember.Component.extend
  asset: null
  t: null
  transform: null
  child: null
  bg: true

  +computed options
  optionsHash: ->
    return unless @t
    yaml = @t.split('|').join("\n")
    hash = jsyaml.load yaml
    sorted = {}
    for k in Object.keys(hash).sort()
      sorted[k] = hash[k]

    sorted

  +computed options
  sortedOptionsSegment: ->
    yaml = jsyaml.dump @optionsHash
    encodeURIComponent yaml.split("\n").join('|')

  +computed asset, transform, child.url
  assetUrl: ->

    if @child and @child.url
      return @child.url

    else if @asset and @t

      @child = @asset.t @t
      return @assetUrl if @child?.url

      if !@child?.url
        debugger if @transform
        @child = @asset.store.createRecord 'asset',
          parentAsset: @asset
          transform: @transform || @asset.store.createRecord 'transform',
            options: @t
            type: 'Herd::MiniMagick'

        @child.save()
        return "https://d13yacurqjgara.cloudfront.net/users/82092/screenshots/1073359/spinner.gif"
    else if @asset
      return @asset.url
    else
      return "http://www.york.ac.uk/media/environment/images/staff/NoImageAvailableFemale.jpg"
  actions:
    metaUpdate: ->
      @asset.save()


make docker container names unique for status pages

Signed-off-by: Tully Foote <22715502305f5acc3bd5bf22a9c406e70a1e1348@osrfoundation.org>

<project>
  <actions/>
  <description>Generated at @ESCAPE(now_str) from template '@ESCAPE(template_name)'</description>
  <keepDependencies>false</keepDependencies>
  <properties>
@(SNIPPET(
    'property_log-rotator',
    days_to_keep=100,
    num_to_keep=100,
))@
@(SNIPPET(
    'property_job-priority',
    priority=20,
))@
@(SNIPPET(
    'property_requeue-job',
))@
  </properties>
@(SNIPPET(
    'scm_git',
    url=ros_buildfarm_repository.url,
    branch_name=ros_buildfarm_repository.version or 'master',
    relative_target_dir='ros_buildfarm',
    refspec=None,
))@
  <scmCheckoutRetryCount>2</scmCheckoutRetryCount>
  <assignedNode>agent_on_master||buildagent</assignedNode>
  <canRoam>false</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>
@(SNIPPET(
    'trigger_timer',
    spec='H/20 * * * *',
))@
  </triggers>
  <concurrentBuild>false</concurrentBuild>
  <builders>
@(SNIPPET(
    'builder_shell_docker-info',
))@
@(SNIPPET(
    'builder_shell_key-files',
    script_generating_key_files=script_generating_key_files,
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'rm -fr $WORKSPACE/docker_generate_status_page',
        'mkdir -p $WORKSPACE/docker_generate_status_page',
        '',
        '# monitor all subprocesses and enforce termination',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/subprocess_reaper.py $$ --cid-file $WORKSPACE/docker_generate_status_page/docker.cid > $WORKSPACE/docker_generate_status_page/subprocess_reaper.log 2>&1 &',
        '# sleep to give python time to startup',
        'sleep 1',
        '',
        '# generate Dockerfile, build and run it',
        '# generating the release status page',
        'echo "# BEGIN SECTION: Generate Dockerfile - status page"',
        'export TZ="%s"' % timezone,
        'export PYTHONPATH=$WORKSPACE/ros_buildfarm:$PYTHONPATH',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/status/run_release_status_page_job.py' +
        ' ' + config_url +
        ' ' + rosdistro_name +
        ' ' + release_build_name +
        ' ' + ' '.join(repository_args) +
        ' --dockerfile-dir $WORKSPACE/docker_generate_status_page',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Build Dockerfile - status page"',
        'cd $WORKSPACE/docker_generate_status_page',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/misc/docker_pull_baseimage.py',
        'docker build --force-rm -t status_page_generation_%s_%s .' % (rosdistro_name, release_build_name),
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Dockerfile - status page"',
        'rm -fr $WORKSPACE/package_repo_cache',
        'rm -fr $WORKSPACE/status_page',
        'mkdir -p $WORKSPACE/package_repo_cache',
        'mkdir -p $WORKSPACE/status_page',
        'docker run' +
        ' --rm ' +
        ' --cidfile=$WORKSPACE/docker_generate_status_page/docker.cid' +
        ' --net=host' +
        ' -v $WORKSPACE/ros_buildfarm:/tmp/ros_buildfarm:ro' +
        ' -v $WORKSPACE/package_repo_cache:/tmp/package_repo_cache' +
        ' -v $WORKSPACE/status_page:/tmp/status_page' +
        ' status_page_generation_%s_%s' % (rosdistro_name, release_build_name),
        'echo "# END SECTION"',
    ]),
))@
  </builders>
  <publishers>
@(SNIPPET(
    'publisher_publish-over-ssh',
    config_name='status_page',
    remote_directory='',
    source_files=['status_page/**'],
    remove_prefix='status_page',
))@
@(SNIPPET(
    'publisher_mailer',
    recipients=notification_emails,
    dynamic_recipients=[],
    send_to_individuals=False,
))@
  </publishers>
  <buildWrappers>
@(SNIPPET(
    'build-wrapper_timestamper',
))@
  </buildWrappers>
</project>

<project>
  <actions/>
  <description>Generated at @ESCAPE(now_str) from template '@ESCAPE(template_name)'</description>
  <keepDependencies>false</keepDependencies>
  <properties>
@(SNIPPET(
    'property_log-rotator',
    days_to_keep=100,
    num_to_keep=100,
))@
@(SNIPPET(
    'property_job-priority',
    priority=20,
))@
@(SNIPPET(
    'property_requeue-job',
))@
  </properties>
@(SNIPPET(
    'scm_git',
    url=ros_buildfarm_repository.url,
    branch_name=ros_buildfarm_repository.version or 'master',
    relative_target_dir='ros_buildfarm',
    refspec=None,
))@
  <scmCheckoutRetryCount>2</scmCheckoutRetryCount>
  <assignedNode>agent_on_master||buildagent</assignedNode>
  <canRoam>false</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>
@(SNIPPET(
    'trigger_timer',
    spec='H/20 * * * *',
))@
  </triggers>
  <concurrentBuild>false</concurrentBuild>
  <builders>
@(SNIPPET(
    'builder_shell_docker-info',
))@
@(SNIPPET(
    'builder_shell_key-files',
    script_generating_key_files=script_generating_key_files,
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'rm -fr $WORKSPACE/docker_generate_status_page',
        'mkdir -p $WORKSPACE/docker_generate_status_page',
        '',
        '# monitor all subprocesses and enforce termination',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/subprocess_reaper.py $$ --cid-file $WORKSPACE/docker_generate_status_page/docker.cid > $WORKSPACE/docker_generate_status_page/subprocess_reaper.log 2>&1 &',
        '# sleep to give python time to startup',
        'sleep 1',
        '',
        '# generate Dockerfile, build and run it',
        '# generating the release status page',
        'echo "# BEGIN SECTION: Generate Dockerfile - status page"',
        'export TZ="%s"' % timezone,
        'export PYTHONPATH=$WORKSPACE/ros_buildfarm:$PYTHONPATH',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/status/run_release_status_page_job.py' +
        ' ' + config_url +
        ' ' + rosdistro_name +
        ' ' + release_build_name +
        ' ' + ' '.join(repository_args) +
        ' --dockerfile-dir $WORKSPACE/docker_generate_status_page',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Build Dockerfile - status page"',
        'cd $WORKSPACE/docker_generate_status_page',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/misc/docker_pull_baseimage.py',
        'docker build --force-rm -t status_page_generation .',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Dockerfile - status page"',
        'rm -fr $WORKSPACE/package_repo_cache',
        'rm -fr $WORKSPACE/status_page',
        'mkdir -p $WORKSPACE/package_repo_cache',
        'mkdir -p $WORKSPACE/status_page',
        'docker run' +
        ' --rm ' +
        ' --cidfile=$WORKSPACE/docker_generate_status_page/docker.cid' +
        ' --net=host' +
        ' -v $WORKSPACE/ros_buildfarm:/tmp/ros_buildfarm:ro' +
        ' -v $WORKSPACE/package_repo_cache:/tmp/package_repo_cache' +
        ' -v $WORKSPACE/status_page:/tmp/status_page' +
        ' status_page_generation',
        'echo "# END SECTION"',
    ]),
))@
  </builders>
  <publishers>
@(SNIPPET(
    'publisher_publish-over-ssh',
    config_name='status_page',
    remote_directory='',
    source_files=['status_page/**'],
    remove_prefix='status_page',
))@
@(SNIPPET(
    'publisher_mailer',
    recipients=notification_emails,
    dynamic_recipients=[],
    send_to_individuals=False,
))@
  </publishers>
  <buildWrappers>
@(SNIPPET(
    'build-wrapper_timestamper',
))@
  </buildWrappers>
</project>


update images tempates to match dockerfile

Signed-off-by: Mikael Arguedas <a16f295d1139a1392bb19262902c32cf3e999ce4@gmail.com>

%YAML 1.1
# ROS2 Dockerfile database
---
images:
    devel:
        base_image: @(os_name):@(os_code_name)
        maintainer_name: @(maintainer_name)
        template_name: docker_images_ros2/devel/create_ros_image.Dockerfile.em
        entrypoint_name: docker_images_ros2/devel/ros_entrypoint.sh
        template_packages:
            - docker_templates
        upstream_packages:
            - bash-completion
        pip3_install:
            - argcomplete
            - flake8
            - flake8-blind-except
            - flake8-builtins
            - flake8-class-newline
            - flake8-comprehensions
            - flake8-deprecated
            - flake8-docstrings
            - flake8-import-order
            - flake8-quotes
            - pytest-repeat
            - pytest-rerunfailures
        ws: /opt/ros2_ws
    source:
        maintainer_name: @(maintainer_name)
        template_name: docker_images_ros2/source/create_ros_image.Dockerfile.em
        template_packages:
            - docker_templates
        upstream_packages:
            - libasio-dev
            - libtinyxml2-dev
        ros2_distro: eloquent
        ws: /opt/ros2_ws
        colcon_args:
            - build
            - --symlink-install
            - --mixin
                build-testing-on
                release
            - --cmake-args
                --no-warn-unused-cli
        rosdep:
            install:
                - --from-paths src
                - --ignore-src
                - --skip-keys "console_bridge fastcdr fastrtps libopensplice67 libopensplice69 rti-connext-dds-5.3.1 urdfdom_headers"
        vcs:
            imports:
                repos:

%YAML 1.1
# ROS2 Dockerfile database
---
images:
    devel:
        base_image: @(os_name):@(os_code_name)
        maintainer_name: @(maintainer_name)
        template_name: docker_images_ros2/devel/create_ros_image.Dockerfile.em
        entrypoint_name: docker_images_ros2/devel/ros_entrypoint.sh
        template_packages:
            - docker_templates
        upstream_packages:
            - bash-completion
        pip3_install:
            - argcomplete
            - flake8
            - flake8-blind-except
            - flake8-builtins
            - flake8-class-newline
            - flake8-comprehensions
            - flake8-deprecated
            - flake8-docstrings
            - flake8-import-order
            - flake8-quotes
            - pytest-repeat
            - pytest-rerunfailures
        ws: /opt/ros2_ws
    source:
        maintainer_name: @(maintainer_name)
        template_name: docker_images_ros2/source/create_ros_image.Dockerfile.em
        template_packages:
            - docker_templates
        upstream_packages:
            - libasio-dev
            - libtinyxml2-dev
        ros2_distro: eloquent
        ws: /opt/ros2_ws
        colcon_args:
            - build
            - --cmake-args
                -DSECURITY=ON --no-warn-unused-cli
            - --symlink-install
        rosdep:
            install:
                - --from-paths src
                - --ignore-src
                - --skip-keys "console_bridge fastcdr fastrtps libopensplice67 libopensplice69 rti-connext-dds-5.3.1 urdfdom_headers"
        vcs:
            imports:
                repos:


add magic docker fix env var

add magic docker fix env var

# generated from @template_name

@(TEMPLATE(
    'snippet/from_base_image.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
    arch=arch,
))@

VOLUME ["/var/cache/apt/archives"]

ENV DEBIAN_FRONTEND noninteractive

@(TEMPLATE(
    'snippet/setup_locale.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
    timezone=timezone,
))@

RUN useradd -u @uid -m buildfarm

@(TEMPLATE(
    'snippet/old_release_set.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
))@

@(TEMPLATE(
    'snippet/add_distribution_repositories.Dockerfile.em',
    distribution_repository_keys=distribution_repository_keys,
    distribution_repository_urls=distribution_repository_urls,
    os_name=os_name,
    os_code_name=os_code_name,
    add_source=False,
))@

@(TEMPLATE(
    'snippet/add_additional_repositories.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
    arch=arch,
))@

@(TEMPLATE(
    'snippet/add_wrapper_scripts.Dockerfile.em',
    wrapper_scripts=wrapper_scripts,
))@

# automatic invalidation once every day
RUN echo "@today_str"

@(TEMPLATE(
    'snippet/install_python3.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
))@

@(TEMPLATE(
    'snippet/install_ccache.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
))@

# magic https://github.com/docker/docker/issues/14203
ENV DOCKER_FIX ' '

@(TEMPLATE(
    'snippet/install_dependencies.Dockerfile.em',
    dependencies=dependencies,
    dependency_versions=dependency_versions,
))@

USER buildfarm
ENTRYPOINT ["sh", "-c"]
@{
cmd = \
    'PYTHONPATH=/tmp/ros_buildfarm:$PYTHONPATH' + \
    ' PATH=/usr/lib/ccache:$PATH' + \
    ' python3 -u' + \
    ' /tmp/ros_buildfarm/scripts/release/build_binarydeb.py' + \
    ' ' + rosdistro_name + \
    ' ' + package_name + \
    ' --sourcedeb-dir ' + binarydeb_dir
}@
CMD ["@cmd"]

# generated from @template_name

@(TEMPLATE(
    'snippet/from_base_image.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
    arch=arch,
))@

VOLUME ["/var/cache/apt/archives"]

ENV DEBIAN_FRONTEND noninteractive

@(TEMPLATE(
    'snippet/setup_locale.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
    timezone=timezone,
))@

RUN useradd -u @uid -m buildfarm

@(TEMPLATE(
    'snippet/old_release_set.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
))@

@(TEMPLATE(
    'snippet/add_distribution_repositories.Dockerfile.em',
    distribution_repository_keys=distribution_repository_keys,
    distribution_repository_urls=distribution_repository_urls,
    os_name=os_name,
    os_code_name=os_code_name,
    add_source=False,
))@

@(TEMPLATE(
    'snippet/add_additional_repositories.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
    arch=arch,
))@

@(TEMPLATE(
    'snippet/add_wrapper_scripts.Dockerfile.em',
    wrapper_scripts=wrapper_scripts,
))@

# automatic invalidation once every day
RUN echo "@today_str"

@(TEMPLATE(
    'snippet/install_python3.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
))@

@(TEMPLATE(
    'snippet/install_ccache.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
))@

@(TEMPLATE(
    'snippet/install_dependencies.Dockerfile.em',
    dependencies=dependencies,
    dependency_versions=dependency_versions,
))@

USER buildfarm
ENTRYPOINT ["sh", "-c"]
@{
cmd = \
    'PYTHONPATH=/tmp/ros_buildfarm:$PYTHONPATH' + \
    ' PATH=/usr/lib/ccache:$PATH' + \
    ' python3 -u' + \
    ' /tmp/ros_buildfarm/scripts/release/build_binarydeb.py' + \
    ' ' + rosdistro_name + \
    ' ' + package_name + \
    ' --sourcedeb-dir ' + binarydeb_dir
}@
CMD ["@cmd"]