##// END OF EJS Templates
New GUI added (kivy framework), clean code, delete unused files
Juan C. Espinoza -
r1288:8eedfb38dc53
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,119 +1,121
1 ## CHANGELOG:
1 ## CHANGELOG:
2
2
3 ### 3.0
3 ### 3.0
4 * Python 3.x compatible
4 * Python 3.x & 2.X compatible
5 * New architecture with multiprocessing and IPC communication
5 * New architecture with multiprocessing support
6 * Add @MPDecorator for multiprocessing Units and Operations
6 * Add @MPDecorator for multiprocessing Operations (Plots, Writers and Publishers)
7 * Added new type of operation `external` for non-locking operations
7 * Added new type of operation `external` for non-locking operations
8 * New plotting architecture with buffering/throttle capabilities to speed up plots
8 * New plotting architecture with buffering/throttle capabilities to speed up plots
9 * Clean controller to optimize scripts (format & optype are no longer required)
10 * New GUI with dinamic load of Units and operations (use Kivy framework)
9
11
10 ### 2.3
12 ### 2.3
11 * Added support for Madrigal formats (reading/writing).
13 * Added support for Madrigal formats (reading/writing).
12 * Added support for reading BLTR parameters (*.sswma).
14 * Added support for reading BLTR parameters (*.sswma).
13 * Added support for reading Julia format (*.dat).
15 * Added support for reading Julia format (*.dat).
14 * Added high order function `MPProject` for multiprocessing scripts.
16 * Added high order function `MPProject` for multiprocessing scripts.
15 * Added two new Processing Units `PublishData` and `ReceiverData` for receiving and sending dataOut through multiple ways (tcp, ipc, inproc).
17 * Added two new Processing Units `PublishData` and `ReceiverData` for receiving and sending dataOut through multiple ways (tcp, ipc, inproc).
16 * Added a new graphics Processing Unit `PlotterReceiver`. It is decoupled from normal processing sequence with support for data generated by multiprocessing scripts.
18 * Added a new graphics Processing Unit `PlotterReceiver`. It is decoupled from normal processing sequence with support for data generated by multiprocessing scripts.
17 * Added support for sending realtime graphic to web server.
19 * Added support for sending realtime graphic to web server.
18 * GUI command `schain` is now `schainGUI`.
20 * GUI command `schain` is now `schainGUI`.
19 * Added a CLI tool named `schain`.
21 * Added a CLI tool named `schain`.
20 * Scripts templates can be now generated with `schain generate`.
22 * Scripts templates can be now generated with `schain generate`.
21 * Now it is possible to search Processing Units and Operations with `schain search [module]` to get the right name and its allowed parameters.
23 * Now it is possible to search Processing Units and Operations with `schain search [module]` to get the right name and its allowed parameters.
22 * `schain xml` to run xml scripts.
24 * `schain xml` to run xml scripts.
23 * Added suggestions when parameters are poorly written.
25 * Added suggestions when parameters are poorly written.
24 * `Controller.start()` now runs in a different process than the process calling it.
26 * `Controller.start()` now runs in a different process than the process calling it.
25 * Added `schainpy.utils.log` for log standarization.
27 * Added `schainpy.utils.log` for log standarization.
26 * Running script on online mode no longer ignores date and hour. Issue #1109.
28 * Running script on online mode no longer ignores date and hour. Issue #1109.
27 * Added support for receving voltage data directly from JARS (tcp, ipc).
29 * Added support for receving voltage data directly from JARS (tcp, ipc).
28 * Updated README for MAC OS GUI installation.
30 * Updated README for MAC OS GUI installation.
29 * Setup now installs numpy.
31 * Setup now installs numpy.
30
32
31 ### 2.2.6
33 ### 2.2.6
32 * Graphics generated by the GUI are now the same as generated by scripts. Issue #1074.
34 * Graphics generated by the GUI are now the same as generated by scripts. Issue #1074.
33 * Added support for C extensions.
35 * Added support for C extensions.
34 * Function `hildebrand_sehkon` optimized with a C wrapper.
36 * Function `hildebrand_sehkon` optimized with a C wrapper.
35 * Numpy version updated.
37 * Numpy version updated.
36 * Migration to GIT.
38 * Migration to GIT.
37
39
38 ### 2.2.5:
40 ### 2.2.5:
39 * splitProfiles and combineProfiles modules were added to VoltageProc and Signal Chain GUI.
41 * splitProfiles and combineProfiles modules were added to VoltageProc and Signal Chain GUI.
40 * nProfiles of USRP data (hdf5) is the number of profiles thera are in one second.
42 * nProfiles of USRP data (hdf5) is the number of profiles thera are in one second.
41 * jroPlotter works directly with data objects instead of dictionaries
43 * jroPlotter works directly with data objects instead of dictionaries
42 * script "schain" was added to Signal Chain installer
44 * script "schain" was added to Signal Chain installer
43
45
44 ### 2.2.4.1:
46 ### 2.2.4.1:
45 * jroIO_usrp.py is update to read Sandra's data
47 * jroIO_usrp.py is update to read Sandra's data
46 * decimation in Spectra and RTI plots is always enabled.
48 * decimation in Spectra and RTI plots is always enabled.
47 * time* window option added to GUI
49 * time* window option added to GUI
48
50
49 ### 2.2.4:
51 ### 2.2.4:
50 * jroproc_spectra_lags.py added to schainpy
52 * jroproc_spectra_lags.py added to schainpy
51 * Bug fixed in schainGUI: ProcUnit was created with the same id in some cases.
53 * Bug fixed in schainGUI: ProcUnit was created with the same id in some cases.
52 * Bug fixed in jroHeaderIO: Header size validation.
54 * Bug fixed in jroHeaderIO: Header size validation.
53
55
54 ### 2.2.3.1:
56 ### 2.2.3.1:
55 * Filtering block by time has been added.
57 * Filtering block by time has been added.
56 * Bug fixed plotting RTI, CoherenceMap and others using xmin and xmax parameters. The first day worked
58 * Bug fixed plotting RTI, CoherenceMap and others using xmin and xmax parameters. The first day worked
57 properly but the next days did not.
59 properly but the next days did not.
58
60
59 ### 2.2.3:
61 ### 2.2.3:
60 * Bug fixed in GUI: Error getting(reading) Code value
62 * Bug fixed in GUI: Error getting(reading) Code value
61 * Bug fixed in GUI: Flip option always needs channelList field
63 * Bug fixed in GUI: Flip option always needs channelList field
62 * Bug fixed in jrodata: when one branch modified a value in "dataOut" (example: dataOut.code) this value
64 * Bug fixed in jrodata: when one branch modified a value in "dataOut" (example: dataOut.code) this value
63 was modified for every branch (because this was a reference). It was modified in data.copy()
65 was modified for every branch (because this was a reference). It was modified in data.copy()
64 * Bug fixed in jroproc_voltage.profileSelector(): rangeList replaces to profileRangeList.
66 * Bug fixed in jroproc_voltage.profileSelector(): rangeList replaces to profileRangeList.
65
67
66 ### 2.2.2:
68 ### 2.2.2:
67 * VoltageProc: ProfileSelector, Reshape, Decoder with nTxs!=1 and getblock=True was tested
69 * VoltageProc: ProfileSelector, Reshape, Decoder with nTxs!=1 and getblock=True was tested
68 * Rawdata and testRawdata.py added to Signal Chain project
70 * Rawdata and testRawdata.py added to Signal Chain project
69
71
70 ### 2.2.1:
72 ### 2.2.1:
71 * Bugs fixed in GUI
73 * Bugs fixed in GUI
72 * Views were improved in GUI
74 * Views were improved in GUI
73 * Support to MST* ISR experiments
75 * Support to MST* ISR experiments
74 * Bug fixed getting noise using hyldebrant. (minimum number of points > 20%)
76 * Bug fixed getting noise using hyldebrant. (minimum number of points > 20%)
75 * handleError added to jroplotter.py
77 * handleError added to jroplotter.py
76
78
77 ### 2.2.0:
79 ### 2.2.0:
78 * GUI: use of external plotter
80 * GUI: use of external plotter
79 * Compatible with matplotlib 1.5.0
81 * Compatible with matplotlib 1.5.0
80
82
81 ### 2.1.5:
83 ### 2.1.5:
82 * serializer module added to Signal Chain
84 * serializer module added to Signal Chain
83 * jroplotter.py added to Signal Chain
85 * jroplotter.py added to Signal Chain
84
86
85 ### 2.1.4.2:
87 ### 2.1.4.2:
86 * A new Plotter Class was added
88 * A new Plotter Class was added
87 * Project.start() does not accept filename as a parameter anymore
89 * Project.start() does not accept filename as a parameter anymore
88
90
89 ### 2.1.4.1:
91 ### 2.1.4.1:
90 * Send notifications when an error different to ValueError is detected
92 * Send notifications when an error different to ValueError is detected
91
93
92 ### 2.1.4:
94 ### 2.1.4:
93 * Sending error notifications to signal chain administrator
95 * Sending error notifications to signal chain administrator
94 * Login to email server added
96 * Login to email server added
95
97
96 ### 2.1.3.3:
98 ### 2.1.3.3:
97 * Colored Button Icons were added to GUI
99 * Colored Button Icons were added to GUI
98
100
99 ### 2.1.3.2:
101 ### 2.1.3.2:
100 * GUI: user interaction enhanced
102 * GUI: user interaction enhanced
101 * controller_api.py: Safe access to ControllerThead
103 * controller_api.py: Safe access to ControllerThead
102
104
103 ### 2.1.3.1:
105 ### 2.1.3.1:
104 * GUI: every icon were resized
106 * GUI: every icon were resized
105 * jroproc_voltage.py: Print a message when "Read from code" option is selected and the code is not defined inside data file
107 * jroproc_voltage.py: Print a message when "Read from code" option is selected and the code is not defined inside data file
106
108
107 ### 2.1.3:
109 ### 2.1.3:
108 * jroplot_heispectra.py: SpectraHeisScope was not showing the right channels
110 * jroplot_heispectra.py: SpectraHeisScope was not showing the right channels
109 * jroproc_voltage.py: Bug fixed selecting profiles (self.nProfiles took a wrong value),
111 * jroproc_voltage.py: Bug fixed selecting profiles (self.nProfiles took a wrong value),
110 Bug fixed selecting heights by block (selecting profiles instead heights)
112 Bug fixed selecting heights by block (selecting profiles instead heights)
111 * jroproc_voltage.py: New feature added: decoding data by block using FFT.
113 * jroproc_voltage.py: New feature added: decoding data by block using FFT.
112 * jroIO_heispectra.py: Bug fixed in FitsReader. Using local Fits instance instead schainpy.mode.data.jrodata.Fits.
114 * jroIO_heispectra.py: Bug fixed in FitsReader. Using local Fits instance instead schainpy.mode.data.jrodata.Fits.
113 * jroIO_heispectra.py: Channel index list does not exist.
115 * jroIO_heispectra.py: Channel index list does not exist.
114
116
115 ### 2.1.2:
117 ### 2.1.2:
116 * jroutils_ftp.py: Bug fixed, Any error sending file stopped the Server Thread
118 * jroutils_ftp.py: Bug fixed, Any error sending file stopped the Server Thread
117 Server thread opens and closes remote server each time file list is sent
119 Server thread opens and closes remote server each time file list is sent
118 * jroplot_spectra.py: Noise path was not being created when noise data is saved.
120 * jroplot_spectra.py: Noise path was not being created when noise data is saved.
119 * jroIO_base.py: startTime can be greater than endTime. Example: SpreadF [18:00 * 07:00] No newline at end of file
121 * jroIO_base.py: startTime can be greater than endTime. Example: SpreadF [18:00 * 07:00]
@@ -1,1 +0,0
1 from viewcontroller import * No newline at end of file
@@ -1,39 +1,325
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 import os
2 import os
3 import sys
3 import sys
4 import ast
5
6 from schainpy.controller import Project
7 from schainpy.cli import cli
4 from schainpy.utils import log
8 from schainpy.utils import log
5
9
6 try:
10 try:
7 from PyQt4 import QtCore, QtGui
11 import kivy
8 from PyQt4.QtGui import QApplication
12 from kivy.app import App
13 from kivy.uix.label import Label
14 from kivy.uix.boxlayout import BoxLayout
15 from kivy.uix.gridlayout import GridLayout
16 from kivy.uix.textinput import TextInput
17 from kivy.uix.button import Button
18 from kivy.uix.dropdown import DropDown
19 from kivy.uix.togglebutton import ToggleButton
20 from kivy.uix.popup import Popup
21 from kivy.uix.filechooser import FileChooserListView
9 except:
22 except:
10 log.error(
23 log.error(
11 'You should install PyQt4 module in order to run the GUI. See the README.')
24 'You should install kivy module in order to run the GUI.')
12 sys.exit()
25 sys.exit()
13
26
14 from schainpy.gui.viewcontroller.initwindow import InitWindow
15 from schainpy.gui.viewcontroller.basicwindow import BasicWindow
16 from schainpy.gui.viewcontroller.workspace import Workspace
17
27
28 DEFAULTS = {
29 'path': os.path.expanduser('~'),
30 'startDate': '2018/01/01',
31 'endDate': '2020/01/01',
32 'startTime': '00:00:00',
33 'endTime': '23:59:59',
34 'online': '1',
35 'delay': '30',
36 'walk': '1',
37 'show': '1',
38 'zmin': '10',
39 'zmax': '40',
40 }
41
42
43 class MainLayout(BoxLayout):
44 def __init__(self, **kwargs):
45 super(MainLayout, self).__init__(**kwargs)
46
47 self.workspace = os.path.join(os.path.expanduser('~'), 'workspace/scripts')
48 self.current_unit_id = None
49 self._units = []
50 self.project = Project()
51 self.project.setup(id='1', name='test', description='')
52
53 self.sidebar_left = BoxLayout(orientation='vertical', size_hint_x=0.4, spacing=5)
54 self.body = BoxLayout(orientation='vertical', spacing=5)
55 self.sidebar_right = BoxLayout(orientation='vertical', size_hint_x=0.6, spacing=5)
56
57 bt_prj = Button(text='Project')
58 bt_prj.bind(on_press=self.show_project)
59 self.sidebar_left.add_widget(bt_prj)
60
61 bt_add_unit = Button(text='Add Unit')
62 bt_add_unit.bind(on_press=self.select_unit)
63 self.sidebar_left.add_widget(bt_add_unit)
64
65 bt_add_operation = Button(text='Add Operation')
66 bt_add_operation.bind(on_press=self.select_operation)
67 self.sidebar_left.add_widget(bt_add_operation)
68
69 bt_import = Button(text='Import')
70 bt_import.bind(on_press=self.load)
71 self.sidebar_left.add_widget(bt_import)
72
73 bt_export = Button(text='Export')
74 bt_export.bind(on_press=self.export)
75 self.sidebar_left.add_widget(bt_export)
76
77 bt_run = Button(text='Run')
78 bt_run.bind(on_press=self.run)
79 self.sidebar_left.add_widget(bt_run)
80
81 bt_stop = Button(text='Stop')
82 bt_stop.bind(on_press = self.stop)
83 self.sidebar_left.add_widget(bt_stop)
84
85 bt_exit = Button(text = 'Exit', height = 40, size_hint_y = None, background_color=(1, 0, 0, 1))
86 bt_exit.bind(on_press=App.get_running_app().stop)
87 self.sidebar_left.add_widget(bt_exit)
88
89 self.add_widget(self.sidebar_left)
90 self.add_widget(self.body)
91 self.add_widget(self.sidebar_right)
92
93 def update_body(self):
94
95 self._units = []
96 self.body.clear_widgets()
97 self.sidebar_right.clear_widgets()
98
99 for unit in self.project.getUnits():
100 box = GridLayout(cols=3)
101 bt = ToggleButton(text=unit.name, group='units')
102 bt._obj = unit
103 bt.bind(on_press=self.show_parameters)
104 box.add_widget(bt)
105 self._units.append(bt)
106
107 for operation in unit.operations:
108 bt_op = Button(text = operation.name, background_color=(1, 0.5, 0, 1))
109 bt_op._id = unit.id
110 bt_op._obj = operation
111 bt_op.bind(on_press=self.show_parameters)
112 box.add_widget(bt_op)
113
114 self.body.add_widget(box)
115
116 print(self.project)
117
118 def show_parameters(self, instance):
119
120 obj = instance._obj
121 self.current_unit_id = obj.id
122 self.sidebar_right.clear_widgets()
123
124 if obj and obj.parameters:
125 self._params = {}
126
127 for key, value in obj.getParameters().items():
128 self.sidebar_right.add_widget(Label(text=key))
129 text = TextInput(text=value, multiline=False)
130 self._params[key] = text
131 self.sidebar_right.add_widget(text)
132
133 bt_save = Button(text = 'Save', height = 40, size_hint_y = None, background_color=(0, 1, 0, 1))
134 bt_save._obj = obj
135 if hasattr(instance, '_id'):
136 bt_save._id = instance._id
137 self.current_unit_id = None
138 bt_save.bind(on_press=self.save_parameters)
139 self.sidebar_right.add_widget(bt_save)
140
141 bt_delete = Button(text = 'Delete', height = 40, size_hint_y = None, background_color=(1, 0, 0, 1))
142 bt_delete._obj = obj
143 if hasattr(instance, '_id'):
144 bt_delete._id = instance._id
145 self.current_unit_id = obj.id
146 bt_delete.bind(on_press=self.delete_object)
147 self.sidebar_right.add_widget(bt_delete)
148
149 def save_parameters(self, instance):
150
151 obj = instance._obj
152 params = {}
153 for key in self._params:
154 if self._params[key]:
155 params[key] = self._params[key].text
156
157 if hasattr(instance, '_id'):
158 unit = self.project.getProcUnit(instance._id)
159 op = unit.getOperation(obj.id)
160 op.update(**params)
161 else:
162 unit = self.project.getProcUnit(obj.id)
163 unit.update(**params)
164
165 def delete_object(self, instance):
166
167 obj = instance._obj
168
169 if hasattr(instance, '_id'):
170 unit = self.project.getProcUnit(instance._id)
171 unit.removeOperation(obj.id)
172 else:
173 self.project.removeProcUnit(obj.id)
174
175 self.project.updateId(self.project.id)
176 self.update_body()
177
178 def show_project(self, instance):
179
180 self.sidebar_right.clear_widgets()
181 self._params = {}
182 for label in ['Id', 'Name', 'Description']:
183 self.sidebar_right.add_widget(Label(text=label))
184 text = TextInput(text=getattr(self.project, label.lower()), multiline=False)
185 self._params[label] = text
186 self.sidebar_right.add_widget(text)
187
188 self.sidebar_right.add_widget(Label(text='Workspace'))
189 text = TextInput(text=getattr(self, 'workspace'), multiline=False)
190 self._params['Workspace'] = text
191 self.sidebar_right.add_widget(text)
192
193 bt_save = Button(text = 'Save', height = 40, size_hint_y = None, background_color=(0, 1, 0, 1))
194 bt_save.bind(on_press = self.save_project_parameters)
195 self.sidebar_right.add_widget(bt_save)
196
197 def save_project_parameters(self, instance):
198
199 for label in ['Id', 'Name', 'Description']:
200 setattr(self.project, label.lower(), self._params[label].text)
201
202 setattr(self, 'workspace', self._params['Workspace'].text)
203
204 def select_unit(self, instance):
205
206 self.sidebar_right.clear_widgets()
207 bt_main = Button(text = 'Select Unit', height = 40, size_hint_y = None)
208 dropdown = DropDown()
209
210 for unit in cli.getProcs():
211
212 btn = Button(text = unit, size_hint_y = None, height = 40)
213 btn.bind(on_release = lambda btn: dropdown.select(btn.text))
214 dropdown.add_widget(btn)
215
216 bt_main.bind(on_release = dropdown.open)
217 dropdown.bind(on_select = lambda instance, x: setattr(bt_main, 'text', x))
218
219 bt_add = Button(text = 'Add', height = 40, size_hint_y = None, background_color=(0, 1, 0, 1))
220 bt_add.bind(on_press = lambda instance: self.add_unit(bt_main.text))
221
222 self.sidebar_right.add_widget(bt_main)
223 self.sidebar_right.add_widget(bt_add)
224
225 def add_unit(self, s):
226
227 if s:
228 if 'Reader' in s:
229 unit = self.project.addReadUnit(name=s)
230 else:
231 *_, last = self.project.getUnits()
232 unit = self.project.addProcUnit(name=s, inputId=last.id)
233
234 keys = cli.getArgs(unit.name)
235 values = [DEFAULTS[key] if key in DEFAULTS else '' for key in keys]
236 unit.update(**dict(zip(keys, values)))
237 self.update_body()
238
239 def select_operation(self, instance):
240
241 self.sidebar_right.clear_widgets()
242 btns = [bt.state == 'down' for bt in self._units]
243 if True in btns:
244 bt_main = Button(text = 'Select Operation', height = 40, size_hint_y = None)
245 dropdown = DropDown()
246
247 for unit in cli.getOperations():
248
249 btn = Button(text = unit, size_hint_y = None, height = 40)
250 btn.bind(on_release = lambda btn: dropdown.select(btn.text))
251 dropdown.add_widget(btn)
252
253 bt_main.bind(on_release = dropdown.open)
254 dropdown.bind(on_select = lambda instance, x: setattr(bt_main, 'text', x))
255
256 bt_add = Button(text = 'Add', height = 40, size_hint_y = None, background_color=(0, 1, 0, 1))
257 bt_add.bind(on_press = lambda instance: self.add_operation(bt_main.text))
258
259 self.sidebar_right.add_widget(bt_main)
260 self.sidebar_right.add_widget(bt_add)
261 else:
262 self.sidebar_right.add_widget(Label(text='Select Unit'))
263
264 def add_operation(self, s):
265
266 if s:
267 unit = self.project.getProcUnit(self.current_unit_id)
268 op = unit.addOperation(name=s)
269 keys = cli.getArgs(op.name)
270 values = [DEFAULTS[key] if key in DEFAULTS else '' for key in keys]
271 op.update(**dict(zip(keys, values)))
272 self.update_body()
273
274 def run(self, instance):
275
276 if self.project and self.project.is_alive():
277 self.sidebar_right.clear_widgets()
278 self.sidebar_right.add_widget(Label(text='Project running'))
279 else:
280 if self.project.exitcode is None:
281 self.project.start()
282 else:
283 self.project = self.project.clone()
284 self.project.start()
285
286 def stop(self, instance):
287
288 if self.project and self.project.is_alive():
289 self.project.kill()
290 log.error('Project Stopped by user', 'GUI')
291 else:
292 self.sidebar_right.clear_widgets()
293 self.sidebar_right.add_widget(Label(text='Project not running'))
294
295 def load(self, instance):
296
297 self.sidebar_right.clear_widgets()
298 textinput = FileChooserListView(
299 path=self.workspace, size_hint=(1, 1), dirselect=False, filters=['*.xml'])
18
300
19 def main():
301 self.sidebar_right.add_widget(textinput)
302 bt_open = Button(text = 'Open', height = 40, size_hint_y = None, background_color=(0, 1, 0, 1))
303 bt_open.textinput = textinput
304 bt_open.bind(on_press = self.load_file)
305 self.sidebar_right.add_widget(bt_open)
306
307 def load_file(self, instance):
20
308
21 app = QtGui.QApplication(sys.argv)
309 self.project.readXml(instance.textinput.selection[0])
310 self.update_body()
22
311
23 Welcome = InitWindow()
312 def export(self, instance):
24
313
25 if not Welcome.exec_():
314 filename = os.path.join(self.workspace, '{}.xml'.format(self.project.name))
26 sys.exit(-1)
315 self.project.writeXml(filename)
316 log.success('File created: {}'.format(filename), 'GUI')
27
317
28 WorkPathspace = Workspace()
29 if not WorkPathspace.exec_():
30 sys.exit(-1)
31
318
32 MainGUI = BasicWindow()
319 class SignalChainApp(App):
33 MainGUI.setWorkSpaceGUI(WorkPathspace.dirComBox.currentText())
320 def build(self):
34 MainGUI.show()
321 return MainLayout(spacing=10)
35 sys.exit(app.exec_())
36
322
37
323
38 if __name__ == "__main__":
324 if __name__ == "__main__":
39 main()
325 SignalChainApp().run() No newline at end of file
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (1765 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (2179 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now