From 50164e996870166aafd7e23e960196cf417fe739 Mon Sep 17 00:00:00 2001
From: jean-pierre charras <jp.charras@wanadoo.fr>
Date: Sat, 19 Aug 2017 18:28:11 +0200
Subject: [PATCH] Add Gerber job file writer in Pcbnew, and a basic reader in
 Gerbview. Currently disabled Fix also very minor issues in Gerbview

---
 bitmaps_png/CMakeLists.txt                 |   1 +
 bitmaps_png/cpp_26/gerber_job_file.cpp     | 146 ++++
 bitmaps_png/sources/gerber_job_file.svg    | 818 +++++++++++++++++++++
 common/gbr_metadata.cpp                    |  35 +
 common/pcb_plot_params.keywords            |   1 +
 common/wildcards_and_files_ext.cpp         |   3 +-
 gerbview/CMakeLists.txt                    |   2 +-
 gerbview/events_called_functions.cpp       |   4 +
 gerbview/files.cpp                         |  18 +
 gerbview/gerbview_config.cpp               |   4 -
 gerbview/gerbview_frame.cpp                |  17 +-
 gerbview/gerbview_frame.h                  |  20 +
 gerbview/gerbview_id.h                     |  15 +-
 gerbview/job_file_reader.cpp               | 245 ++++++
 gerbview/menubar.cpp                       |  81 +-
 gerbview/readgerb.cpp                      |  10 +-
 include/bitmaps.h                          |   1 +
 include/plot_auxiliary_data.h              |   9 +
 include/wildcards_and_files_ext.h          |   1 +
 kicad/tree_project_frame.cpp               |  12 +-
 pcbnew/CMakeLists.txt                      |   1 +
 pcbnew/dialogs/dialog_plot.cpp             |  37 +-
 pcbnew/dialogs/dialog_plot_base.cpp        |   7 +-
 pcbnew/dialogs/dialog_plot_base.fbp        |  88 +++
 pcbnew/dialogs/dialog_plot_base.h          |   3 +-
 pcbnew/exporters/gerber_jobfile_writer.cpp | 388 ++++++++++
 pcbnew/exporters/gerber_jobfile_writer.h   | 125 ++++
 pcbnew/pcb_plot_params.cpp                 |  18 +-
 pcbnew/pcb_plot_params.h                   |   6 +
 pcbnew/pcbplot.cpp                         |  96 +++
 30 files changed, 2134 insertions(+), 78 deletions(-)
 create mode 100644 bitmaps_png/cpp_26/gerber_job_file.cpp
 create mode 100644 bitmaps_png/sources/gerber_job_file.svg
 create mode 100644 gerbview/job_file_reader.cpp
 create mode 100644 pcbnew/exporters/gerber_jobfile_writer.cpp
 create mode 100644 pcbnew/exporters/gerber_jobfile_writer.h

diff --git a/bitmaps_png/CMakeLists.txt b/bitmaps_png/CMakeLists.txt
index 40003dcccc..a646f19eee 100644
--- a/bitmaps_png/CMakeLists.txt
+++ b/bitmaps_png/CMakeLists.txt
@@ -238,6 +238,7 @@ set( BMAPS_MID
     gbr_select_mode1
     gbr_select_mode2
     gerber_file
+    gerber_job_file
     gerbview_show_negative_objects
     gerbview_drill_file
     gerbview_clear_layers
diff --git a/bitmaps_png/cpp_26/gerber_job_file.cpp b/bitmaps_png/cpp_26/gerber_job_file.cpp
new file mode 100644
index 0000000000..c63a07c7eb
--- /dev/null
+++ b/bitmaps_png/cpp_26/gerber_job_file.cpp
@@ -0,0 +1,146 @@
+
+/* Do not modify this file, it was automatically generated by the
+ * PNG2cpp CMake script, using a *.png file as input.
+ */
+
+#include <bitmaps.h>
+
+static const unsigned char png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
+ 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c,
+ 0xce, 0x00, 0x00, 0x08, 0x14, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xad, 0x56, 0x69, 0x6c, 0x53,
+ 0xe9, 0x15, 0x35, 0x23, 0xa6, 0xaa, 0xda, 0x8a, 0xf9, 0x53, 0xca, 0x08, 0x5a, 0x44, 0x01, 0x01,
+ 0x1a, 0x60, 0x40, 0x45, 0x2c, 0x65, 0xdf, 0x09, 0x61, 0x11, 0xbb, 0x10, 0xc3, 0xbe, 0xa9, 0x02,
+ 0x04, 0xc3, 0x0f, 0x98, 0x16, 0x04, 0x65, 0x08, 0x59, 0x86, 0x84, 0x6c, 0x10, 0xb2, 0x2f, 0x64,
+ 0x71, 0x20, 0x21, 0x8b, 0x1d, 0x12, 0x48, 0x1c, 0x27, 0x71, 0x56, 0xc7, 0xf6, 0xb3, 0x1d, 0xe3,
+ 0x2d, 0x89, 0x63, 0x27, 0x4e, 0xf2, 0xfc, 0xbc, 0xc7, 0x8e, 0xf7, 0xed, 0xf6, 0x1a, 0x01, 0x22,
+ 0x4c, 0xa7, 0x6a, 0xa5, 0x3e, 0xe9, 0xca, 0x7e, 0xcf, 0xcf, 0xf7, 0x7c, 0xf7, 0xdc, 0xf3, 0x9d,
+ 0xfb, 0xd1, 0x68, 0x9f, 0x5d, 0xa7, 0x4f, 0x9f, 0x3e, 0x7c, 0xee, 0xdc, 0xb9, 0x98, 0x43, 0x87,
+ 0x0e, 0xed, 0xde, 0xb3, 0x67, 0xcf, 0xef, 0xc3, 0xcf, 0x2e, 0x5e, 0xbc, 0xf8, 0xe5, 0xb1, 0x63,
+ 0xc7, 0xfe, 0x79, 0xf8, 0xf0, 0xe1, 0x5d, 0x78, 0x3b, 0x89, 0xf6, 0xff, 0xb8, 0xb2, 0xb3, 0xb3,
+ 0xe9, 0x81, 0x40, 0xe0, 0xe5, 0xd0, 0xd0, 0x10, 0x83, 0xcd, 0x66, 0x33, 0x93, 0x92, 0x92, 0xe8,
+ 0x17, 0x2e, 0x5c, 0x28, 0x2b, 0x2d, 0x2d, 0x65, 0x0b, 0x44, 0xe2, 0xa6, 0x2a, 0x76, 0x87, 0x92,
+ 0x23, 0xe9, 0x1f, 0xe0, 0xf6, 0x0e, 0xa9, 0xdb, 0xa4, 0x1a, 0x2e, 0x5b, 0xa4, 0xbe, 0xdd, 0xd3,
+ 0xd3, 0xf3, 0xdb, 0xff, 0x09, 0x64, 0xdb, 0xb6, 0x6d, 0xd3, 0x3b, 0x3b, 0x3b, 0xab, 0x83, 0xc1,
+ 0x60, 0xf4, 0xa9, 0x53, 0xa7, 0xca, 0x32, 0x32, 0x32, 0xf2, 0x48, 0x92, 0xcc, 0x31, 0x1a, 0x8d,
+ 0x5c, 0xa2, 0x4f, 0x63, 0x6d, 0x93, 0x0f, 0x07, 0x98, 0x6f, 0x8d, 0xde, 0x8c, 0x36, 0xd2, 0xf9,
+ 0x53, 0x9d, 0xca, 0x92, 0xd6, 0xae, 0xeb, 0xaf, 0x14, 0x92, 0x64, 0x13, 0xa1, 0xb4, 0xd6, 0x75,
+ 0x29, 0xa2, 0xff, 0x6b, 0xa0, 0x03, 0x07, 0x0e, 0xec, 0x1d, 0x1e, 0x1e, 0xae, 0x1c, 0x1b, 0x1b,
+ 0x8b, 0xb9, 0x73, 0xe7, 0xce, 0xb3, 0xb8, 0xb8, 0xb8, 0xbc, 0xe3, 0xc7, 0x8f, 0xb3, 0x1b, 0xba,
+ 0x04, 0xae, 0x57, 0x52, 0x8b, 0xb7, 0x90, 0xb0, 0x8e, 0xd1, 0x25, 0xe3, 0x26, 0x46, 0x9f, 0xcf,
+ 0x58, 0xdb, 0xe7, 0x35, 0x57, 0x4a, 0xac, 0xa6, 0xd4, 0x86, 0xbe, 0xd1, 0x18, 0xc6, 0x5b, 0x75,
+ 0x45, 0xbb, 0x72, 0xbc, 0xec, 0x4d, 0x47, 0xdb, 0x2f, 0x52, 0x8b, 0x2b, 0xdf, 0x8e, 0x91, 0x18,
+ 0x8e, 0x13, 0x27, 0x4e, 0xbc, 0x8e, 0x8d, 0x8d, 0x6d, 0xbd, 0x7c, 0xf9, 0x72, 0xd3, 0xc6, 0x8d,
+ 0x1b, 0x85, 0x5b, 0xb7, 0x6e, 0x25, 0x52, 0xb2, 0x0a, 0x8c, 0x15, 0xbc, 0x41, 0x7f, 0x42, 0x5d,
+ 0xaf, 0x35, 0xea, 0x25, 0xdf, 0x9a, 0x58, 0x27, 0x37, 0xff, 0x54, 0xc9, 0x33, 0x3d, 0xae, 0x93,
+ 0x18, 0x32, 0x58, 0x32, 0x7d, 0x26, 0x4b, 0x66, 0xcc, 0x6e, 0x56, 0x19, 0xca, 0xc5, 0x66, 0xaa,
+ 0xba, 0x43, 0xea, 0x2d, 0x78, 0x51, 0x23, 0x39, 0x72, 0xe4, 0xc8, 0x8e, 0x9f, 0x01, 0x61, 0xe2,
+ 0x4c, 0x00, 0x60, 0x62, 0x54, 0xda, 0x6c, 0xb6, 0x2e, 0xfc, 0xec, 0xd4, 0xe9, 0x74, 0x3c, 0xb9,
+ 0x5c, 0x2e, 0x92, 0xc9, 0x64, 0xe2, 0x66, 0x81, 0xd4, 0x5f, 0x22, 0xf7, 0xdb, 0x6a, 0x94, 0x4e,
+ 0xf3, 0x2b, 0xac, 0xe2, 0x75, 0xaf, 0xd3, 0xd0, 0xa2, 0xf1, 0xe8, 0x39, 0x6a, 0x97, 0xbe, 0x93,
+ 0x0c, 0x91, 0xdd, 0x64, 0x80, 0x2a, 0x69, 0x55, 0x91, 0xcd, 0x1a, 0x2f, 0xc9, 0x90, 0x98, 0xf5,
+ 0x95, 0xac, 0x0e, 0x1f, 0xb2, 0x70, 0xeb, 0x67, 0x40, 0x8f, 0x1e, 0x3d, 0xca, 0xc2, 0xe4, 0x65,
+ 0x7c, 0x3e, 0xbf, 0xbe, 0xb2, 0xb2, 0x92, 0xa8, 0xa9, 0xa9, 0xe1, 0x15, 0x15, 0x15, 0x09, 0xbb,
+ 0xbb, 0xbb, 0x45, 0x95, 0xd5, 0x0c, 0x55, 0x0d, 0x5f, 0xe5, 0xa7, 0xf7, 0xd8, 0xcd, 0xa5, 0x7c,
+ 0xca, 0xdc, 0xa8, 0x72, 0x53, 0x6f, 0x14, 0x76, 0xea, 0xf5, 0x5b, 0xa3, 0xbe, 0x51, 0x6e, 0xa6,
+ 0x08, 0x0a, 0x46, 0xba, 0x87, 0xdd, 0xba, 0xf2, 0x2e, 0xd5, 0x28, 0xbb, 0x6f, 0x4c, 0xc5, 0xd5,
+ 0x81, 0xb6, 0x8a, 0x23, 0xf1, 0xfe, 0x18, 0x9b, 0x28, 0xde, 0xbb, 0x77, 0xef, 0xa6, 0x7f, 0x0b,
+ 0xd4, 0xda, 0xda, 0xda, 0x5c, 0x5c, 0x5c, 0x4c, 0x60, 0x08, 0x58, 0x2c, 0x16, 0x91, 0x9f, 0x9f,
+ 0x2f, 0x62, 0xd6, 0xb1, 0x46, 0x2a, 0xb8, 0x6a, 0x1f, 0x5d, 0x64, 0x35, 0x96, 0xf0, 0x74, 0x06,
+ 0xa6, 0x58, 0xa7, 0x67, 0xf7, 0xda, 0x75, 0x0c, 0x62, 0x84, 0xac, 0x97, 0x19, 0x48, 0x99, 0x09,
+ 0x74, 0xfc, 0x21, 0x87, 0xae, 0x49, 0x4a, 0x92, 0xcd, 0x32, 0x72, 0x58, 0x6e, 0x01, 0x75, 0x6d,
+ 0x97, 0xd2, 0x51, 0xf5, 0x8a, 0x33, 0x24, 0x91, 0x48, 0x18, 0x97, 0x2e, 0x5d, 0xca, 0xda, 0xbe,
+ 0x7d, 0xfb, 0x82, 0x09, 0x40, 0x74, 0x3a, 0xbd, 0xfb, 0xc1, 0x83, 0x07, 0xa2, 0x70, 0x24, 0x24,
+ 0x24, 0x88, 0x1a, 0x1a, 0x1a, 0x44, 0x79, 0x05, 0x25, 0x5a, 0x46, 0xb7, 0xca, 0x97, 0xcd, 0x19,
+ 0x34, 0xbe, 0xe9, 0x75, 0xea, 0x0b, 0x5b, 0x94, 0x64, 0xe7, 0xa0, 0x83, 0x6a, 0x94, 0x51, 0xba,
+ 0x6e, 0xb5, 0xd5, 0xa0, 0xb2, 0x81, 0x4e, 0x42, 0x3a, 0x0c, 0xbc, 0x7e, 0xca, 0xc0, 0x57, 0xe9,
+ 0x75, 0xda, 0x71, 0x18, 0xae, 0xe7, 0xca, 0xc6, 0x53, 0x33, 0x8a, 0x75, 0x98, 0x33, 0xce, 0xeb,
+ 0xf5, 0xd2, 0x1b, 0x1b, 0x1b, 0xab, 0x4e, 0x9e, 0x3c, 0x79, 0xe5, 0x53, 0x20, 0xfe, 0x07, 0xa0,
+ 0x70, 0x20, 0x8d, 0xa2, 0xec, 0xec, 0x5c, 0x45, 0x75, 0x13, 0xdf, 0x97, 0xdf, 0xa1, 0x35, 0xd7,
+ 0xf7, 0xda, 0xf5, 0xc5, 0x2d, 0x0a, 0xb2, 0xb5, 0xcf, 0x4a, 0xb2, 0x24, 0x5a, 0xaa, 0x67, 0xc4,
+ 0xae, 0x1f, 0x1a, 0x0b, 0x18, 0x35, 0x66, 0xb7, 0x49, 0xaa, 0x35, 0x99, 0xe5, 0xc3, 0x46, 0xa3,
+ 0xc1, 0x05, 0xd4, 0xab, 0x66, 0x9e, 0x3b, 0x25, 0xed, 0x99, 0x02, 0x73, 0x46, 0x85, 0x03, 0xf7,
+ 0x24, 0xfd, 0xea, 0xd5, 0xab, 0xc9, 0x1f, 0x81, 0x9e, 0x3f, 0x7f, 0x4e, 0x7c, 0x0e, 0x54, 0x52,
+ 0x52, 0xd2, 0x53, 0x5a, 0xd1, 0xe0, 0x2e, 0xe7, 0x0e, 0x39, 0x9b, 0x07, 0xdc, 0x86, 0x12, 0x8e,
+ 0x9c, 0xec, 0xa1, 0x3c, 0x54, 0xbb, 0x7c, 0xc4, 0x20, 0x1f, 0xb5, 0x99, 0x06, 0x4d, 0x4e, 0xcb,
+ 0x88, 0xd5, 0x65, 0xd5, 0xe8, 0xad, 0x63, 0xa4, 0xcd, 0x65, 0x32, 0x3a, 0xfd, 0x96, 0x82, 0x12,
+ 0x86, 0x5f, 0x22, 0x51, 0x64, 0xbd, 0x07, 0x8a, 0xc3, 0x5e, 0x57, 0xef, 0xda, 0xb5, 0x6b, 0x19,
+ 0x2d, 0x3e, 0x3e, 0x3e, 0x0b, 0x4b, 0xac, 0x2a, 0x2b, 0x2b, 0x9b, 0x00, 0x84, 0x96, 0x43, 0xae,
+ 0x58, 0xb1, 0xc2, 0xbb, 0x62, 0xc5, 0x4a, 0x77, 0xe1, 0xcb, 0x06, 0x5f, 0x39, 0x31, 0x6c, 0x29,
+ 0x66, 0xf7, 0x50, 0xe8, 0x04, 0x86, 0x16, 0x91, 0xca, 0x24, 0xd7, 0x9a, 0x2c, 0xc3, 0x16, 0xa7,
+ 0x8d, 0xb2, 0x7b, 0xc6, 0x47, 0x4c, 0x63, 0x0e, 0x9b, 0x2f, 0x64, 0x15, 0x2a, 0x06, 0x3c, 0x09,
+ 0x49, 0xd9, 0xf6, 0x4f, 0xaa, 0x29, 0xba, 0x76, 0xed, 0xda, 0xd3, 0x77, 0x3d, 0x0a, 0x03, 0x8d,
+ 0x8f, 0x8f, 0xbf, 0x89, 0x89, 0x89, 0x21, 0x66, 0xce, 0x9c, 0xa9, 0x99, 0x3a, 0x75, 0xaa, 0x68,
+ 0xfa, 0xf4, 0xe9, 0xa2, 0xc5, 0x8b, 0x17, 0xdb, 0x9b, 0x9a, 0x9a, 0x60, 0xf7, 0xee, 0xdd, 0xde,
+ 0xb8, 0xf8, 0x64, 0xb2, 0x94, 0xc9, 0xf1, 0xde, 0x4f, 0xcd, 0x77, 0x70, 0x7a, 0x06, 0xcc, 0xdd,
+ 0x0a, 0xad, 0x59, 0x3e, 0xa8, 0x1f, 0x1b, 0x35, 0xdb, 0xc7, 0xcd, 0x2e, 0xaf, 0x53, 0x6f, 0x73,
+ 0xb8, 0x65, 0xaa, 0x41, 0x5f, 0x52, 0x72, 0x6e, 0x40, 0x2e, 0x55, 0x3c, 0xf9, 0x50, 0x0d, 0x97,
+ 0xcb, 0xad, 0xde, 0xb1, 0x63, 0xc7, 0x5f, 0x3e, 0x02, 0xa1, 0xaf, 0xb1, 0x30, 0xb1, 0x75, 0xe7,
+ 0xce, 0x9d, 0xa1, 0x69, 0xd3, 0xa6, 0x39, 0x10, 0xcc, 0xba, 0x7a, 0xf5, 0x6a, 0xbf, 0x42, 0xa1,
+ 0x80, 0x1b, 0x37, 0x6e, 0x04, 0x67, 0xcd, 0x9a, 0xe5, 0x8a, 0x88, 0x88, 0x74, 0x1d, 0x3f, 0x7e,
+ 0x22, 0xb4, 0x71, 0xd3, 0xe6, 0x50, 0x15, 0xab, 0xdd, 0xd5, 0x37, 0xa2, 0xc7, 0x4a, 0x6c, 0xce,
+ 0x1e, 0xa5, 0xda, 0xf7, 0xa2, 0xe2, 0x75, 0x30, 0x39, 0x29, 0x27, 0xf0, 0x30, 0x3e, 0xd5, 0xfa,
+ 0x69, 0x35, 0x57, 0xae, 0x5c, 0x49, 0xfb, 0x28, 0xef, 0x30, 0xd0, 0xe8, 0xe8, 0x28, 0x67, 0xc1,
+ 0x82, 0x05, 0x4e, 0x14, 0x04, 0xe4, 0xe5, 0xe5, 0x41, 0x6e, 0x6e, 0x2e, 0xf4, 0xf7, 0xf7, 0x83,
+ 0xd9, 0x6c, 0x06, 0xac, 0x16, 0x04, 0x02, 0x01, 0x20, 0xb5, 0xa0, 0x56, 0xab, 0x61, 0xeb, 0xd6,
+ 0x6d, 0x81, 0x9b, 0x3f, 0x44, 0xd9, 0x1f, 0x26, 0x64, 0xb9, 0x1f, 0x25, 0xe6, 0xba, 0xd3, 0x9e,
+ 0x3e, 0x73, 0x77, 0xf0, 0x44, 0xa1, 0x86, 0xa6, 0x8e, 0xe0, 0xcd, 0xbf, 0xff, 0x68, 0x44, 0x9f,
+ 0xfc, 0xb4, 0x9a, 0x25, 0x1f, 0x81, 0xd0, 0xcf, 0x72, 0x4c, 0x26, 0x53, 0xe7, 0xe6, 0xcd, 0x9b,
+ 0x25, 0x68, 0x3b, 0x01, 0x8d, 0x46, 0x03, 0x14, 0x45, 0x01, 0x1a, 0x29, 0x84, 0x2b, 0x0a, 0x7f,
+ 0x47, 0xef, 0x03, 0x7c, 0x07, 0xf0, 0x5d, 0x38, 0x7a, 0xf4, 0x28, 0x85, 0x8e, 0x21, 0x40, 0xaa,
+ 0x45, 0xa9, 0xa9, 0xa9, 0x04, 0x93, 0x59, 0xab, 0x2c, 0x2a, 0x29, 0x1f, 0x7b, 0xdb, 0xd7, 0x0f,
+ 0x8f, 0xd3, 0x0a, 0xfc, 0xaf, 0xd3, 0x4e, 0x6a, 0x2c, 0xfc, 0x64, 0xce, 0x84, 0x6a, 0xc2, 0x57,
+ 0x54, 0x54, 0xd4, 0x73, 0xa7, 0xd3, 0xd9, 0xb5, 0x72, 0xe5, 0xca, 0x91, 0x87, 0x0f, 0x1f, 0x86,
+ 0xc2, 0x00, 0x62, 0xb1, 0x18, 0xd6, 0xac, 0x59, 0xe3, 0x5b, 0xb6, 0x6c, 0xd9, 0xf8, 0xaa, 0x55,
+ 0xab, 0x3c, 0x4f, 0x9f, 0x3e, 0x0d, 0xa2, 0x2d, 0x41, 0x73, 0x73, 0x33, 0xe0, 0xbd, 0xf3, 0xc9,
+ 0x93, 0x27, 0x02, 0x9c, 0x59, 0x42, 0x1c, 0x21, 0x04, 0x2e, 0xa4, 0xbb, 0xae, 0xae, 0x8e, 0x68,
+ 0x62, 0xa4, 0x85, 0x94, 0xa5, 0x11, 0x60, 0xab, 0x58, 0x0c, 0xaa, 0xb8, 0x5f, 0x05, 0xff, 0x76,
+ 0x60, 0xe9, 0x9a, 0x09, 0x40, 0xfb, 0xf6, 0xed, 0x93, 0x61, 0x35, 0x2e, 0x4c, 0xec, 0x57, 0x2a,
+ 0x95, 0xe0, 0x72, 0xb9, 0x00, 0x4d, 0xd1, 0x3f, 0x7f, 0xfe, 0x7c, 0xf9, 0xd2, 0xa5, 0x4b, 0x85,
+ 0x6d, 0x6d, 0x6d, 0xc4, 0xdc, 0xb9, 0x73, 0xdd, 0x58, 0x05, 0xa0, 0xff, 0xc1, 0xf5, 0xeb, 0xd7,
+ 0x43, 0xcb, 0x97, 0x2f, 0xf7, 0xcd, 0x9e, 0x3d, 0xdb, 0x81, 0x8b, 0x14, 0x22, 0xbd, 0xbc, 0x97,
+ 0x39, 0x51, 0x7d, 0x03, 0xa5, 0xab, 0x01, 0x82, 0x1e, 0x00, 0xe9, 0x35, 0xb0, 0xe7, 0xff, 0x11,
+ 0xa4, 0xb1, 0xb4, 0xec, 0x09, 0x40, 0x6b, 0xd7, 0xae, 0xa5, 0x6a, 0x6b, 0x6b, 0x01, 0xfb, 0x04,
+ 0x1e, 0x8f, 0x07, 0x1c, 0x0e, 0x07, 0x60, 0x75, 0x5e, 0x4c, 0x26, 0x8c, 0x88, 0x88, 0x20, 0xec,
+ 0x76, 0x7b, 0x07, 0x82, 0x5a, 0x98, 0x4c, 0xe6, 0xbb, 0x5e, 0x85, 0xdf, 0xcd, 0xca, 0xca, 0x82,
+ 0x6f, 0xbe, 0xf9, 0xc6, 0x8b, 0xcf, 0x78, 0xb8, 0x10, 0x11, 0x83, 0xc1, 0x10, 0x97, 0xdd, 0xfa,
+ 0xf3, 0xb8, 0x47, 0x5d, 0x04, 0x60, 0xe6, 0x40, 0x80, 0xb3, 0x0d, 0xb4, 0xb1, 0x5f, 0x84, 0x88,
+ 0x68, 0xda, 0xb7, 0x1f, 0x81, 0x70, 0xbf, 0xb0, 0xb6, 0x6c, 0xd9, 0x62, 0x42, 0x9a, 0x7c, 0x2a,
+ 0x95, 0x0a, 0xac, 0x56, 0x2b, 0xe0, 0x38, 0x0f, 0xe0, 0x6c, 0xea, 0xc7, 0x7d, 0x24, 0x44, 0xfb,
+ 0x10, 0x63, 0x52, 0x0f, 0x87, 0xc3, 0x81, 0x96, 0x96, 0x16, 0xd8, 0xb0, 0x61, 0x83, 0x7f, 0xde,
+ 0xbc, 0x79, 0x36, 0x64, 0x60, 0xf4, 0xe0, 0xc1, 0x83, 0xc2, 0xfa, 0xfa, 0x7a, 0x02, 0xed, 0x4a,
+ 0x78, 0xff, 0xf6, 0xf7, 0x75, 0x8a, 0xdc, 0x45, 0x81, 0xa0, 0x9b, 0x04, 0x50, 0xc5, 0x83, 0xbb,
+ 0x7c, 0x21, 0x48, 0xee, 0xd1, 0xe4, 0x00, 0xef, 0xe7, 0x13, 0x36, 0x38, 0xbc, 0x8b, 0x33, 0xce,
+ 0x9c, 0x39, 0xd3, 0x9a, 0x98, 0x98, 0x18, 0xd4, 0xeb, 0xf5, 0x20, 0x95, 0x4a, 0x01, 0xa5, 0xee,
+ 0xc3, 0x7e, 0x38, 0xc2, 0xbd, 0x4a, 0x49, 0x49, 0x81, 0xf0, 0x9e, 0x42, 0xa3, 0x85, 0x25, 0x4b,
+ 0x96, 0x38, 0xb0, 0x02, 0x1e, 0x3a, 0x07, 0x0f, 0x9d, 0x83, 0x87, 0x63, 0x9c, 0x8f, 0x3d, 0x12,
+ 0xa2, 0x29, 0xa7, 0x97, 0x3e, 0x88, 0xec, 0xb3, 0x70, 0x6f, 0x02, 0x38, 0x07, 0x00, 0x04, 0x87,
+ 0xc0, 0x90, 0x32, 0x05, 0xba, 0xee, 0xd0, 0x4e, 0x4f, 0x00, 0xc2, 0x86, 0x17, 0x44, 0x46, 0x46,
+ 0x7a, 0x70, 0x4f, 0xbd, 0x93, 0x71, 0xb8, 0x27, 0x38, 0xd6, 0xa1, 0xbd, 0xbd, 0x1d, 0xd0, 0xcd,
+ 0x21, 0x4c, 0x1d, 0xbe, 0x03, 0x48, 0xa9, 0x13, 0xcf, 0x15, 0x44, 0x41, 0x41, 0x01, 0x51, 0x58,
+ 0x58, 0x48, 0x68, 0xb5, 0x5a, 0x1e, 0xfe, 0x46, 0xa0, 0x88, 0xe8, 0xdf, 0x7d, 0x77, 0x2c, 0xbf,
+ 0xe5, 0xfe, 0x57, 0x5a, 0xbf, 0xb1, 0x13, 0x60, 0x94, 0x0e, 0xbe, 0xba, 0x55, 0xf0, 0xf6, 0xee,
+ 0x24, 0x27, 0xeb, 0x07, 0xda, 0x57, 0x34, 0xb4, 0x9b, 0x4c, 0xbf, 0xdf, 0x5f, 0x8e, 0x94, 0x58,
+ 0x90, 0x82, 0x77, 0xc9, 0xd2, 0xd3, 0xd3, 0xdf, 0xd1, 0x14, 0xa6, 0x0b, 0x57, 0x0b, 0x99, 0x99,
+ 0x99, 0x80, 0x54, 0x06, 0xd2, 0xd2, 0xd2, 0xe0, 0xec, 0xd9, 0xb3, 0xc1, 0xe8, 0xe8, 0xe8, 0x21,
+ 0xac, 0x9c, 0x8b, 0x63, 0x9f, 0x87, 0xbd, 0x25, 0x5e, 0xbc, 0x78, 0x21, 0x08, 0x1f, 0x64, 0xd6,
+ 0xad, 0x5b, 0xf7, 0xed, 0x95, 0xcd, 0xb4, 0xc3, 0x83, 0xd5, 0x91, 0x21, 0x08, 0x7a, 0x51, 0x18,
+ 0xdf, 0x03, 0x95, 0xfe, 0x35, 0xd4, 0xdc, 0x9c, 0xf2, 0x88, 0x86, 0x0a, 0xdb, 0x87, 0x52, 0x4d,
+ 0x43, 0x85, 0xa9, 0x71, 0x74, 0x7b, 0x17, 0x2e, 0x5c, 0x38, 0xb8, 0x68, 0xd1, 0x22, 0x35, 0x86,
+ 0x2b, 0x27, 0x27, 0x07, 0xce, 0x9f, 0x3f, 0x1f, 0x98, 0x33, 0x67, 0x8e, 0x09, 0x05, 0xc2, 0x42,
+ 0xf5, 0x99, 0x71, 0x63, 0xdb, 0xf7, 0xef, 0xdf, 0xcf, 0x46, 0x47, 0xee, 0x42, 0xd5, 0xb5, 0xdf,
+ 0xbd, 0x7b, 0xb7, 0x11, 0x29, 0x6f, 0xc4, 0x93, 0xd2, 0x87, 0x7d, 0xf3, 0x1b, 0xfa, 0xa5, 0x49,
+ 0x0d, 0x63, 0x92, 0xc7, 0x20, 0x29, 0x3f, 0x0f, 0x65, 0x09, 0x27, 0xe1, 0xf6, 0x3f, 0x6e, 0x5e,
+ 0xfd, 0x54, 0x80, 0x93, 0x26, 0x4f, 0x9e, 0xfc, 0xd7, 0x0f, 0x37, 0x33, 0x66, 0xcc, 0xb8, 0x8f,
+ 0x49, 0x00, 0x55, 0xa9, 0xc3, 0xdb, 0xdf, 0xbd, 0x7f, 0xfc, 0x25, 0xc6, 0xb4, 0xf0, 0x17, 0xa4,
+ 0xf0, 0x4f, 0x28, 0xa4, 0x64, 0xec, 0x4d, 0x35, 0x0a, 0xa2, 0x6a, 0xfd, 0xfa, 0xf5, 0x8b, 0x3f,
+ 0xfc, 0x37, 0x72, 0x21, 0x6d, 0x69, 0xc1, 0xad, 0x4d, 0xdd, 0xed, 0x1d, 0x1c, 0x6f, 0x7a, 0x46,
+ 0xde, 0xc8, 0xbd, 0x7b, 0xf7, 0xa6, 0xfc, 0xe2, 0x89, 0x08, 0x41, 0xd7, 0xa1, 0xc9, 0x92, 0x68,
+ 0xb0, 0xe2, 0xff, 0x74, 0x72, 0xc2, 0x85, 0x2c, 0x41, 0xe1, 0xec, 0xfb, 0xec, 0xf1, 0x17, 0x18,
+ 0xbf, 0xc6, 0xf8, 0xc3, 0xfb, 0x4f, 0xda, 0xbf, 0x00, 0xbc, 0x29, 0xf9, 0xf3, 0xe7, 0x0e, 0xc6,
+ 0x86, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+};
+
+const BITMAP_OPAQUE gerber_job_file_xpm[1] = {{ png, sizeof( png ), "gerber_job_file_xpm" }};
+
+//EOF
diff --git a/bitmaps_png/sources/gerber_job_file.svg b/bitmaps_png/sources/gerber_job_file.svg
new file mode 100644
index 0000000000..3694a87463
--- /dev/null
+++ b/bitmaps_png/sources/gerber_job_file.svg
@@ -0,0 +1,818 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="26"
+   width="26"
+   version="1.1"
+   id="svg2"
+   inkscape:version="0.92.0 r15299"
+   sodipodi:docname="gerber_job_file.svg">
+  <metadata
+     id="metadata172">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1170"
+     inkscape:window-height="836"
+     id="namedview170"
+     showgrid="true"
+     inkscape:zoom="9.3622609"
+     inkscape:cx="13.030913"
+     inkscape:cy="4.5453342"
+     inkscape:window-x="413"
+     inkscape:window-y="162"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2"
+     showguides="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3100"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       originx="0"
+       originy="0"
+       spacingx="1.0666667"
+       spacingy="1.0666667" />
+  </sodipodi:namedview>
+  <defs
+     id="defs4">
+    <linearGradient
+       id="ab"
+       y2="4.2192998"
+       gradientUnits="userSpaceOnUse"
+       x2="7.5955"
+       gradientTransform="matrix(0.88924,0,0,0.78227,0.62292,7.6472)"
+       y1="43.993999"
+       x1="40.751999">
+      <stop
+         stop-color="#333"
+         offset="0"
+         id="stop7" />
+      <stop
+         stop-color="#474747"
+         offset="1"
+         id="stop9" />
+    </linearGradient>
+    <linearGradient
+       id="a"
+       y2="19500"
+       gradientUnits="userSpaceOnUse"
+       x2="15000"
+       y1="14100"
+       x1="10100">
+      <stop
+         stop-color="#f5fffa"
+         offset="0"
+         id="stop12" />
+      <stop
+         stop-color="#6f6d7f"
+         offset="1.2"
+         id="stop14" />
+    </linearGradient>
+    <linearGradient
+       id="b"
+       y2="19500"
+       gradientUnits="userSpaceOnUse"
+       x2="15000"
+       y1="14100"
+       x1="10100">
+      <stop
+         stop-color="#fff"
+         stop-opacity="0.698"
+         offset="0"
+         id="stop17" />
+      <stop
+         stop-color="#5db7ff"
+         stop-opacity="0.698"
+         offset="1.2"
+         id="stop19" />
+    </linearGradient>
+    <linearGradient
+       id="x"
+       y2="19500"
+       gradientUnits="userSpaceOnUse"
+       x2="15000"
+       y1="14100"
+       x1="10100">
+      <stop
+         stop-color="#f5ffff"
+         offset="0"
+         id="stop22" />
+      <stop
+         stop-color="#fff"
+         stop-opacity="0"
+         offset="1.2"
+         id="stop24" />
+    </linearGradient>
+    <radialGradient
+       id="ac"
+       xlink:href="#b"
+       gradientUnits="userSpaceOnUse"
+       cy="17526"
+       cx="18632"
+       gradientTransform="matrix(0.00205653,0,0,0.00205653,35.864533,-12.1536)"
+       r="40170" />
+    <radialGradient
+       id="ad"
+       xlink:href="#b"
+       gradientUnits="userSpaceOnUse"
+       cy="17831"
+       cx="18969"
+       r="23166"
+       gradientTransform="matrix(0.00191701,0,0,0.00191701,38.437333,-10.359467)" />
+    <radialGradient
+       id="ae"
+       xlink:href="#a"
+       gradientUnits="userSpaceOnUse"
+       cy="27370"
+       cx="25538"
+       gradientTransform="matrix(0.00194549,0,0,0.00194549,24.0288,-25.181866)"
+       r="3682.2" />
+    <radialGradient
+       id="af"
+       xlink:href="#x"
+       gradientUnits="userSpaceOnUse"
+       cy="17398"
+       cx="18401"
+       gradientTransform="matrix(0.00191701,0,0,0.00191701,38.242133,-10.359467)"
+       r="11888" />
+    <radialGradient
+       id="ag"
+       xlink:href="#a"
+       gradientUnits="userSpaceOnUse"
+       cy="15674"
+       cx="16467"
+       gradientTransform="matrix(0.00204277,0,0,0.00207051,35.864533,-12.1536)"
+       r="3055.2" />
+    <radialGradient
+       id="ah"
+       xlink:href="#b"
+       gradientUnits="userSpaceOnUse"
+       cy="17753"
+       cx="18300"
+       gradientTransform="matrix(0.00205653,0,0,0.00205653,35.864533,-12.1536)"
+       r="28430" />
+    <radialGradient
+       id="ai"
+       xlink:href="#a"
+       gradientUnits="userSpaceOnUse"
+       cy="33086"
+       cx="-2182.7"
+       gradientTransform="matrix(0.00349152,0,0,0.00121131,33.954133,16.765867)"
+       r="11540" />
+    <radialGradient
+       id="aj"
+       xlink:href="#a"
+       gradientUnits="userSpaceOnUse"
+       cy="18596"
+       cx="17070"
+       gradientTransform="matrix(0.00208203,0,0,0.00203136,35.864533,-12.1536)"
+       r="3734.6001" />
+    <linearGradient
+       id="ao"
+       y2="39368"
+       xlink:href="#x"
+       gradientUnits="userSpaceOnUse"
+       x2="2312.5"
+       gradientTransform="matrix(0.00349152,0,0,0.00121131,33.954133,16.765867)"
+       y1="39560"
+       x1="-1083.8" />
+    <radialGradient
+       id="ak"
+       xlink:href="#b"
+       gradientUnits="userSpaceOnUse"
+       cy="11246"
+       cx="13190"
+       gradientTransform="matrix(0.00173621,0,0,0.00173621,34.7392,-13.975467)"
+       r="16248" />
+    <linearGradient
+       id="ap"
+       y2="18951"
+       xlink:href="#a"
+       gradientUnits="userSpaceOnUse"
+       x2="12508"
+       gradientTransform="matrix(0.00205653,0,0,0.00205653,35.864533,-12.1536)"
+       y1="-85.142998"
+       x1="-1308.3" />
+    <radialGradient
+       id="al"
+       xlink:href="#a"
+       gradientUnits="userSpaceOnUse"
+       cy="29167"
+       cx="26631"
+       gradientTransform="matrix(0.00178912,0,0,0.00178912,42.586666,-6.9703469)"
+       r="4284.2002" />
+    <linearGradient
+       id="y"
+       y2="20482"
+       gradientUnits="userSpaceOnUse"
+       x2="6753.3999"
+       gradientTransform="matrix(0.00141995,0,0,0.00297856,33.954133,16.765867)"
+       y1="27356"
+       x1="850.32001">
+      <stop
+         stop-color="#a66500"
+         offset="0"
+         id="stop39" />
+      <stop
+         stop-color="#da8f00"
+         offset="1"
+         id="stop41" />
+    </linearGradient>
+    <linearGradient
+       id="z"
+       y2="21261"
+       gradientUnits="userSpaceOnUse"
+       x2="3741.1001"
+       gradientTransform="matrix(0.001344,0,0,0.00314709,33.954133,16.765867)"
+       y1="21261"
+       x1="-3478.8999">
+      <stop
+         stop-color="#eda700"
+         offset="0"
+         id="stop44" />
+      <stop
+         stop-color="#fff"
+         offset=".38824"
+         id="stop46" />
+      <stop
+         stop-color="#ffcb50"
+         offset="0.7"
+         id="stop48" />
+      <stop
+         stop-color="#ed8700"
+         offset="1"
+         id="stop50" />
+    </linearGradient>
+    <linearGradient
+       id="aa"
+       y2="29618"
+       xlink:href="#a"
+       gradientUnits="userSpaceOnUse"
+       x2="24590"
+       gradientTransform="matrix(0.00205653,0,0,0.00205653,35.864533,-12.1536)"
+       y1="405.03"
+       x1="389.39999" />
+    <radialGradient
+       id="am"
+       gradientUnits="userSpaceOnUse"
+       cy="10444"
+       cx="11715"
+       gradientTransform="matrix(0.00205653,0,0,0.00205653,35.864533,-12.1536)"
+       r="15132">
+      <stop
+         stop-color="#f5ffff"
+         stop-opacity=".49020"
+         offset="0"
+         id="stop54" />
+      <stop
+         stop-color="#fff"
+         stop-opacity="0"
+         offset="1.2"
+         id="stop56" />
+    </radialGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#ab"
+       id="linearGradient3191"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.94852267,0,0,0.83442133,0.664448,8.1570133)"
+       x1="40.751999"
+       y1="43.993999"
+       x2="7.5955"
+       y2="4.2192998" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#ab"
+       id="linearGradient1016"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.94852267,0,0,0.83442133,0.664448,8.1570133)"
+       x1="40.751999"
+       y1="43.993999"
+       x2="7.5955"
+       y2="4.2192998" />
+    <linearGradient
+       id="a-6"
+       y2="39.685001"
+       gradientUnits="userSpaceOnUse"
+       x2="34.534"
+       gradientTransform="matrix(0.92673,0,0,0.84499,4.7271,52.187)"
+       y1="12.285"
+       x1="14.463">
+      <stop
+         stop-color="#c9c9c9"
+         offset="0"
+         id="stop1040" />
+      <stop
+         stop-color="#f8f8f8"
+         offset=".25"
+         id="stop1042" />
+      <stop
+         stop-color="#e2e2e2"
+         offset=".5"
+         id="stop1044" />
+      <stop
+         stop-color="#b0b0b0"
+         offset=".75"
+         id="stop1046" />
+      <stop
+         stop-color="#c9c9c9"
+         offset="1"
+         id="stop1048" />
+    </linearGradient>
+  </defs>
+  <g
+     id="g1010"
+     transform="matrix(0.96357902,0,0,0.99699248,-0.99217666,0.8052567)">
+    <g
+       style="opacity:0.81081082"
+       id="g99"
+       transform="matrix(0.54157884,0,0,0.5495207,0.11187994,-2.8442232)">
+      <g
+         style="stroke-linecap:round;stroke-linejoin:round"
+         id="use101"
+         transform="matrix(0.88516,0.46528,-0.46528,0.88516,20.799849,-8.6726939)">
+        <rect
+           style="color:#000000;display:block;fill:#ffffff;fill-opacity:0.63253;stroke:url(#linearGradient3191);stroke-width:1.06666672"
+           ry="0.95879465"
+           height="34.145069"
+           width="33.079464"
+           display="block"
+           y="11.2"
+           x="6.928"
+           id="rect3151" />
+        <rect
+           style="color:#000000;display:block;opacity:0.79120998;fill:none;stroke:#ffffff;stroke-width:1.06666672"
+           display="block"
+           rx="0.14066133"
+           ry="0.12247467"
+           height="32.004265"
+           width="30.9312"
+           y="12.262401"
+           x="8"
+           id="rect3153" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="m 10.862933,14.365867 5.6704,0.03413 3.2,3.2 v 8.533333"
+           display="block"
+           id="path3155" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="M 24,26.133333 V 17.6 l -3.2,-3.2"
+           display="block"
+           id="path3157" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="M 28.266667,26.133333 V 17.6 l -3.2,-3.2"
+           display="block"
+           id="path3159" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="M 32.533333,26.133333 V 14.4"
+           display="block"
+           id="path3161" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 19.733333,26.133333 v 2.133334"
+           display="block"
+           id="path3163" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 24,26.133333 v 2.133334"
+           display="block"
+           id="path3165" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 28.266667,26.133333 v 2.133334"
+           display="block"
+           id="path3167" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 32.533333,26.133333 v 2.133334"
+           display="block"
+           id="path3169" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 32.533333,33.6 v 2.133333"
+           display="block"
+           id="path3171" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 28.266667,33.6 v 2.133333"
+           display="block"
+           id="path3173" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 24,33.6 v 2.133333"
+           display="block"
+           id="path3175" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 19.733333,33.6 v 2.133333"
+           display="block"
+           id="path3177" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="m 19.733333,35.733333 v 3.2 L 17.6,41.066667 h -6.4"
+           display="block"
+           id="path3179" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="m 24,35.733333 v 5.333334"
+           display="block"
+           id="path3181" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="m 28.266667,35.733333 v 3.2 L 30.4,41.066667 h 6.4"
+           display="block"
+           id="path3183" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="m 32.533333,35.733333 2.133334,2.133334 H 36.8"
+           display="block"
+           id="path3185" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;stroke:#000000;stroke-width:1.06666672"
+           display="block"
+           d="m 11.2,16.533333 h 4.266667 L 17.6,18.666667 v 19.2 l -1.066667,1.066666 H 11.2 Z"
+           id="path3187" />
+        <rect
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           display="block"
+           ry="2.1632001"
+           height="13.866667"
+           width="17.066668"
+           y="24"
+           x="17.6"
+           id="rect3189" />
+      </g>
+      <use
+         id="use103"
+         x="0"
+         y="0"
+         width="48"
+         height="48"
+         transform="matrix(0.97367,0.22797,-0.22797,0.97367,10.729289,-7.9365122)"
+         xlink:href="#an" />
+      <g
+         style="stroke-linecap:round;stroke-linejoin:round"
+         id="an"
+         transform="translate(-4.2613333,1.0552224)">
+        <rect
+           style="color:#000000;display:block;fill:#ffffff;fill-opacity:0.63253;stroke:url(#linearGradient1016);stroke-width:1.06666672"
+           ry="0.95879465"
+           height="34.145069"
+           width="33.079464"
+           display="block"
+           y="11.2"
+           x="6.928"
+           id="rect3195" />
+        <rect
+           style="color:#000000;display:block;opacity:0.79120998;fill:none;stroke:#ffffff;stroke-width:1.06666672"
+           display="block"
+           rx="0.14066133"
+           ry="0.12247467"
+           height="32.004265"
+           width="30.9312"
+           y="12.262401"
+           x="8"
+           id="rect3197" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="m 10.862933,14.365867 5.6704,0.03413 3.2,3.2 v 8.533333"
+           display="block"
+           id="path3199" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="M 24,26.133333 V 17.6 l -3.2,-3.2"
+           display="block"
+           id="path3201" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="M 28.266667,26.133333 V 17.6 l -3.2,-3.2"
+           display="block"
+           id="path3203" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="M 32.533333,26.133333 V 14.4"
+           display="block"
+           id="path3205" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 19.733333,26.133333 v 2.133334"
+           display="block"
+           id="path3207" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 24,26.133333 v 2.133334"
+           display="block"
+           id="path3209" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 28.266667,26.133333 v 2.133334"
+           display="block"
+           id="path3211" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 32.533333,26.133333 v 2.133334"
+           display="block"
+           id="path3213" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 32.533333,33.6 v 2.133333"
+           display="block"
+           id="path3215" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 28.266667,33.6 v 2.133333"
+           display="block"
+           id="path3217" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 24,33.6 v 2.133333"
+           display="block"
+           id="path3219" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:2.13333344"
+           d="m 19.733333,33.6 v 2.133333"
+           display="block"
+           id="path3221" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="m 19.733333,35.733333 v 3.2 L 17.6,41.066667 h -6.4"
+           display="block"
+           id="path3223" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="m 24,35.733333 v 5.333334"
+           display="block"
+           id="path3225" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="m 28.266667,35.733333 v 3.2 L 30.4,41.066667 h 6.4"
+           display="block"
+           id="path3227" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           d="m 32.533333,35.733333 2.133334,2.133334 H 36.8"
+           display="block"
+           id="path3229" />
+        <path
+           inkscape:connector-curvature="0"
+           style="color:#000000;display:block;stroke:#000000;stroke-width:1.06666672"
+           display="block"
+           d="m 11.2,16.533333 h 4.266667 L 17.6,18.666667 v 19.2 l -1.066667,1.066666 H 11.2 Z"
+           id="path3231" />
+        <rect
+           style="color:#000000;display:block;fill:none;stroke:#000000;stroke-width:1.06666672"
+           display="block"
+           ry="2.1632001"
+           height="13.866667"
+           width="17.066668"
+           y="24"
+           x="17.6"
+           id="rect3233" />
+      </g>
+      <path
+         style="fill:#ffffff;fill-opacity:0.51807;fill-rule:evenodd;stroke-width:1.06666672"
+         inkscape:connector-curvature="0"
+         id="path106"
+         d="M 4.2666667,27.733333 V 13.866667 H 34.133333 v 13.866666 c -7.466666,6.4 -19.2,-6.4 -29.8666663,0 z" />
+    </g>
+    <g
+       id="g114"
+       transform="matrix(0.37303414,0.10324413,-0.09465317,0.34403422,-4.4968508,-1.3805606)">
+      <g
+         style="opacity:0.18469998"
+         id="g116"
+         transform="matrix(0.001928,0,0,0.001928,35.5648,-10.49184)">
+        <path
+           style="fill-rule:evenodd;stroke-width:1.10570669"
+           inkscape:connector-curvature="0"
+           id="path118"
+           d="m 23872.83,21016.084 a 2527.3137,2527.3137 0 1 1 -5054.627,0 2527.3137,2527.3137 0 1 1 5054.627,0 z" />
+        <path
+           style="fill-rule:evenodd;stroke-width:1.06666672"
+           inkscape:connector-curvature="0"
+           id="path120"
+           d="m 20995.2,18544 c -494.848,-610.219 -685.771,-195.563 -944.715,-401.365 -198.73,-178.134 135.168,-459.222 -297.205,-926.87 l -2109.76,2098.454 c 360.523,355.733 558.496,97.792 779.307,400.128 165.578,240.64 -18.251,553.856 514.89,898.57 l 2057.494,-2068.906 z" />
+        <rect
+           style="fill-rule:evenodd;stroke-width:1.06666672"
+           id="rect122"
+           x="-2201.6001"
+           y="24636.801"
+           width="4977.8135"
+           height="1726.9333"
+           transform="rotate(-45)" />
+        <path
+           style="fill-rule:evenodd;stroke-width:1.06666672"
+           inkscape:connector-curvature="0"
+           id="path124"
+           d="m 20958.933,10346.987 c 0,5395.2 -4373.653,9768.96 -9768.96,9768.96 -5395.1997,0 -9768.9597,-4373.654 -9768.9597,-9768.96 0,-5395.2003 4373.6534,-9768.96033 9768.9597,-9768.96033 5395.2,0 9768.96,4373.65333 9768.96,9768.96033 z m -967.69,-0.01 c 0,4860.8 -3940.48,8801.28 -8801.28,8801.28 -4860.8003,0 -8801.1737,-3940.48 -8801.1737,-8801.28 0,-4860.8 3940.48,-8801.28 8801.1737,-8801.28 4860.8,0 8801.28,3940.48 8801.28,8801.28 z" />
+        <path
+           style="fill-rule:evenodd;stroke-width:1.0222187"
+           inkscape:connector-curvature="0"
+           id="path126"
+           d="m 31187.387,28241.364 a 2336.4855,2336.4855 0 1 1 -4672.971,0 2336.4855,2336.4855 0 1 1 4672.971,0 z" />
+        <rect
+           style="stroke-width:1.06666672"
+           id="rect128"
+           x="-2533.3333"
+           y="28601.6"
+           width="5890.3467"
+           height="12355.2"
+           transform="rotate(-45)" />
+      </g>
+      <path
+         style="opacity:0.29300005;fill:url(#ac);fill-rule:evenodd;stroke-width:1.06666672"
+         inkscape:connector-curvature="0"
+         id="path130"
+         d="m 72.802133,10.33856 c 0,7.183893 -5.82368,13.008 -13.008,13.008 -7.183786,0 -13.006933,-5.82368 -13.006933,-13.008 0,-7.1837867 5.82368,-13.008 13.006933,-13.008 7.183894,0 13.008,5.82368 13.008,13.008 z m 1.97152,-2.5621333 c 0,9.5886933 -7.77312,17.3621333 -17.362133,17.3621333 -9.588693,0 -17.362133,-7.773227 -17.362133,-17.3621333 0,-9.5886934 7.773226,-17.3621334 17.362133,-17.3621334 9.588693,0 17.362133,7.7732267 17.362133,17.3621334 z" />
+      <path
+         style="opacity:0.68790002;fill:url(#ad);fill-rule:evenodd;stroke-width:0.00191701"
+         inkscape:connector-curvature="0"
+         id="path132"
+         d="m 75.617807,7.5176412 a 17.686557,17.686557 0 1 1 -35.37273,0 17.686557,17.686557 0 1 1 35.37273,0 z" />
+      <path
+         style="fill:#717386;fill-rule:evenodd;stroke-width:0.00213184"
+         inkscape:connector-curvature="0"
+         id="path134"
+         d="m 81.892977,28.365297 a 4.8727467,4.8727467 0 1 1 -9.745493,0 4.8727467,4.8727467 0 1 1 9.745493,0 z" />
+      <path
+         style="fill:url(#ae);fill-rule:evenodd;stroke-width:0.00194549"
+         inkscape:connector-curvature="0"
+         id="path136"
+         d="m 81.467545,28.365892 a 4.4468141,4.4468141 0 1 1 -8.893628,0 4.4468141,4.4468141 0 1 1 8.893628,0 z" />
+      <path
+         style="fill:url(#af);fill-rule:evenodd;stroke-width:0.00191701"
+         inkscape:connector-curvature="0"
+         id="path138"
+         d="m 75.422607,7.5176412 a 17.686557,17.686557 0 1 1 -35.37273,0 17.686557,17.686557 0 1 1 35.37273,0 z" />
+      <path
+         style="fill:url(#ag);fill-rule:evenodd;stroke-width:1.06666672"
+         inkscape:connector-curvature="0"
+         id="path140"
+         d="m 76.343467,23.6 c -0.954091,-1.176533 -1.32224,-0.377056 -1.82144,-0.773845 -0.383158,-0.343446 0.260608,-0.885398 -0.573024,-1.787094 l -4.06784,4.045867 c 0.695104,0.685867 1.0768,0.188544 1.502506,0.771467 0.319243,0.463968 -0.03519,1.06784 0.992726,1.73248 l 3.96704,-3.988907 z" />
+      <path
+         style="fill:url(#ah);fill-rule:evenodd;stroke-width:1.06666672"
+         inkscape:connector-curvature="0"
+         id="path142"
+         d="m 74.241067,8.1754667 c 0,8.9271463 -7.184427,16.1642663 -16.046934,16.1642663 -8.8624,0 -16.046933,-7.236906 -16.046933,-16.1642663 0,-8.9271467 7.184427,-16.1642667 16.046933,-16.1642667 8.8624,0 16.046934,7.2368 16.046934,16.1642667 z m 1.31424,-0.6552107 c 0,10.01696 -8.12032,18.1376 -18.1376,18.1376 -10.01696,0 -18.1376,-8.12032 -18.1376,-18.1376 0,-10.01696 8.12032,-18.1376 18.1376,-18.1376 10.01696,0 18.1376,8.12032 18.1376,18.1376 z" />
+      <rect
+         style="opacity:0.9554;fill:url(#ai);fill-rule:evenodd;stroke-width:1.06666672"
+         id="rect144"
+         x="29.709867"
+         y="64.267731"
+         width="9.5974398"
+         height="3.3297067"
+         transform="rotate(-45)" />
+      <path
+         style="fill:url(#aj);fill-rule:evenodd;stroke-width:1.06666672"
+         inkscape:connector-curvature="0"
+         id="path146"
+         d="m 76.0992,23.943467 c -0.954091,-1.176534 -1.32224,-0.377056 -1.82144,-0.773846 -0.383157,-0.343445 0.211648,-1.1792 -0.866805,-2.227733 l -3.773974,3.703147 c 0.842006,0.832768 1.664427,0.286485 2.090134,0.869397 0.319242,0.463968 -0.03519,1.06784 0.992725,1.73248 l 3.379413,-3.30336 z" />
+      <rect
+         style="fill:url(#ao);fill-rule:evenodd;stroke-width:1.06666672"
+         id="rect148"
+         x="30.532267"
+         y="64"
+         width="7.9522138"
+         height="2.7589333"
+         transform="rotate(-45)" />
+      <path
+         style="opacity:0.21019999;fill:url(#ak);fill-rule:evenodd;stroke-width:0.00173621"
+         inkscape:connector-curvature="0"
+         id="path150"
+         d="m 58.124257,-0.35660928 a 6.1968926,6.1968926 0 1 1 -12.393785,0 6.1968926,6.1968926 0 1 1 12.393785,0 z" />
+      <path
+         style="fill:url(#ap);fill-rule:evenodd;stroke-width:1.06666672"
+         inkscape:connector-curvature="0"
+         id="path152"
+         d="m 76.274133,7.79552 c 0,10.40224 -8.43264,18.8352 -18.8352,18.8352 -10.40224,0 -18.8352,-8.43264 -18.8352,-18.8352 0,-10.40224 8.43264,-18.8352 18.8352,-18.8352 10.40224,0 18.8352,8.43264 18.8352,18.8352 z m -1.865706,-1.81e-5 c 0,9.3718401 -7.597334,16.9696001 -16.9696,16.9696001 -9.371734,0 -16.9696,-7.597333 -16.9696,-16.9696001 0,-9.37184 7.597333,-16.9696 16.9696,-16.9696 9.37184,0 16.9696,7.5973333 16.9696,16.9696 z" />
+      <path
+         style="fill:#808080;fill-rule:evenodd;stroke-width:0.00197088"
+         inkscape:connector-curvature="0"
+         id="path154"
+         d="m 95.995194,42.296634 a 4.5048404,4.5048404 0 1 1 -9.00968,0 4.5048404,4.5048404 0 1 1 9.00968,0 z" />
+      <path
+         style="fill:url(#al);fill-rule:evenodd;stroke-width:0.00178912"
+         inkscape:connector-curvature="0"
+         id="path156"
+         d="m 95.408646,42.273392 a 4.089392,4.089392 0 1 1 -8.178784,0 4.089392,4.089392 0 1 1 8.178784,0 z" />
+      <rect
+         style="fill:url(#y);stroke-width:1.06666672"
+         id="rect158"
+         x="29.069866"
+         y="71.911469"
+         width="11.3568"
+         height="23.821867"
+         transform="rotate(-45)" />
+      <rect
+         style="fill:url(#z);stroke-width:1.06666672"
+         id="rect160"
+         x="30.209066"
+         y="73.19146"
+         width="9.080533"
+         height="21.262934"
+         transform="rotate(-45)" />
+      <path
+         style="fill:url(#aa);fill-rule:evenodd;stroke-width:1.06666672"
+         inkscape:connector-curvature="0"
+         id="path162"
+         d="m 74.776533,7.6485333 c 0,9.5166937 -7.71488,17.2319997 -17.232,17.2319997 -9.516693,0 -17.232,-7.71488 -17.232,-17.2319997 0,-9.5166933 7.71488,-17.232 17.232,-17.232 9.516694,0 17.232,7.71488 17.232,17.232 z m -0.514368,6.4e-6 c 0,9.2326403 -7.484586,16.7168003 -16.7168,16.7168003 -9.23264,0 -16.7168,-7.484587 -16.7168,-16.7168003 0,-9.23264 7.484587,-16.7168 16.7168,-16.7168 9.23264,0 16.7168,7.4845867 16.7168,16.7168 z" />
+      <path
+         style="opacity:0.54140003;fill:url(#am);fill-rule:evenodd;stroke-width:1.06666672"
+         inkscape:connector-curvature="0"
+         id="path164"
+         d="m 60.269867,2.3768533 c 0,3.8557867 -3.12576,6.9815467 -6.98144,6.9815467 -3.855787,0 -6.98144,-3.12576 -6.98144,-6.9815467 0,-3.8557866 3.12576,-6.98144 6.98144,-6.98144 3.855786,0 6.98144,3.12576 6.98144,6.98144 z M 61.49472,1.641984 c 0,4.9381333 -4.003093,8.941227 -8.941227,8.941227 -4.938133,0 -8.941226,-4.0030937 -8.941226,-8.941227 0,-4.9381333 4.003093,-8.9412267 8.941226,-8.9412267 4.938134,0 8.941227,4.0030934 8.941227,8.9412267 z" />
+      <path
+         style="fill:#9a9ba9;fill-rule:evenodd;stroke-width:1.06666672"
+         inkscape:connector-curvature="0"
+         id="path166"
+         d="m 72.385067,27.006933 0.310048,0.25232 3.43712,-3.307946 -0.187648,-0.301291 -3.559467,3.356907 z" />
+      <path
+         style="fill:#8a92a0;fill-rule:evenodd;stroke-width:1.06666672"
+         inkscape:connector-curvature="0"
+         id="path168"
+         d="m 69.693867,24.718933 0.285653,0.210699 3.72416,-3.651093 -0.222336,-0.343243 -3.787413,3.78368 z" />
+    </g>
+  </g>
+  <g
+     style="stroke:#000000"
+     transform="matrix(0.4228008,0,0,0.47494899,-3.6057646,-15.908652)"
+     id="g1063">
+    <path
+       inkscape:connector-curvature="0"
+       style="color:#000000;fill:url(#a-6);stroke-width:1.30209994"
+       d="m 25.828,57.411 c -0.34731,0.02167 -0.68489,0.07071 -1.026,0.10631 h -0.02332 l -0.81616,4.061 c -1.3303,0.27623 -2.5818,0.74502 -3.7077,1.382 l -3.661,-2.402 c -0.98968,0.70058 -1.8903,1.5177 -2.6817,2.4026 l 2.5417,3.3807 c -0.77174,1.0754 -1.3521,2.3033 -1.679,3.5933 -5.2e-5,0.0061 -4.5e-5,0.0202 0,0.02126 l -4.4306,0.63786 c -0.081,0.60325 -0.11659,1.2267 -0.11659,1.8498 0,0.50981 0.0154,1.0128 0.0699,1.5096 l 4.4306,0.72291 c 0.31511,1.4029 0.91369,2.713 1.7489,3.8697 l -2.635,3.2956 c 0.75466,0.85424 1.6259,1.632 2.5651,2.3176 l 3.731,-2.3388 c 1.3039,0.75844 2.7595,1.2903 4.3373,1.5521 l 0.69956,4.0185 c 0.49711,0.04126 1.0069,0.04252 1.5157,0.04252 0.71836,-10e-7 1.4045,-0.02482 2.0987,-0.10631 l 0.83948,-4.1036 c 1.499,-0.341 2.906,-0.931 4.128,-1.723 l 3.5911,2.3813 c 0.93128,-0.72243 1.7829,-1.5528 2.5184,-2.4451 l -2.6117,-3.4444 c 0.70729,-1.1138 1.1974,-2.3427 1.4458,-3.6571 l 4.4073,-0.63786 c 0.03865,-0.41935 0.04663,-0.82605 0.04663,-1.2545 0,-0.74449 -0.09491,-1.4745 -0.20987,-2.19 l -4.476,-0.745 c -0.351,-1.181 -0.927,-2.283 -1.656,-3.274 l 2.635,-3.2956 c -0.817,-0.911 -1.749,-1.752 -2.775,-2.466 l -3.801,2.381 c -1.092,-0.589 -2.268,-1.041 -3.544,-1.297 l -0.7,-4.04 c -0.63673,-0.06829 -1.2787,-0.10631 -1.9355,-0.10631 -0.1775,0 -0.36018,-0.0051 -0.53633,0 -0.08587,0.0024 -0.17086,-0.0046 -0.25651,0 -0.0232,0.0012 -0.0468,-0.0014 -0.06996,0 z m 0.60629,10.333 c 0.08519,-0.0039 0.17025,0 0.25651,0 2.7603,0 5.0135,2.0545 5.0135,4.5713 1e-6,2.5168 -2.2532,4.5501 -5.0135,4.5501 -2.7603,1e-6 -4.9902,-2.0332 -4.9902,-4.5501 0,-2.4382 2.0928,-4.4491 4.7337,-4.5713 z"
+       id="path1057" />
+    <path
+       inkscape:connector-curvature="0"
+       style="color:#000000;opacity:0.34658999;fill:none;stroke-width:1.40030003"
+       d="m 25.311,58.215 -0.6553,3.932 c -1.2469,0.25892 -3.5405,1.0508 -4.5959,1.6479 l -3.4863,-2.3726 c -0.92766,0.65668 -0.99127,0.70121 -1.7331,1.5307 l 2.5207,3.4087 c -0.72338,1.008 -1.5922,2.8042 -1.9042,4.0878 0,0 -4.4171,0.67892 -4.4171,0.67892 -0.07593,0.56544 -0.03948,1.7757 0.01164,2.2413 l 4.2192,0.69303 c 0.29536,1.315 1.4006,3.4316 2.1835,4.5157 l -2.6681,3.2142 c 0.70736,0.8007 0.84892,0.87397 1.7292,1.5166 l 3.5677,-2.3833 c 1.2222,0.7109 3.6482,1.5757 5.1271,1.8211 l 0.58553,3.8824 c 0.46595,0.03867 1.7532,0.14715 2.4038,0.07077 l 0.65531,-4.0416 c 1.4042,-0.31862 3.8304,-1.2267 4.9759,-1.9697 l 3.5639,2.3479 c 0.87292,-0.67715 0.88074,-0.77919 1.5702,-1.6156 l -2.641,-3.4228 c 0.66296,-1.044 1.5202,-3.0857 1.753,-4.3177 l 4.324,-0.65416 c 0.03623,-0.39307 0.03799,-1.4892 -0.06977,-2.1599 l -4.4054,-0.69303 c -0.32887,-1.1073 -1.4575,-3.1025 -2.1409,-4.0314 l 2.8,-3.2142 c -0.76558,-0.85369 -1.0502,-0.97082 -2.0124,-1.6403 l -3.688,2.408 c -1.024,-0.553 -3.066,-1.394 -4.262,-1.634 l -0.65149,-3.8471 c -0.59683,-0.06401 -2.3187,-0.03559 -2.6598,0 z"
+       id="path1059" />
+    <path
+       inkscape:connector-curvature="0"
+       style="color:#000000;opacity:0.64772997;fill:none;stroke-width:0.71253002"
+       d="m 32.454,72.306 a 5.7605,5.2524 0 0 1 -11.521,0 5.7605,5.2524 0 1 1 11.521,0 z"
+       id="path1061" />
+  </g>
+</svg>
diff --git a/common/gbr_metadata.cpp b/common/gbr_metadata.cpp
index f9faecf525..fe24f23377 100644
--- a/common/gbr_metadata.cpp
+++ b/common/gbr_metadata.cpp
@@ -122,6 +122,41 @@ std::string GBR_APERTURE_METADATA::FormatAttribute( GBR_APERTURE_ATTRIB aAttribu
     return attribute_string;
 }
 
+wxString FormatStringFromGerber( const wxString& aString )
+{
+    // make the inverse conversion of formatStringToGerber()
+    // It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode
+    // and return a wxString (unicode 16) from the gerber string
+    wxString txt;
+
+    for( unsigned ii = 0; ii < aString.Length(); ++ii )
+    {
+        unsigned code = aString[ii];
+
+        if( code == '\\' )
+        {
+            // Convert 4 hexadecimal digits to a 16 bit unicode
+            // (Gerber allows only 4 hexadecimal digits)
+            long value = 0;
+
+            for( int jj = 0; jj < 4; jj++ )
+            {
+                value <<= 4;
+                code = aString[++ii];
+                // Very basic conversion, but it expects a valid gerber file
+                int hexa = (code <= '9' ? code - '0' : code - 'A' + 10) & 0xF;
+                value += hexa;
+            }
+
+            txt.Append( wxChar( value ) );
+        }
+        else
+            txt.Append( aString[ii] );
+    }
+
+    return txt;
+}
+
 
 std::string formatStringToGerber( const wxString& aString )
 {
diff --git a/common/pcb_plot_params.keywords b/common/pcb_plot_params.keywords
index 12ff3db2b3..059eb84684 100644
--- a/common/pcb_plot_params.keywords
+++ b/common/pcb_plot_params.keywords
@@ -1,3 +1,4 @@
+creategerberjobfile
 drillshape
 excludeedgelayer
 false
diff --git a/common/wildcards_and_files_ext.cpp b/common/wildcards_and_files_ext.cpp
index 1ac009c112..d29b1f62f7 100644
--- a/common/wildcards_and_files_ext.cpp
+++ b/common/wildcards_and_files_ext.cpp
@@ -42,7 +42,8 @@ const wxString ProjectFileExtension( wxT( "pro" ) );
 const wxString SchematicFileExtension( wxT( "sch" ) );
 const wxString NetlistFileExtension( wxT( "net" ) );
 const wxString ComponentFileExtension( wxT( "cmp" ) );
-const wxString GerberFileExtension( wxT( ".((gbr|(gb|gt)[alops])|pho)" ) );
+const wxString GerberFileExtension( "gbr" );
+const wxString GerberJobFileExtension( "gbj" );
 const wxString HtmlFileExtension( wxT( "html" ) );
 
 const wxString LegacyPcbFileExtension( wxT( "brd" ) );
diff --git a/gerbview/CMakeLists.txt b/gerbview/CMakeLists.txt
index ffbde6a668..be12ffae31 100644
--- a/gerbview/CMakeLists.txt
+++ b/gerbview/CMakeLists.txt
@@ -51,7 +51,7 @@ set( GERBVIEW_SRCS
     gerbview_config.cpp
     gerbview_frame.cpp
     hotkeys.cpp
-    clear_gbr_drawlayers.cpp
+    job_file_reader.cpp
     locate.cpp
     menubar.cpp
     onleftclick.cpp
diff --git a/gerbview/events_called_functions.cpp b/gerbview/events_called_functions.cpp
index c9512bcc8b..4e70219014 100644
--- a/gerbview/events_called_functions.cpp
+++ b/gerbview/events_called_functions.cpp
@@ -54,6 +54,7 @@ BEGIN_EVENT_TABLE( GERBVIEW_FRAME, EDA_DRAW_FRAME )
     EVT_TOOL( ID_GERBVIEW_ERASE_ALL, GERBVIEW_FRAME::Files_io )
     EVT_TOOL( ID_GERBVIEW_LOAD_DRILL_FILE, GERBVIEW_FRAME::Files_io )
     EVT_TOOL( ID_GERBVIEW_LOAD_ZIP_ARCHIVE_FILE, GERBVIEW_FRAME::Files_io )
+    EVT_TOOL( ID_GERBVIEW_LOAD_JOB_FILE, GERBVIEW_FRAME::Files_io )
     EVT_TOOL( ID_NEW_BOARD, GERBVIEW_FRAME::Files_io )
     EVT_TOOL( ID_GERBVIEW_SET_PAGE_BORDER, GERBVIEW_FRAME::Process_Special_Functions )
 
@@ -70,6 +71,9 @@ BEGIN_EVENT_TABLE( GERBVIEW_FRAME, EDA_DRAW_FRAME )
     EVT_MENU_RANGE( ID_GERBVIEW_ZIP_FILE1, ID_GERBVIEW_ZIP_FILE9,
                     GERBVIEW_FRAME::OnZipFileHistory )
 
+    EVT_MENU_RANGE( ID_GERBVIEW_JOB_FILE1, ID_GERBVIEW_JOB_FILE9,
+                    GERBVIEW_FRAME::OnJobFileHistory )
+
     EVT_MENU( wxID_EXIT, GERBVIEW_FRAME::OnQuit )
 
     // menu Preferences
diff --git a/gerbview/files.cpp b/gerbview/files.cpp
index 3fe971402d..3562a29486 100644
--- a/gerbview/files.cpp
+++ b/gerbview/files.cpp
@@ -74,6 +74,7 @@ void GERBVIEW_FRAME::OnDrlFileHistory( wxCommandEvent& event )
     }
 }
 
+
 void GERBVIEW_FRAME::OnZipFileHistory( wxCommandEvent& event )
 {
     wxString filename;
@@ -87,6 +88,18 @@ void GERBVIEW_FRAME::OnZipFileHistory( wxCommandEvent& event )
 }
 
 
+void GERBVIEW_FRAME::OnJobFileHistory( wxCommandEvent& event )
+{
+    wxString filename;
+    filename = GetFileFromHistory( event.GetId(), _( "Job files" ), &m_jobFileHistory );
+
+    if( !filename.IsEmpty() )
+    {
+        LoadGerberJobFile( filename );
+    }
+}
+
+
 /* File commands. */
 void GERBVIEW_FRAME::Files_io( wxCommandEvent& event )
 {
@@ -116,6 +129,11 @@ void GERBVIEW_FRAME::Files_io( wxCommandEvent& event )
         m_canvas->Refresh();
         break;
 
+    case ID_GERBVIEW_LOAD_JOB_FILE:
+        LoadGerberJobFile( wxEmptyString );
+        m_canvas->Refresh();
+        break;
+
     default:
         wxFAIL_MSG( wxT( "File_io: unexpected command id" ) );
         break;
diff --git a/gerbview/gerbview_config.cpp b/gerbview/gerbview_config.cpp
index 75c1ceacab..8b52e1a19b 100644
--- a/gerbview/gerbview_config.cpp
+++ b/gerbview/gerbview_config.cpp
@@ -29,7 +29,6 @@
 */
 
 #include <fctsys.h>
-#include <macros.h>
 #include <id.h>
 #include <common.h>
 #include <class_drawpanel.h>
@@ -41,9 +40,6 @@
 #include <dialog_hotkeys_editor.h>
 
 
-#define GROUP wxT("/gerbview")
-
-
 void GERBVIEW_FRAME::Process_Config( wxCommandEvent& event )
 {
     int      id = event.GetId();
diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp
index 0853de3552..418d43fd7e 100644
--- a/gerbview/gerbview_frame.cpp
+++ b/gerbview/gerbview_frame.cpp
@@ -37,6 +37,7 @@
 #include <class_gbr_layer_box_selector.h>
 #include <msgpanel.h>
 #include <bitmaps.h>
+#include <wildcards_and_files_ext.h>
 
 #include <gerbview.h>
 #include <gerbview_frame.h>
@@ -81,6 +82,7 @@ GERBVIEW_FRAME::GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ):
     m_displayMode   = 0;
     m_drillFileHistory.SetBaseId( ID_GERBVIEW_DRILL_FILE1 );
     m_zipFileHistory.SetBaseId( ID_GERBVIEW_ZIP_FILE1 );
+    m_jobFileHistory.SetBaseId( ID_GERBVIEW_JOB_FILE1 );
 
     if( m_canvas )
         m_canvas->SetEnableBlockCommands( true );
@@ -230,8 +232,10 @@ bool GERBVIEW_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
             wxFileName fn( aFileSet[i] );
             wxString ext = fn.GetExt();
 
-            if( ext == "drl" )
+            if( ext == DrillFileExtension )     // In Excellon format
                 LoadExcellonFiles( aFileSet[i] );
+            else if( ext == GerberJobFileExtension )
+                LoadGerberJobFile( aFileSet[i] );
             else
                 LoadGerberFiles( aFileSet[i] );
         }
@@ -307,6 +311,12 @@ void GERBVIEW_FRAME::LoadSettings( wxConfigBase* aCfg )
     aCfg->SetPath( wxT( "zip_files" ) );
     m_zipFileHistory.Load( *aCfg );
     aCfg->SetPath( wxT( ".." ) );
+
+    // because we have more than one file history, we must read this one
+    // using a specific path
+    aCfg->SetPath( "job_files" );
+    m_jobFileHistory.Load( *aCfg );
+    aCfg->SetPath( wxT( ".." ) );
 }
 
 
@@ -334,6 +344,11 @@ void GERBVIEW_FRAME::SaveSettings( wxConfigBase* aCfg )
     aCfg->SetPath( wxT( "zip_files" ) );
     m_zipFileHistory.Save( *aCfg );
     aCfg->SetPath( wxT( ".." ) );
+
+    // Save the job file history list.
+    aCfg->SetPath( "job_files" );
+    m_jobFileHistory.Save( *aCfg );
+    aCfg->SetPath( ".." );
 }
 
 
diff --git a/gerbview/gerbview_frame.h b/gerbview/gerbview_frame.h
index 31f23e9fb0..39a7f1b868 100644
--- a/gerbview/gerbview_frame.h
+++ b/gerbview/gerbview_frame.h
@@ -163,6 +163,9 @@ protected:
     // Auxiliary file history used to store drill files history.
     wxFileHistory           m_drillFileHistory;
 
+    // Auxiliary file history used to store job files history.
+    wxFileHistory           m_jobFileHistory;
+
     /// The last filename chosen to be proposed to the user
     wxString                m_lastFileName;
 
@@ -606,6 +609,12 @@ public:
      */
     void                OnZipFileHistory( wxCommandEvent& event );
 
+    /**
+     * deletes the current data and load a gerber job file selected from the
+     * history list.
+     */
+    void                OnJobFileHistory( wxCommandEvent& event );
+
     /**
      * Extracts gerber and drill files from the zip archive, and load them
      * @param aFullFileName is the full filename of the zip archive
@@ -647,6 +656,17 @@ public:
      */
     bool                LoadZipArchiveFile( const wxString& aFileName );
 
+
+    /**
+     * Load a Gerber job file, and load gerber files found in job files.
+     * @param aFileName - void string or file name with full path to open or empty string to
+     *                    open a new file.
+     *                    if empty string: user will be prompted for filename(s)
+     * @return true if file(s) was opened successfully.
+     */
+    bool                LoadGerberJobFile( const wxString& aFileName );
+
+
     bool                GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey = 0 ) override;
 
     /**
diff --git a/gerbview/gerbview_id.h b/gerbview/gerbview_id.h
index 48e39fb5dc..e54a6bb07e 100644
--- a/gerbview/gerbview_id.h
+++ b/gerbview/gerbview_id.h
@@ -41,6 +41,7 @@ enum gerbview_ids
 
     ID_GERBVIEW_SHOW_LIST_DCODES,
     ID_GERBVIEW_LOAD_DRILL_FILE,
+    ID_GERBVIEW_LOAD_JOB_FILE,
     ID_GERBVIEW_LOAD_ZIP_ARCHIVE_FILE,
     ID_GERBVIEW_ERASE_ALL,
     ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE,
@@ -66,7 +67,19 @@ enum gerbview_ids
     ID_GERBVIEW_DRILL_FILE8,
     ID_GERBVIEW_DRILL_FILE9,
 
-    // IDs for drill file history (wxID_FILEnn is already in use)
+    // IDs for job file history (wxID_FILEnn is already in use)
+    ID_GERBVIEW_JOB_FILE,
+    ID_GERBVIEW_JOB_FILE1,
+    ID_GERBVIEW_JOB_FILE2,
+    ID_GERBVIEW_JOB_FILE3,
+    ID_GERBVIEW_JOB_FILE4,
+    ID_GERBVIEW_JOB_FILE5,
+    ID_GERBVIEW_JOB_FILE6,
+    ID_GERBVIEW_JOB_FILE7,
+    ID_GERBVIEW_JOB_FILE8,
+    ID_GERBVIEW_JOB_FILE9,
+
+    // IDs for zip file history (wxID_FILEnn is already in use)
     ID_GERBVIEW_ZIP_FILE,
     ID_GERBVIEW_ZIP_FILE1,
     ID_GERBVIEW_ZIP_FILE2,
diff --git a/gerbview/job_file_reader.cpp b/gerbview/job_file_reader.cpp
new file mode 100644
index 0000000000..48798dbba8
--- /dev/null
+++ b/gerbview/job_file_reader.cpp
@@ -0,0 +1,245 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2017 Jean-Pierre Charras  jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+/**
+ * @file job_file_reader.cpp
+ */
+
+#include <fctsys.h>
+#include <wx/filename.h>
+
+#include <gerbview.h>
+#include <richio.h>
+#include <class_drawpanel.h>
+#include <class_gerber_file_image.h>
+#include <class_gerber_file_image_list.h>
+#include <gerbview_frame.h>
+#include <reporter.h>
+#include <plot_auxiliary_data.h>
+#include <html_messagebox.h>
+
+extern int ReadInt( char*& text, bool aSkipSeparator = true );
+extern double ReadDouble( char*& text, bool aSkipSeparator = true );
+extern bool GetEndOfBlock( char* buff, char*& text, FILE* gerber_file );
+
+/**
+ * this class read and parse a Gerber job file to extract useful info
+ * for GerbView
+ *
+ * In a gerber job file, data lines start by
+ * %TF.     (usual Gerber X2 info)
+ * %TJ.B.   (board info)
+ * %TJ.D.   (design info)
+ * %TJ.L.   (layers info)
+ * some others are not yet handled by Kicad
+ * M02*     is the last line
+ */
+class GERBER_JOBFILE_READER
+{
+public:
+    GERBER_JOBFILE_READER( const wxString& aFileName, REPORTER* aReporter )
+    {
+        m_filename = aFileName;
+        m_reporter = aReporter;
+    }
+
+    ~GERBER_JOBFILE_READER() {}
+
+    bool ReadGerberJobFile();       /// read the .gbj file
+    wxArrayString& GetGerberFiles() { return m_GerberFiles; }
+
+private:
+    /** parse a string starting by "%TJ.L" (layer gerber filename)
+     * and add the filename in m_GerberFiles
+     */
+    bool parseTJLayerString( wxString& aText );
+
+private:
+    REPORTER* m_reporter;
+    wxFileName m_filename;
+    wxArrayString m_GerberFiles;    // List of gerber files in job
+};
+
+
+bool GERBER_JOBFILE_READER::ReadGerberJobFile()
+{
+    // Read the gerber file */
+   FILE* jobFile = wxFopen( m_filename.GetFullPath(), wxT( "rt" ) );
+
+    if( jobFile == nullptr )
+        return false;
+
+    LOCALE_IO toggleIo;
+
+    FILE_LINE_READER jobfileReader( jobFile, m_filename.GetFullPath() );  // Will close jobFile
+
+    wxString msg;
+    wxString data;
+
+    while( true )
+    {
+        char* line = jobfileReader.ReadLine();
+
+        if( !line )     // end of file
+            break;
+
+        wxString text( line );
+        text.Trim( true );
+        text.Trim( false );
+
+        // Search for lines starting by '%', others are not usefull
+        if( text.StartsWith( "%TJ.L.", &data ) )
+        {
+            parseTJLayerString( data );
+            continue;
+        }
+
+        if( text.StartsWith( "M02" ) )  // End of file
+            break;
+    }
+
+    return true;
+}
+
+
+bool GERBER_JOBFILE_READER::parseTJLayerString( wxString& aText )
+{
+    // Parse a line like:
+    // %TJ.L."Copper,L1,Top",Positive,kit-dev-coldfire-xilinx_5213-Top_layer.gbr*%
+    // and extract the .gbr filename
+
+    // The filename is between the last comma in string and the '*' char
+    // the filename cannot contain itself a comma:
+    // this is a not allowed char, that is transcoded in hexa sequence
+    // if found in filename
+    wxString name = aText.AfterLast( ',' ).BeforeFirst( '*' );
+    m_GerberFiles.Add( FormatStringFromGerber( name ) );
+
+    return true;
+}
+
+
+bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
+{
+#define jobFileWildcard  _( "Gerber job file (*.gbj)|*.gbj;.gbj" )
+    wxFileName filename = aFullFileName;
+    wxString currentPath;
+
+    if( !filename.IsOk() )
+    {
+        // Use the current working directory if the file name path does not exist.
+        if( filename.DirExists() )
+            currentPath = filename.GetPath();
+        else
+            currentPath = m_mruPath;
+
+        wxFileDialog dlg( this, _( "Open Gerber Job File" ),
+                          currentPath,
+                          filename.GetFullName(),
+                          jobFileWildcard,
+                          wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
+
+        if( dlg.ShowModal() == wxID_CANCEL )
+            return false;
+
+        filename = dlg.GetPath();
+        currentPath = wxGetCwd();
+        m_mruPath = currentPath;
+    }
+    else
+    {
+        currentPath = filename.GetPath();
+        m_mruPath = currentPath;
+    }
+
+    wxString msg;
+    WX_STRING_REPORTER reporter( &msg );
+
+    if( filename.IsOk() )
+    {
+        GERBER_JOBFILE_READER gbjReader( filename.GetFullPath(), &reporter );
+
+        if( gbjReader.ReadGerberJobFile() )
+        {
+            // Update the list of recent drill files.
+            UpdateFileHistory( filename.GetFullPath(), &m_jobFileHistory );
+
+            Clear_DrawLayers( false );
+            ClearMsgPanel();
+
+            wxArrayString& gbrfiles = gbjReader.GetGerberFiles();
+
+            wxFileName gbr_fn = filename;
+            bool read_ok;
+            int layer = 0;
+            setActiveLayer( layer, false );
+
+            for( unsigned ii = 0; ii < gbrfiles.GetCount(); ii++ )
+            {
+                gbr_fn.SetFullName( gbrfiles[ii] );
+
+                if( gbr_fn.FileExists() )
+                {
+                    //LoadGerberFiles( gbr_fn.GetFullPath() );
+                    read_ok = Read_GERBER_File( gbr_fn.GetFullPath() );
+
+                    if( read_ok )
+                    {
+                        layer = getNextAvailableLayer( layer );
+                        setActiveLayer( layer, false );
+                    }
+                }
+                else
+                    read_ok = false;
+
+                if( !read_ok )
+                {
+                    wxString err;
+                    err.Printf( _( "Can't load Gerber file:<br><i>%s</i><br>" ), gbr_fn.GetFullPath() );
+                    reporter.Report( err, REPORTER::RPT_WARNING );
+                }
+            }
+
+            GetImagesList()->SortImagesByZOrder();
+            ReFillLayerWidget();
+            syncLayerBox( true );
+            GetCanvas()->Refresh();
+        }
+    }
+
+    Zoom_Automatique( false );
+
+    if( !msg.IsEmpty() )
+    {
+        wxSafeYield();  // Allows slice of time to redraw the screen
+                        // to refresh widgets, before displaying messages
+        HTML_MESSAGE_BOX mbox( this, _( "Messages" ) );
+        mbox.ListSet( msg );
+        mbox.ShowModal();
+    }
+
+    return true;
+}
+
+
diff --git a/gerbview/menubar.cpp b/gerbview/menubar.cpp
index f991b1ad06..40bb93fb93 100644
--- a/gerbview/menubar.cpp
+++ b/gerbview/menubar.cpp
@@ -59,22 +59,25 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     wxMenu* fileMenu = new wxMenu;
 
     // Load Gerber files
-    AddMenuItem( fileMenu,
-                 wxID_FILE,
+    AddMenuItem( fileMenu, wxID_FILE,
                  _( "Load &Gerber File" ),
                  _( "Load a new Gerber file on the current layer. Previous data will be deleted" ),
                  KiBitmap( gerber_file_xpm ) );
 
     // Load Excellon drill files
-    AddMenuItem( fileMenu,
-                 ID_GERBVIEW_LOAD_DRILL_FILE,
+    AddMenuItem( fileMenu, ID_GERBVIEW_LOAD_DRILL_FILE,
                  _( "Load &EXCELLON Drill File" ),
                  _( "Load excellon drill file" ),
                  KiBitmap( gerbview_drill_file_xpm ) );
 
+    // Load Gerber job files
+    AddMenuItem( fileMenu, ID_GERBVIEW_LOAD_JOB_FILE,
+                 _( "Load Gerber &Job File" ),
+                 _( "Load a Gerber job file, and load gerber files depending on the job" ),
+                 KiBitmap( gerber_job_file_xpm ) );
+
     // Load Zip archive files
-    AddMenuItem( fileMenu,
-                 ID_GERBVIEW_LOAD_ZIP_ARCHIVE_FILE,
+    AddMenuItem( fileMenu, ID_GERBVIEW_LOAD_ZIP_ARCHIVE_FILE,
                  _( "Load &Zip Archive File" ),
                  _( "Load a zipped archive (Gerber and drill) file" ),
                  KiBitmap( zip_xpm ) );
@@ -92,8 +95,7 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     Kiface().GetFileHistory().UseMenu( openRecentGbrMenu );
     Kiface().GetFileHistory().AddFilesToMenu();
 
-    AddMenuItem( fileMenu, openRecentGbrMenu,
-                 wxID_ANY,
+    AddMenuItem( fileMenu, openRecentGbrMenu, wxID_ANY,
                  _( "Open &Recent Gerber File" ),
                  _( "Open a recent opened Gerber file" ),
                  KiBitmap( recent_xpm ) );
@@ -107,8 +109,7 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     openRecentDrlMenu = new wxMenu();
     m_drillFileHistory.UseMenu( openRecentDrlMenu );
     m_drillFileHistory.AddFilesToMenu( );
-    AddMenuItem( fileMenu, openRecentDrlMenu,
-                 wxID_ANY,
+    AddMenuItem( fileMenu, openRecentDrlMenu, wxID_ANY,
                  _( "Open Recent Dri&ll File" ),
                  _( "Open a recent opened drill file" ),
                  KiBitmap( recent_xpm ) );
@@ -122,12 +123,25 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     openRecentZipArchiveMenu = new wxMenu();
     m_zipFileHistory.UseMenu( openRecentZipArchiveMenu );
     m_zipFileHistory.AddFilesToMenu( );
-    AddMenuItem( fileMenu, openRecentZipArchiveMenu,
-                 wxID_ANY,
+    AddMenuItem( fileMenu, openRecentZipArchiveMenu, wxID_ANY,
                  _( "Open Recent Zip &Archive File" ),
                  _( "Open a recent opened zip archive file" ),
                  KiBitmap( recent_xpm ) );
 
+    // Recent job files
+    static wxMenu* openRecentJobFilesMenu;
+
+    if( openRecentJobFilesMenu )
+        m_jobFileHistory.RemoveMenu( openRecentJobFilesMenu );
+
+    openRecentJobFilesMenu = new wxMenu();
+    m_jobFileHistory.UseMenu( openRecentJobFilesMenu );
+    m_jobFileHistory.AddFilesToMenu( );
+    AddMenuItem( fileMenu, openRecentJobFilesMenu, wxID_ANY,
+                 _( "Open Recent &Job File" ),
+                 _( "Open a recent opened gerber job file" ),
+                 KiBitmap( recent_xpm ) );
+
     // Separator
     fileMenu->AppendSeparator();
 
@@ -152,40 +166,33 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     fileMenu->AppendSeparator();
 
     // Print
-    AddMenuItem( fileMenu,
-                 wxID_PRINT,
-                 _( "&Print" ),
-                 _( "Print gerber" ),
+    AddMenuItem( fileMenu, wxID_PRINT,
+                 _( "&Print" ), _( "Print gerber" ),
                  KiBitmap( print_button_xpm ) );
 
     // Separator
     fileMenu->AppendSeparator();
 
     // Exit
-    AddMenuItem( fileMenu,
-                 wxID_EXIT,
-                 _( "&Close" ),
-                 _( "Close GerbView" ),
+    AddMenuItem( fileMenu, wxID_EXIT,
+                 _( "&Close" ), _( "Close GerbView" ),
                  KiBitmap( exit_xpm ) );
 
     // Menu for configuration and preferences
     wxMenu* configMenu = new wxMenu;
 
     // Hide layer manager
-    AddMenuItem( configMenu,
-                 ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
+    AddMenuItem( configMenu, ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
                  _( "Hide &Layers Manager" ),
                  m_show_layer_manager_tools ?
                            _( "Hide &Layers Manager" ) : _("Show &Layers Manager" ),
                  KiBitmap( layers_manager_xpm ) );
 
     // Options (Preferences on WXMAC)
-
 #ifdef __WXMAC__
     configMenu->Append(wxID_PREFERENCES);
 #else
-    AddMenuItem( configMenu,
-                 wxID_PREFERENCES,
+    AddMenuItem( configMenu, wxID_PREFERENCES,
                  _( "&Options" ),
                  _( "Set options to draw items" ),
                  KiBitmap( preference_xpm ) );
@@ -204,15 +211,13 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     wxMenu* miscellaneousMenu = new wxMenu;
 
     // List dcodes
-    AddMenuItem( miscellaneousMenu,
-                 ID_GERBVIEW_SHOW_LIST_DCODES,
+    AddMenuItem( miscellaneousMenu, ID_GERBVIEW_SHOW_LIST_DCODES,
                  _( "&List DCodes" ),
                  _( "List D-codes defined in Gerber files" ),
                  KiBitmap( show_dcodenumber_xpm ) );
 
     // Show source
-    AddMenuItem( miscellaneousMenu,
-                 ID_GERBVIEW_SHOW_SOURCE,
+    AddMenuItem( miscellaneousMenu, ID_GERBVIEW_SHOW_SOURCE,
                  _( "&Show Source" ),
                  _( "Show source file for the current layer" ),
                  KiBitmap( tools_xpm ) );
@@ -221,8 +226,7 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     miscellaneousMenu->AppendSeparator();
 
     // Erase graphic layer
-    AddMenuItem( miscellaneousMenu,
-                 ID_GERBVIEW_ERASE_CURR_LAYER,
+    AddMenuItem( miscellaneousMenu, ID_GERBVIEW_ERASE_CURR_LAYER,
                  _( "&Clear Current Layer" ),
                  _( "Erase the graphic layer currently selected" ),
                  KiBitmap( delete_sheet_xpm ) );
@@ -231,8 +235,7 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     miscellaneousMenu->AppendSeparator();
 
     // Text editor (usefull to browse source files)
-    AddMenuItem( miscellaneousMenu,
-                 ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR,
+    AddMenuItem( miscellaneousMenu, ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR,
                  _( "&Text Editor" ),
                  _( "Select your preferred text editor" ),
                  KiBitmap( editor_xpm ) );
@@ -240,14 +243,12 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     // Help menu
     wxMenu* helpMenu = new wxMenu;
 
-    AddMenuItem( helpMenu,
-                 wxID_HELP,
+    AddMenuItem( helpMenu, wxID_HELP,
                  _( "Gerbview &Manual" ),
                  _( "Open the GerbView Manual" ),
                  KiBitmap( online_help_xpm ) );
 
-    AddMenuItem( helpMenu,
-                 ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST,
+    AddMenuItem( helpMenu, ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST,
                  _( "&List Hotkeys" ),
                  _( "Displays the current hotkeys list and corresponding commands" ),
                  KiBitmap( hotkeys_xpm ) );
@@ -264,10 +265,8 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     helpMenu->AppendSeparator();
 
     // About Kicad
-    AddMenuItem( helpMenu,
-                 wxID_ABOUT,
-                 _( "&About Kicad" ),
-                 _( "About KiCad" ),
+    AddMenuItem( helpMenu, wxID_ABOUT,
+                 _( "&About Kicad" ), _( "About KiCad" ),
                  KiBitmap( about_xpm ) );
 
     // Append menus to the menubar
diff --git a/gerbview/readgerb.cpp b/gerbview/readgerb.cpp
index ce30cd52aa..59f2ec61f1 100644
--- a/gerbview/readgerb.cpp
+++ b/gerbview/readgerb.cpp
@@ -69,9 +69,9 @@ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName )
     }
 
     /* if the gerber file is only a RS274D file
-     * (i.e. without any aperture information), wran the user:
+     * (i.e. without any aperture information, but with items), warn the user:
      */
-    if( !gerber->m_Has_DCode )
+    if( !gerber->m_Has_DCode && gerber->GetItemsList() )
     {
         msg = _("Warning: this file has no D-Code definition\n"
                 "It is perhaps an old RS274D file\n"
@@ -101,12 +101,6 @@ bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
 
     m_FileName = aFullFileName;
 
-    wxString path = wxPathOnly( aFullFileName );
-
-    // This change is needed to load included files, if exists:
-    if( path != wxEmptyString )
-        wxSetWorkingDirectory( path );
-
     LOCALE_IO toggleIo;
 
     wxString msg;
diff --git a/include/bitmaps.h b/include/bitmaps.h
index 14a7dffc31..a5de83bfab 100644
--- a/include/bitmaps.h
+++ b/include/bitmaps.h
@@ -169,6 +169,7 @@ EXTERN_BITMAP( gbr_select_mode0_xpm )
 EXTERN_BITMAP( gbr_select_mode1_xpm )
 EXTERN_BITMAP( gbr_select_mode2_xpm )
 EXTERN_BITMAP( gerbview_drill_file_xpm )
+EXTERN_BITMAP( gerber_job_file_xpm )
 EXTERN_BITMAP( gerber_file_xpm )
 EXTERN_BITMAP( gerbview_clear_layers_xpm )
 EXTERN_BITMAP( gerbview_show_negative_objects_xpm )
diff --git a/include/plot_auxiliary_data.h b/include/plot_auxiliary_data.h
index b909d7e27f..100acb3feb 100644
--- a/include/plot_auxiliary_data.h
+++ b/include/plot_auxiliary_data.h
@@ -151,6 +151,7 @@ private:
     bool m_isCopper;
 };
 
+
 /**
  * This helper function "normalize" aString and convert it to a Gerber std::string
  * Normalisation means convert any code > 0x7F and unautorized code to a hexadecimal
@@ -161,6 +162,14 @@ private:
  */
 std::string formatStringToGerber( const wxString& aString );
 
+/**
+ * This helper function make the inverse conversion of formatStringToGerber()
+ * It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode
+ * @param aString = the wxString compliant with a gerber string format
+ * @return a wxString (unicode 16) from the gerber string
+ */
+wxString FormatStringFromGerber( const wxString& aString );
+
 /**
  * Generates the string to print to a gerber file, to set a net attribute
  * for a graphic object.
diff --git a/include/wildcards_and_files_ext.h b/include/wildcards_and_files_ext.h
index 5bd7fa1ca3..1a2f223f2d 100644
--- a/include/wildcards_and_files_ext.h
+++ b/include/wildcards_and_files_ext.h
@@ -51,6 +51,7 @@ extern const wxString ProjectFileExtension;
 extern const wxString SchematicFileExtension;
 extern const wxString NetlistFileExtension;
 extern const wxString GerberFileExtension;
+extern const wxString GerberJobFileExtension;
 extern const wxString HtmlFileExtension;
 
 extern const wxString LegacyPcbFileExtension;
diff --git a/kicad/tree_project_frame.cpp b/kicad/tree_project_frame.cpp
index 4512d47f2a..2eb304d23e 100644
--- a/kicad/tree_project_frame.cpp
+++ b/kicad/tree_project_frame.cpp
@@ -75,9 +75,10 @@ static const wxChar* s_allowedExtensionsToList[] =
     wxT( "^.*\\.txt$" ),
     wxT( "^.*\\.pho$" ),            // Gerber file (Old Kicad extension)
     wxT( "^.*\\.gbr$" ),            // Gerber file
-    wxT( "^.*\\.gb[alops]$" ),      // Gerber back (or bottom) layer file
-    wxT( "^.*\\.gt[alops]$" ),      // Gerber front (or top) layer file
-    wxT( "^.*\\.g[0-9]{1,2}$" ),    // Gerber inner layer file
+    wxT( "^.*\\.gbj$" ),            // Gerber job file
+    wxT( "^.*\\.gb[alops]$" ),      // Gerber back (or bottom) layer file (deprecated Protel ext)
+    wxT( "^.*\\.gt[alops]$" ),      // Gerber front (or top) layer file (deprecated Protel ext)
+    wxT( "^.*\\.g[0-9]{1,2}$" ),    // Gerber inner layer file (deprecated Protel ext)
     wxT( "^.*\\.odt$" ),
     wxT( "^.*\\.htm$" ),
     wxT( "^.*\\.html$" ),
@@ -102,6 +103,9 @@ const wxChar  TextFileExtension[] = wxT( "txt" );
 // File wildcard definitions.
 const wxChar  TextFileWildcard[] = wxT( "Text files (*.txt)|*.txt" );
 
+// Gerber file extension wildcard.
+const wxString GerberFileExtensionWildCard( ".((gbr|gbj|(gb|gt)[alops])|pho)" );
+
 
 /**
  * @brief class TREE_PROJECT_FRAME is the frame that shows the tree list
@@ -255,7 +259,7 @@ wxString TREE_PROJECT_FRAME::GetFileExt( TreeFileType type )
         break;
 
     case TREE_GERBER:
-        ext = GerberFileExtension;
+        ext = GerberFileExtensionWildCard;
         break;
 
     case TREE_HTML:
diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index 85a1144786..a57c035f55 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -182,6 +182,7 @@ set( PCBNEW_EXPORTERS
     exporters/gendrill_Excellon_writer.cpp
     exporters/gendrill_file_writer_base.cpp
     exporters/gendrill_gerber_writer.cpp
+    exporters/gerber_jobfile_writer.cpp
     )
 
 set( PCBNEW_MICROWAVE_SRCS
diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp
index 8c89425215..efb7272690 100644
--- a/pcbnew/dialogs/dialog_plot.cpp
+++ b/pcbnew/dialogs/dialog_plot.cpp
@@ -31,9 +31,11 @@
 #include <confirm.h>
 #include <wxPcbStruct.h>
 #include <pcbplot.h>
+#include <gerber_jobfile_writer.h>
 #include <base_units.h>
 #include <macros.h>
 #include <reporter.h>
+#include <wildcards_and_files_ext.h>
 
 #include <class_board.h>
 #include <wx/ffile.h>
@@ -164,6 +166,9 @@ void DIALOG_PLOT::init_Dialog()
     // Grey out if m_useGerberX2Attributes is not checked
     m_useGerberNetAttributes->Enable( m_useGerberX2Attributes->GetValue() );
 
+    // Option to generate a Gerber job file
+    m_generateGerberJobFile->SetValue( m_plotOpts.GetCreateGerberJobFile() );
+
     // Gerber precision for coordinates
     m_rbGerberFormat->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
 
@@ -682,6 +687,8 @@ void DIALOG_PLOT::applyPlotSettings()
     tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
     tempOptions.SetUseGerberAttributes( m_useGerberX2Attributes->GetValue() );
     tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
+    tempOptions.SetCreateGerberJobFile( m_generateGerberJobFile->GetValue() );
+
     tempOptions.SetGerberPrecision( m_rbGerberFormat->GetSelection() == 0 ? 5 : 6 );
 
     LSET selectedLayers;
@@ -740,6 +747,14 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
 {
     applyPlotSettings();
 
+    // If no layer selected, we have nothing plotted.
+    // Prompt user if it happens because he could think there is a bug in Pcbnew.
+    if( !m_plotOpts.GetLayerSelection().any() )
+    {
+        DisplayError( this, _( "No layer selected, Nothing to plot" ) );
+        return;
+    }
+
     // Create output directory if it does not exist (also transform it in
     // absolute form). Bail if it fails
     wxFileName  outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
@@ -781,7 +796,7 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
     }
 
     /* If the scale factor edit controls are disabled or the scale value
-     * is 0, don't adjust the base scale factor.   This fixes a bug when
+     * is 0, don't adjust the base scale factor. This fixes a bug when
      * the default scale adjust is initialized to 0 and saved in program
      * settings resulting in a divide by zero fault.
      */
@@ -807,6 +822,8 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
         DisplayInfoMessage( this,
                             _( "Warning: Scale option set to a very large value" ) );
 
+    GERBER_JOBFILE_WRITER jobfile_writer( m_board, &reporter );
+
     // Save the current plot options in the board
     m_parent->SetPlotSettings( m_plotOpts );
 
@@ -833,9 +850,9 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
         if( m_plotOpts.GetFormat() == PLOT_FORMAT_GERBER && m_useGerberExtensions->GetValue() )
             file_ext = GetGerberProtelExtension( layer );
 
-        BuildPlotFileName( &fn, outputDir.GetPath(),
-                           m_board->GetLayerName( layer ),
-                           file_ext );
+        BuildPlotFileName( &fn, outputDir.GetPath(), m_board->GetLayerName( layer ), file_ext );
+        wxString fullname = fn.GetFullName();
+        jobfile_writer.AddGbrFile( layer, fullname );
 
         LOCALE_IO toggle;
 
@@ -861,10 +878,14 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
         }
     }
 
-    // If no layer selected, we have nothing plotted.
-    // Prompt user if it happens because he could think there is a bug in Pcbnew.
-    if( !m_plotOpts.GetLayerSelection().any() )
-        DisplayError( this, _( "No layer selected" ) );
+    if( m_plotOpts.GetFormat() == PLOT_FORMAT_GERBER && m_plotOpts.GetCreateGerberJobFile() )
+    {
+        // Pick the basename from the board file
+        wxFileName fn( boardFilename );
+        // Build gerber job file from basename
+        BuildPlotFileName( &fn, outputDir.GetPath(), "job", GerberJobFileExtension );
+        jobfile_writer.CreateJobFile( fn.GetFullPath() );
+    }
 }
 
 #include <drc_stuff.h>
diff --git a/pcbnew/dialogs/dialog_plot_base.cpp b/pcbnew/dialogs/dialog_plot_base.cpp
index 75ff3946cf..b9c9d9a859 100644
--- a/pcbnew/dialogs/dialog_plot_base.cpp
+++ b/pcbnew/dialogs/dialog_plot_base.cpp
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jul  2 2017)
+// C++ code generated with wxFormBuilder (version May  6 2016)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -238,6 +238,11 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr
 	
 	bSizerGbrOpt->Add( m_useGerberNetAttributes, 0, wxALL, 2 );
 	
+	m_generateGerberJobFile = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Generate Gerber job file"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_generateGerberJobFile->SetToolTip( _("Generate a Gerber job file that contains info about the board,\nand the list of generated Gerber plot files") );
+	
+	bSizerGbrOpt->Add( m_generateGerberJobFile, 0, wxALL, 2 );
+	
 	m_subtractMaskFromSilk = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Subtract soldermask from silkscreen"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_subtractMaskFromSilk->SetToolTip( _("Remove silkscreen from areas without soldermask") );
 	
diff --git a/pcbnew/dialogs/dialog_plot_base.fbp b/pcbnew/dialogs/dialog_plot_base.fbp
index 95ef900d15..9360357f0f 100644
--- a/pcbnew/dialogs/dialog_plot_base.fbp
+++ b/pcbnew/dialogs/dialog_plot_base.fbp
@@ -2958,6 +2958,94 @@
                                                         <event name="OnUpdateUI"></event>
                                                     </object>
                                                 </object>
+                                                <object class="sizeritem" expanded="1">
+                                                    <property name="border">2</property>
+                                                    <property name="flag">wxALL</property>
+                                                    <property name="proportion">0</property>
+                                                    <object class="wxCheckBox" expanded="1">
+                                                        <property name="BottomDockable">1</property>
+                                                        <property name="LeftDockable">1</property>
+                                                        <property name="RightDockable">1</property>
+                                                        <property name="TopDockable">1</property>
+                                                        <property name="aui_layer"></property>
+                                                        <property name="aui_name"></property>
+                                                        <property name="aui_position"></property>
+                                                        <property name="aui_row"></property>
+                                                        <property name="best_size"></property>
+                                                        <property name="bg"></property>
+                                                        <property name="caption"></property>
+                                                        <property name="caption_visible">1</property>
+                                                        <property name="center_pane">0</property>
+                                                        <property name="checked">0</property>
+                                                        <property name="close_button">1</property>
+                                                        <property name="context_help"></property>
+                                                        <property name="context_menu">1</property>
+                                                        <property name="default_pane">0</property>
+                                                        <property name="dock">Dock</property>
+                                                        <property name="dock_fixed">0</property>
+                                                        <property name="docking">Left</property>
+                                                        <property name="enabled">1</property>
+                                                        <property name="fg"></property>
+                                                        <property name="floatable">1</property>
+                                                        <property name="font"></property>
+                                                        <property name="gripper">0</property>
+                                                        <property name="hidden">0</property>
+                                                        <property name="id">wxID_ANY</property>
+                                                        <property name="label">Generate Gerber job file</property>
+                                                        <property name="max_size"></property>
+                                                        <property name="maximize_button">0</property>
+                                                        <property name="maximum_size"></property>
+                                                        <property name="min_size"></property>
+                                                        <property name="minimize_button">0</property>
+                                                        <property name="minimum_size"></property>
+                                                        <property name="moveable">1</property>
+                                                        <property name="name">m_generateGerberJobFile</property>
+                                                        <property name="pane_border">1</property>
+                                                        <property name="pane_position"></property>
+                                                        <property name="pane_size"></property>
+                                                        <property name="permission">protected</property>
+                                                        <property name="pin_button">1</property>
+                                                        <property name="pos"></property>
+                                                        <property name="resize">Resizable</property>
+                                                        <property name="show">1</property>
+                                                        <property name="size"></property>
+                                                        <property name="style"></property>
+                                                        <property name="subclass"></property>
+                                                        <property name="toolbar_pane">0</property>
+                                                        <property name="tooltip">Generate a Gerber job file that contains info about the board,&#x0A;and the list of generated Gerber plot files</property>
+                                                        <property name="validator_data_type"></property>
+                                                        <property name="validator_style">wxFILTER_NONE</property>
+                                                        <property name="validator_type">wxDefaultValidator</property>
+                                                        <property name="validator_variable"></property>
+                                                        <property name="window_extra_style"></property>
+                                                        <property name="window_name"></property>
+                                                        <property name="window_style"></property>
+                                                        <event name="OnChar"></event>
+                                                        <event name="OnCheckBox"></event>
+                                                        <event name="OnEnterWindow"></event>
+                                                        <event name="OnEraseBackground"></event>
+                                                        <event name="OnKeyDown"></event>
+                                                        <event name="OnKeyUp"></event>
+                                                        <event name="OnKillFocus"></event>
+                                                        <event name="OnLeaveWindow"></event>
+                                                        <event name="OnLeftDClick"></event>
+                                                        <event name="OnLeftDown"></event>
+                                                        <event name="OnLeftUp"></event>
+                                                        <event name="OnMiddleDClick"></event>
+                                                        <event name="OnMiddleDown"></event>
+                                                        <event name="OnMiddleUp"></event>
+                                                        <event name="OnMotion"></event>
+                                                        <event name="OnMouseEvents"></event>
+                                                        <event name="OnMouseWheel"></event>
+                                                        <event name="OnPaint"></event>
+                                                        <event name="OnRightDClick"></event>
+                                                        <event name="OnRightDown"></event>
+                                                        <event name="OnRightUp"></event>
+                                                        <event name="OnSetFocus"></event>
+                                                        <event name="OnSize"></event>
+                                                        <event name="OnUpdateUI"></event>
+                                                    </object>
+                                                </object>
                                                 <object class="sizeritem" expanded="0">
                                                     <property name="border">2</property>
                                                     <property name="flag">wxALL</property>
diff --git a/pcbnew/dialogs/dialog_plot_base.h b/pcbnew/dialogs/dialog_plot_base.h
index d0d5043088..01aaeded78 100644
--- a/pcbnew/dialogs/dialog_plot_base.h
+++ b/pcbnew/dialogs/dialog_plot_base.h
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jul  2 2017)
+// C++ code generated with wxFormBuilder (version May  6 2016)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -94,6 +94,7 @@ class DIALOG_PLOT_BASE : public DIALOG_SHIM
 		wxCheckBox* m_useGerberExtensions;
 		wxCheckBox* m_useGerberX2Attributes;
 		wxCheckBox* m_useGerberNetAttributes;
+		wxCheckBox* m_generateGerberJobFile;
 		wxCheckBox* m_subtractMaskFromSilk;
 		wxRadioBox* m_rbGerberFormat;
 		wxStaticBoxSizer* m_HPGLOptionsSizer;
diff --git a/pcbnew/exporters/gerber_jobfile_writer.cpp b/pcbnew/exporters/gerber_jobfile_writer.cpp
new file mode 100644
index 0000000000..da132f4bb0
--- /dev/null
+++ b/pcbnew/exporters/gerber_jobfile_writer.cpp
@@ -0,0 +1,388 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 Jean_Pierre Charras <jp.charras at wanadoo.fr>
+ * Copyright (C) 1992-2017 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+/**
+ * @file gendrill_gerber_writer.cpp
+ * @brief Functions to create drill files in gerber X2 format.
+ */
+
+#include <fctsys.h>
+
+#include <vector>
+
+#include <plot_common.h>
+#include <wxPcbStruct.h>
+#include <build_version.h>
+
+#include <class_board.h>
+#include <class_zone.h>
+#include <class_module.h>
+
+#include <pcbplot.h>
+#include <pcbnew.h>
+#include <gerber_jobfile_writer.h>
+#include <wildcards_and_files_ext.h>
+#include <reporter.h>
+#include <plot_auxiliary_data.h>
+
+
+GERBER_JOBFILE_WRITER::GERBER_JOBFILE_WRITER( BOARD* aPcb, REPORTER* aReporter )
+{
+    m_pcb = aPcb;
+    m_reporter = aReporter;
+    m_conversionUnits = 1.0 / IU_PER_MM;    // Gerber units = mm
+}
+
+enum ONSIDE GERBER_JOBFILE_WRITER::hasSilkLayers()
+{
+    int flag = SIDE_NONE;
+
+    for( unsigned ii = 0; ii < m_params.m_LayerId.size(); ii++ )
+    {
+        if( m_params.m_LayerId[ii] == B_SilkS )
+            flag |= SIDE_BOTTOM;
+
+        if( m_params.m_LayerId[ii] == F_SilkS )
+            flag |= SIDE_TOP;
+    }
+
+    return (enum ONSIDE)flag;
+}
+
+
+enum ONSIDE GERBER_JOBFILE_WRITER::hasSolderMasks()
+{
+    int flag = SIDE_NONE;
+
+    for( unsigned ii = 0; ii < m_params.m_LayerId.size(); ii++ )
+    {
+        if( m_params.m_LayerId[ii] == B_Mask )
+            flag |= SIDE_BOTTOM;
+
+        if( m_params.m_LayerId[ii] == F_Mask )
+            flag |= SIDE_TOP;
+    }
+
+    return (enum ONSIDE)flag;
+}
+
+const char* GERBER_JOBFILE_WRITER::sideKeyValue( enum ONSIDE aValue )
+{
+    // return the key associated to sides used for some layers
+    // "No, TopOnly, BotOnly or Both"
+    const char* value = nullptr;
+
+    switch( aValue )
+    {
+        case SIDE_NONE:
+            value = "No"; break;
+
+        case SIDE_TOP:
+            value = "TopOnly"; break;
+
+        case SIDE_BOTTOM:
+            value = "BotOnly"; break;
+
+        case SIDE_BOTH:
+            value = "Both"; break;
+
+    }
+
+    return value;
+}
+
+
+extern void BuildGerberX2Header( const BOARD *aBoard, wxArrayString& aHeader );
+
+
+bool GERBER_JOBFILE_WRITER::CreateJobFile( const wxString& aFullFilename )
+{
+    // Note: in Gerber job file, dimensions are in mm, and are floating numbers
+    FILE* jobFile = wxFopen( aFullFilename, "wt" );
+
+    wxString msg;
+
+    if( jobFile == nullptr )
+    {
+        if( m_reporter )
+        {
+            msg.Printf( _( "Unable to create job file '%s'" ), aFullFilename );
+            m_reporter->Report( msg, REPORTER::RPT_ERROR );
+        }
+        return false;
+    }
+
+    LOCALE_IO dummy;
+
+    // output the job file header
+    bool hasInnerLayers = m_pcb->GetCopperLayerCount() > 2;
+    wxArrayString header;
+
+    fputs( "G04 Gerber job file with board parameters*\n"
+           "%TF.FileFunction,JobInfo*%\n"
+           "%TF.Part,SinglePCB*%\n", jobFile );
+    fputs( "G04 Single PCB fabrication instructions*\n", jobFile );
+
+    BuildGerberX2Header( m_pcb, header );
+
+    for( unsigned ii = 0; ii < header.GetCount(); ii++ )
+    {
+        if( header[ii].Contains( "TF.SameCoordinates" ) )
+            continue;   // This attribute is not useful in job file, skip it
+
+        fputs( header[ii], jobFile );
+        fputs( "\n", jobFile );
+    }
+
+
+    fputs( "%MOMM*%\n", jobFile );
+
+    fputs( "G04 Overall board parameters*\n", jobFile );
+    // output the bord size in mm:
+    EDA_RECT brect = m_pcb->GetBoardEdgesBoundingBox();
+    fprintf( jobFile, "%%TJ.B.Size.X,%.3f*%%\n", brect.GetWidth()*m_conversionUnits );
+    fprintf( jobFile, "%%TJ.B.Size.Y,%.3f*%%\n", brect.GetHeight()*m_conversionUnits );
+
+    // number of copper layers
+    fprintf( jobFile, "%%TJ.B.LayerNum,%d*%%\n", m_pcb->GetCopperLayerCount() );
+
+    // Board thickness
+    fprintf( jobFile, "%%TJ.B.Overall.Thickness,%.3f*%%\n",
+             m_pcb->GetDesignSettings().GetBoardThickness()*m_conversionUnits );
+
+    fprintf( jobFile, "%%TJ.B.Legend.Present,%s*%%\n", sideKeyValue( hasSilkLayers() ) );
+
+    fprintf( jobFile, "%%TJ.B.SolderMask.Present,%s*%%\n", sideKeyValue( hasSolderMasks() ) );
+
+    // Job file support a few design rules:
+    fputs( "G04 board design rules*\n", jobFile );
+    const BOARD_DESIGN_SETTINGS& dsnSettings = m_pcb->GetDesignSettings();
+    NETCLASS defaultNC = *dsnSettings.GetDefault();
+    int minclearanceOuter = defaultNC.GetClearance();
+
+    // Search a smaller clearance in other net classes, if any.
+    for( NETCLASSES::const_iterator it = dsnSettings.m_NetClasses.begin();
+         it != dsnSettings.m_NetClasses.end();
+         ++it )
+    {
+        NETCLASS netclass = *it->second;
+        minclearanceOuter = std::min( minclearanceOuter, netclass.GetClearance() );
+    }
+
+    // job file knows different clearance types.
+    // Kicad knows only one clearance for pads and tracks
+    // However, pads can have a specific clearance defined for a pad or a footprint,
+    // and min clearance can be dependent on layers.
+    // Search for a minimal pad clearance:
+    int minPadClearanceOuter = defaultNC.GetClearance();
+    int minPadClearanceInner = defaultNC.GetClearance();
+
+    for( MODULE* module : m_pcb->Modules() )
+    {
+        for( auto& pad : module->Pads() )
+        {
+            if( ( pad->GetLayerSet() & LSET::InternalCuMask() ).any() )
+               minPadClearanceInner = std::min( minPadClearanceInner, pad->GetClearance() );
+
+            if( ( pad->GetLayerSet() & LSET::ExternalCuMask() ).any() )
+               minPadClearanceOuter = std::min( minPadClearanceOuter, pad->GetClearance() );
+        }
+    }
+
+
+    fprintf( jobFile, "%%TJ.D.PadToPad.Outer,%.3f*%%\n", minPadClearanceOuter*m_conversionUnits );
+
+    if( hasInnerLayers )
+        fprintf( jobFile, "%%TJ.D.PadToPad.Inner,%.3f*%%\n", minPadClearanceInner*m_conversionUnits );
+
+    fprintf( jobFile, "%%TJ.D.PadToTrack.Outer,%.3f*%%\n", minPadClearanceOuter*m_conversionUnits );
+
+    if( hasInnerLayers )
+        fprintf( jobFile, "%%TJ.D.PadToTrack.Inner,%.3f*%%\n", minPadClearanceInner*m_conversionUnits );
+
+    // Until this is changed in Kicad, use the same value for internal tracks
+    int minclearanceInner = minclearanceOuter;
+
+    fprintf( jobFile, "%%TJ.D.TrackToTrack.Outer,%.3f*%%\n", minclearanceOuter*m_conversionUnits );
+
+    if( hasInnerLayers )
+        fprintf( jobFile, "%%TJ.D.TrackToTrack.Inner,%.3f*%%\n", minclearanceInner*m_conversionUnits );
+
+    // Output the minimal track width
+    int mintrackWidthOuter = INT_MAX;
+    int mintrackWidthInner = INT_MAX;
+
+    for( TRACK* track : m_pcb->Tracks() )
+    {
+        if( track->Type() == PCB_VIA_T )
+            continue;
+
+        if( track->GetLayer() == B_Cu || track->GetLayer() == F_Cu )
+            mintrackWidthOuter = std::min( mintrackWidthOuter, track->GetWidth() );
+        else
+            mintrackWidthInner = std::min( mintrackWidthInner, track->GetWidth() );
+    }
+
+    if( mintrackWidthOuter != INT_MAX )
+        fprintf( jobFile, "%%TJ.D.MinLineWidth.Outer,%.3f*%%\n", mintrackWidthOuter*m_conversionUnits );
+
+    if( mintrackWidthInner != INT_MAX )
+        fprintf( jobFile, "%%TJ.D.MinLineWidth.Inner,%.3f*%%\n", mintrackWidthInner*m_conversionUnits );
+
+    // Output the minimal zone to xx clearance
+    // Note: zones can have a zone clearance set to 0
+    // if happens, the actual zone clearance is the clearance of its class
+    minclearanceOuter = INT_MAX;
+    minclearanceInner = INT_MAX;
+
+    for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
+    {
+        ZONE_CONTAINER* zone = m_pcb->GetArea( ii );
+
+        if( zone->GetIsKeepout() || !zone->IsOnCopperLayer() )
+            continue;
+
+        int zclerance = zone->GetClearance();
+
+        if( zone->GetLayer() == B_Cu || zone->GetLayer() == F_Cu )
+            minclearanceOuter = std::min( minclearanceOuter, zclerance );
+        else
+            minclearanceInner = std::min( minclearanceInner, zclerance );
+    }
+
+    if( minclearanceOuter != INT_MAX )
+        fprintf( jobFile, "%%TJ.D.TrackToRegion.Outer,%.3f*%%\n", minclearanceOuter*m_conversionUnits );
+
+    if( hasInnerLayers && minclearanceInner != INT_MAX )
+        fprintf( jobFile, "%%TJ.D.TrackToRegion.Inner,%.3f*%%\n", minclearanceInner*m_conversionUnits );
+
+    if( minclearanceOuter != INT_MAX )
+        fprintf( jobFile, "%%TJ.D.RegionToRegion.Outer,%.3f*%%\n", minclearanceOuter*m_conversionUnits );
+
+    if( hasInnerLayers && minclearanceInner != INT_MAX )
+        fprintf( jobFile, "%%TJ.D.RegionToRegion.Inner,%.3f*%%\n", minclearanceInner*m_conversionUnits );
+
+    // output the gerber file list:
+    fputs( "G04 Layer Structure*\n", jobFile );
+
+    for( unsigned ii = 0; ii < m_params.m_GerberFileList.GetCount(); ii ++ )
+    {
+        wxString& name = m_params.m_GerberFileList[ii];
+        PCB_LAYER_ID layer = m_params.m_LayerId[ii];
+        wxString gbr_layer_id;
+        bool skip_file = false;     // true to skip files which should not be in job file
+        const char* polarity = "Positive";
+
+        if( layer <= B_Cu )
+        {
+            gbr_layer_id = "Copper,L";
+
+            if( layer == B_Cu )
+                gbr_layer_id << m_pcb->GetCopperLayerCount();
+            else
+                gbr_layer_id << layer+1;
+
+            gbr_layer_id << ",";
+
+            if( layer == B_Cu )
+                gbr_layer_id << "Bottom";
+            else if( layer == F_Cu )
+                gbr_layer_id << "Top";
+            else
+                gbr_layer_id << "Inner";
+        }
+
+        else
+        {
+            switch( layer )
+            {
+                case B_Adhes:
+                    gbr_layer_id = "Glue,Bottom"; break;
+                case F_Adhes:
+                    gbr_layer_id = "Glue,Top"; break;
+
+                case B_Paste:
+                    gbr_layer_id = "SolderPaste,Bottom"; break;
+                case F_Paste:
+                    gbr_layer_id = "SolderPaste,Top"; break;
+
+                case B_SilkS:
+                    gbr_layer_id = "Legend,Bottom"; break;
+                case F_SilkS:
+                    gbr_layer_id = "Legend,Top"; break;
+
+                case B_Mask:
+                    gbr_layer_id = "SolderMask,Bottom"; polarity = "Negative"; break;
+                case F_Mask:
+                    gbr_layer_id = "SolderMask,Top"; polarity = "Negative"; break;
+
+                case Edge_Cuts:
+                    gbr_layer_id = "Profile"; break;
+
+                case B_Fab:
+                    gbr_layer_id = "AssemblyDrawing,Bottom"; break;
+                case F_Fab:
+                    gbr_layer_id = "AssemblyDrawing,Top"; break;
+
+                case Dwgs_User:
+                case Cmts_User:
+                case Eco1_User:
+                case Eco2_User:
+                case Margin:
+                case B_CrtYd:
+                case F_CrtYd:
+                   skip_file = true; break;
+
+                default:
+                    skip_file = true;
+                    m_reporter->Report( "Unexpected layer id in job file",
+                                        REPORTER::RPT_ERROR );
+                    break;
+            }
+        }
+
+        if( !skip_file )
+        {
+            // name can contain non ASCII7 chars.
+            // Only ASCII7 chars are accepted in gerber files. others must be converted to
+            // a gerber hexa sequence.
+            std::string strname = formatStringToGerber( name );
+            fprintf( jobFile, "%%TJ.L.\"%s\",%s,%s*%%\n", TO_UTF8( gbr_layer_id ),
+                     polarity, strname.c_str() );
+        }
+    }
+
+    // Close job file
+    fputs( "M02*\n", jobFile );
+
+    fclose( jobFile );
+
+    if( m_reporter )
+    {
+        msg.Printf( _( "Create Gerber job file '%s'" ), aFullFilename );
+        m_reporter->Report( msg, REPORTER::RPT_ACTION );
+    }
+
+    return true;
+}
diff --git a/pcbnew/exporters/gerber_jobfile_writer.h b/pcbnew/exporters/gerber_jobfile_writer.h
new file mode 100644
index 0000000000..f5f24fa9fb
--- /dev/null
+++ b/pcbnew/exporters/gerber_jobfile_writer.h
@@ -0,0 +1,125 @@
+/**
+ * @file gerber_jobfile_writer.h
+ * @brief Classes used in drill files, map files and report files generation.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2017 Jean_Pierre Charras <jp.charras at wanadoo.fr>
+ * Copyright (C) 1992-2017 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef GERBER_JOBFILE_WRITER_H
+#define GERBER_JOBFILE_WRITER_H
+
+
+// A helper enum to handle sides of some layers (silk, mask)
+enum ONSIDE
+{
+    SIDE_NONE = 0,      // layers not present
+    SIDE_TOP = 1,       // top layer only
+    SIDE_BOTTOM = 2,    // bottom layer only
+    SIDE_BOTH = SIDE_TOP|SIDE_BOTTOM    // both layers
+};
+
+class BOARD;
+
+/**
+ * class JOBFILE_PARAMS store the list of parameters written in Gerber job file
+ * especialy list of .gbr filenames and the corresponding layer id belonging the job
+ */
+class JOBFILE_PARAMS
+{
+public:
+    wxArrayString m_GerberFileList;         // the list of gerber filenames (without path)
+    std::vector<PCB_LAYER_ID> m_LayerId;    // the list of corresponding layer id
+};
+
+
+/**
+ * GERBER_JOBFILE_WRITER is a class used to create Gerber job file
+ * a Gerber job file stores info to make a board:
+ * list of gerber files
+ * info about the board itsel:
+ *  size, number of copper layers
+ *  thickness of the board, copper and dielectric
+ *  and some other info (colors, finish type ...)
+ *
+ * note: dimensions are always in mm in Kicad job file (can be also in inches in a job file)
+ * and they are in floating point notation
+ */
+class GERBER_JOBFILE_WRITER
+{
+public:
+    GERBER_JOBFILE_WRITER( BOARD* aPcb, REPORTER* aReporter = nullptr );
+
+    virtual ~GERBER_JOBFILE_WRITER()
+    {
+    }
+
+    /**
+     * add a gerber file name and type in job file list
+     * @param aLayer is the PCB_LAYER_ID corresponding to the gerber file
+     * @param aFilename is the filename (without path) of the gerber file
+     */
+    void AddGbrFile( PCB_LAYER_ID aLayer, wxString& aFilename )
+    {
+        m_params.m_GerberFileList.Add( aFilename );
+        m_params.m_LayerId.push_back( aLayer );
+    }
+
+    /**
+     * Creates an Excellon drill file
+     * @param aFullFilename = the full filename
+     * @param aParams = true for a NPTH file, false for a PTH file
+     * @return true, or false if the file cannot be created
+     */
+    bool  CreateJobFile( const wxString& aFullFilename );
+
+private:
+    /** @return SIDE_NONE if no silk screen layer is in list
+     * SIDE_TOP if top silk screen layer is in list
+     * SIDE_BOTTOM if bottom silk screen layer is in list
+     * SIDE_BOTH if top and bottom silk screen layers are in list
+     */
+    enum ONSIDE hasSilkLayers();
+
+    /** @return SIDE_NONE if no soldermask layer is in list
+     * SIDE_TOP if top soldermask layer is in list
+     * SIDE_BOTTOM if bottom soldermask layer is in list
+     * SIDE_BOTH if top and bottom soldermask layers are in list
+     */
+    enum ONSIDE hasSolderMasks();
+
+    /** @return the key associated to sides used for some layers
+     * No TopOnly BotOnly Both
+     */
+    const char* sideKeyValue( enum ONSIDE aValue );
+
+
+private:
+    BOARD* m_pcb;               // The board
+    REPORTER* m_reporter;       // a reporter for messages (can be null)
+    JOBFILE_PARAMS m_params;    // the list of various prms and data to write in a job file
+    double m_conversionUnits;   // scaling factor to convert brd units to gerber units (mm)
+};
+
+#endif  //  #ifndef GERBER_JOBFILE_WRITER_H
diff --git a/pcbnew/pcb_plot_params.cpp b/pcbnew/pcb_plot_params.cpp
index 5ae43b2e18..2e153b3308 100644
--- a/pcbnew/pcb_plot_params.cpp
+++ b/pcbnew/pcb_plot_params.cpp
@@ -82,6 +82,7 @@ PCB_PLOT_PARAMS::PCB_PLOT_PARAMS()
     m_useGerberProtelExtensions  = false;
     m_useGerberAttributes        = false;
     m_includeGerberNetlistInfo   = false;
+    m_createGerberJobFile        = false;
     m_gerberPrecision            = gbrDefaultPrecision;
     m_excludeEdgeLayer           = true;
     m_lineWidth                  = g_DrawDefaultLineThickness;
@@ -146,14 +147,11 @@ void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
     aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberextensions ),
                        m_useGerberProtelExtensions ? trueStr : falseStr );
 
-    if( m_useGerberAttributes ) // save this option only if active,
-                                // to avoid incompatibility with older Pcbnew version
-    {
-        aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberattributes ), trueStr );
+    aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberattributes ), trueStr );
 
-        if( GetIncludeGerberNetlistInfo() )
-            aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberadvancedattributes ), trueStr );
-    }
+    aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberadvancedattributes ), trueStr );
+
+    aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_creategerberjobfile ), trueStr );
 
     if( m_gerberPrecision != gbrDefaultPrecision ) // save this option only if it is not the default value,
                                                    // to avoid incompatibility with older Pcbnew version
@@ -228,6 +226,8 @@ bool PCB_PLOT_PARAMS::IsSameAs( const PCB_PLOT_PARAMS &aPcbPlotParams, bool aCom
         return false;
     if( m_useGerberAttributes && m_includeGerberNetlistInfo != aPcbPlotParams.m_includeGerberNetlistInfo )
         return false;
+    if( m_createGerberJobFile != aPcbPlotParams.m_createGerberJobFile )
+        return false;
     if( m_gerberPrecision != aPcbPlotParams.m_gerberPrecision )
         return false;
     if( m_excludeEdgeLayer != aPcbPlotParams.m_excludeEdgeLayer )
@@ -392,6 +392,10 @@ void PCB_PLOT_PARAMS_PARSER::Parse( PCB_PLOT_PARAMS* aPcbPlotParams )
             aPcbPlotParams->m_includeGerberNetlistInfo = parseBool();
             break;
 
+        case T_creategerberjobfile:
+            aPcbPlotParams->m_createGerberJobFile = parseBool();
+            break;
+
         case T_gerberprecision:
             aPcbPlotParams->m_gerberPrecision =
                 parseInt( gbrDefaultPrecision-1, gbrDefaultPrecision);
diff --git a/pcbnew/pcb_plot_params.h b/pcbnew/pcb_plot_params.h
index 6d0e2fca12..cf3e6e082a 100644
--- a/pcbnew/pcb_plot_params.h
+++ b/pcbnew/pcb_plot_params.h
@@ -108,6 +108,9 @@ private:
     /// Include netlist info (only in Gerber X2 format) (chapter ? in revision ?)
     bool        m_includeGerberNetlistInfo;
 
+    /// generate the auxiliary "job file" in gerber format
+    bool        m_createGerberJobFile;
+
     /// precision of coordinates in Gerber files: accepted 5 or 6
     /// when units are in mm (6 or 7 in inches, but Pcbnew uses mm).
     /// 6 is the internal resolution of Pcbnew, but not alwys accepted by board maker
@@ -245,6 +248,9 @@ public:
     void        SetIncludeGerberNetlistInfo( bool aUse ) { m_includeGerberNetlistInfo = aUse; }
     bool        GetIncludeGerberNetlistInfo() const { return m_includeGerberNetlistInfo; }
 
+    void        SetCreateGerberJobFile( bool aCreate ) { m_createGerberJobFile = aCreate; }
+    bool        GetCreateGerberJobFile() const { return m_createGerberJobFile; }
+
     void        SetUseGerberProtelExtensions( bool aUse ) { m_useGerberProtelExtensions = aUse; }
     bool        GetUseGerberProtelExtensions() const { return m_useGerberProtelExtensions; }
 
diff --git a/pcbnew/pcbplot.cpp b/pcbnew/pcbplot.cpp
index 6ddcb50129..2fea89e650 100644
--- a/pcbnew/pcbplot.cpp
+++ b/pcbnew/pcbplot.cpp
@@ -270,6 +270,102 @@ static wxString& makeStringCompatX1( wxString& aText, bool aUseX1CompatibilityMo
 }
 
 
+void BuildGerberX2Header( const BOARD *aBoard, wxArrayString& aHeader )
+{
+    wxString text;
+
+    // Creates the TF,.GenerationSoftware. Format is:
+    // %TF,.GenerationSoftware,<vendor>,<application name>[,<application version>]*%
+    text.Printf( wxT( "%%TF.GenerationSoftware,KiCad,Pcbnew,%s*%%" ), GetBuildVersion() );
+    aHeader.Add( text );
+
+    // creates the TF.CreationDate ext:
+    // The attribute value must conform to the full version of the ISO 8601
+    // date and time format, including time and time zone. Note that this is
+    // the date the Gerber file was effectively created,
+    // not the time the project of PCB was started
+    wxDateTime date( wxDateTime::GetTimeNow() );
+    // Date format: see http://www.cplusplus.com/reference/ctime/strftime
+    wxString msg = date.Format( wxT( "%z" ) );  // Extract the time zone offset
+    // The time zone offset format is + (or -) mm or hhmm  (mm = number of minutes, hh = number of hours)
+    // we want +(or -) hh:mm
+    if( msg.Len() > 3 )
+        msg.insert( 3, ":", 1 ),
+    text.Printf( wxT( "%%TF.CreationDate,%s%s*%%" ), GetChars( date.FormatISOCombined() ), GetChars( msg ) );
+    aHeader.Add( text );
+
+    // Creates the TF,.ProjectId. Format is (from Gerber file format doc):
+    // %TF.ProjectId,<project id>,<project GUID>,<revision id>*%
+    // <project id> is the name of the project, restricted to basic ASCII symbols only,
+    // and comma not accepted
+    // All illegal chars will be replaced by underscore
+    // <project GUID> is a 32 hexadecimal digits string which is an unique id of a project.
+    // This is a random 128-bit number expressed in 32 hexadecimal digits.
+    // See en.wikipedia.org/wiki/GUID for more information
+    // However Kicad does not handle such a project GUID, so it is built from the board name
+    // Rem: <project id> accepts only ASCII 7 code (only basic ASCII codes are allowed in gerber files).
+    wxFileName fn = aBoard->GetFileName();
+    msg = fn.GetFullName();
+    wxString guid;
+
+    // Build a 32 digits GUID from the board name:
+    for( unsigned ii = 0; ii < msg.Len(); ii++ )
+    {
+        int cc1 = int( msg[ii] ) & 0x0F;
+        int cc2 = ( int( msg[ii] ) >> 4) & 0x0F;
+        guid << wxString::Format( wxT( "%X%X" ), cc2, cc1 );
+
+        if( guid.Len() >= 32 )
+            break;
+    }
+
+    // guid has 32 digits, so add missing digits
+    int cnt = 32 - guid.Len();
+
+    if( cnt > 0 )
+        guid.Append( '0', cnt );
+
+    // build the <project id> string: this is the board short filename (without ext)
+    // and all non ASCII chars and comma are replaced by '_'
+    msg = fn.GetName();
+    msg.Replace( wxT( "," ), wxT( "_" ) );
+
+    // build the <rec> string. All non ASCII chars and comma are replaced by '_'
+    wxString rev = ((BOARD*)aBoard)->GetTitleBlock().GetRevision();
+    rev.Replace( wxT( "," ), wxT( "_" ) );
+
+    if( rev.IsEmpty() )
+        rev = wxT( "rev?" );
+
+    text.Printf( wxT( "%%TF.ProjectId,%s,%s,%s*%%" ), msg.ToAscii(), GetChars( guid ), rev.ToAscii() );
+    aHeader.Add( text );
+
+    // Add the TF.SameCoordinates, that specify all gerber files uses the same
+    // origin and orientation, and the registration between files is OK.
+    // The parameter of TF.SameCoordinates is a string that is common
+    // to all files using the same registration and has no special meaning:
+    // this is just a key
+    // Because there is no mirroring/rotation in Kicad, only the plot offset origin
+    // can create incorrect registration.
+    // So we create a key from plot offset options.
+    // and therefore for a given board, all Gerber files having the same key have the same
+    // plot origin and use the same registration
+    //
+    // Currently the key is "Original" when using absolute Pcbnew coordinates,
+    // and te PY ans PY position od auxiliary axis, when using it.
+    // Please, if absolute Pcbnew coordinates, one day, are set by user, change the way
+    // the key is built to ensure file only using the *same* axis have the same key.
+    wxString registration_id = "Original";
+    wxPoint auxOrigin = aBoard->GetAuxOrigin();
+
+    if( aBoard->GetPlotOptions().GetUseAuxOrigin() && auxOrigin.x && auxOrigin.y )
+        registration_id.Printf( "PX%xPY%x", auxOrigin.x, auxOrigin.y );
+
+    text.Printf( "%%TF.SameCoordinates,%s*%%", registration_id.GetData() );
+    aHeader.Add( text );
+}
+
+
 void AddGerberX2Header( PLOTTER * aPlotter,
             const BOARD *aBoard, bool aUseX1CompatibilityMode )
 {