annotate test/editortest/REPEditor.java @ 420:5c95a9020e31

Modify ServerMainLoop
author one
date Fri, 13 Feb 2009 19:13:50 +0900
parents 7ff127c8ad64
children 49b689b17d06
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
417
267f9748e826 (no commit message)
one
parents:
diff changeset
1 package test.editortest;
267f9748e826 (no commit message)
one
parents:
diff changeset
2
267f9748e826 (no commit message)
one
parents:
diff changeset
3 import java.io.IOException;
267f9748e826 (no commit message)
one
parents:
diff changeset
4 import java.net.InetSocketAddress;
267f9748e826 (no commit message)
one
parents:
diff changeset
5 import java.nio.channels.SelectionKey;
267f9748e826 (no commit message)
one
parents:
diff changeset
6 import java.util.LinkedList;
267f9748e826 (no commit message)
one
parents:
diff changeset
7 import rep.REP;
267f9748e826 (no commit message)
one
parents:
diff changeset
8 import rep.REPCommand;
267f9748e826 (no commit message)
one
parents:
diff changeset
9 import rep.REPCommandPacker;
267f9748e826 (no commit message)
one
parents:
diff changeset
10 import rep.channel.REPSelectionKey;
267f9748e826 (no commit message)
one
parents:
diff changeset
11 import rep.channel.REPSelector;
267f9748e826 (no commit message)
one
parents:
diff changeset
12 import rep.channel.REPSocketChannel;
267f9748e826 (no commit message)
one
parents:
diff changeset
13
267f9748e826 (no commit message)
one
parents:
diff changeset
14
267f9748e826 (no commit message)
one
parents:
diff changeset
15 public class REPEditor extends Thread implements REPTextListener{
267f9748e826 (no commit message)
one
parents:
diff changeset
16
267f9748e826 (no commit message)
one
parents:
diff changeset
17 private REPSocketChannel<REPCommand> channel;
267f9748e826 (no commit message)
one
parents:
diff changeset
18 REPSelector<REPCommand> selector;
267f9748e826 (no commit message)
one
parents:
diff changeset
19 private boolean running = true;
267f9748e826 (no commit message)
one
parents:
diff changeset
20 private boolean inputLock = false;
267f9748e826 (no commit message)
one
parents:
diff changeset
21 private long timeout = 1;
267f9748e826 (no commit message)
one
parents:
diff changeset
22 private int syncCounter = 0;
267f9748e826 (no commit message)
one
parents:
diff changeset
23 private LinkedList<REPCommand> userCommand = new LinkedList<REPCommand>();
267f9748e826 (no commit message)
one
parents:
diff changeset
24 private LinkedList<Runnable> runners = new LinkedList<Runnable>();
267f9748e826 (no commit message)
one
parents:
diff changeset
25 private String name = "test";
267f9748e826 (no commit message)
one
parents:
diff changeset
26 private int seq;
267f9748e826 (no commit message)
one
parents:
diff changeset
27 private int eid;
267f9748e826 (no commit message)
one
parents:
diff changeset
28 private int sid;
267f9748e826 (no commit message)
one
parents:
diff changeset
29 private REPText repText;
419
7ff127c8ad64 (no commit message)
one
parents: 417
diff changeset
30 private boolean hasInputLock = false;
417
267f9748e826 (no commit message)
one
parents:
diff changeset
31 private boolean master;
267f9748e826 (no commit message)
one
parents:
diff changeset
32 private boolean syncEnable = true;
267f9748e826 (no commit message)
one
parents:
diff changeset
33 private LogTarget logTarget;
420
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
34 private int tempseq = -1;
417
267f9748e826 (no commit message)
one
parents:
diff changeset
35
267f9748e826 (no commit message)
one
parents:
diff changeset
36 public REPEditor(REPText repText, boolean master){
267f9748e826 (no commit message)
one
parents:
diff changeset
37 this.repText = repText;
267f9748e826 (no commit message)
one
parents:
diff changeset
38 this.master = master;
267f9748e826 (no commit message)
one
parents:
diff changeset
39 repText.addTextListener(this);
267f9748e826 (no commit message)
one
parents:
diff changeset
40 if(master){
267f9748e826 (no commit message)
one
parents:
diff changeset
41 userCommand.add(new REPCommand(REP.SMCMD_PUT,0,0,0,0,name +"-file"));
267f9748e826 (no commit message)
one
parents:
diff changeset
42 }else{
267f9748e826 (no commit message)
one
parents:
diff changeset
43 userCommand.add(new REPCommand(REP.SMCMD_JOIN, 0, 0, 0, 0, name));
267f9748e826 (no commit message)
one
parents:
diff changeset
44 }
267f9748e826 (no commit message)
one
parents:
diff changeset
45 }
267f9748e826 (no commit message)
one
parents:
diff changeset
46
267f9748e826 (no commit message)
one
parents:
diff changeset
47 public void textDeleted(REPTextEvent event) {
267f9748e826 (no commit message)
one
parents:
diff changeset
48 Logger.print(event.getText());
267f9748e826 (no commit message)
one
parents:
diff changeset
49 addUserInput(new REPCommand(REP.REPCMD_DELETE_USER, 0, 0, 0, event.getLineno(), event.getText()));
267f9748e826 (no commit message)
one
parents:
diff changeset
50 }
267f9748e826 (no commit message)
one
parents:
diff changeset
51
267f9748e826 (no commit message)
one
parents:
diff changeset
52 public void textInserted(REPTextEvent event) {
267f9748e826 (no commit message)
one
parents:
diff changeset
53 Logger.print(event.getText());
267f9748e826 (no commit message)
one
parents:
diff changeset
54 addUserInput(new REPCommand(REP.REPCMD_INSERT_USER, 0, 0, 0, event.getLineno(), event.getText()));
267f9748e826 (no commit message)
one
parents:
diff changeset
55 }
267f9748e826 (no commit message)
one
parents:
diff changeset
56
419
7ff127c8ad64 (no commit message)
one
parents: 417
diff changeset
57 public void addUserInput(final REPCommand command) {
417
267f9748e826 (no commit message)
one
parents:
diff changeset
58 Runnable runner = new Runnable(){
267f9748e826 (no commit message)
one
parents:
diff changeset
59 public void run(){
267f9748e826 (no commit message)
one
parents:
diff changeset
60 userCommand.add(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
61 timeout = 1;
267f9748e826 (no commit message)
one
parents:
diff changeset
62 }
267f9748e826 (no commit message)
one
parents:
diff changeset
63 };
267f9748e826 (no commit message)
one
parents:
diff changeset
64 synchronized(runners){
267f9748e826 (no commit message)
one
parents:
diff changeset
65 runners.add(runner);
267f9748e826 (no commit message)
one
parents:
diff changeset
66 }
267f9748e826 (no commit message)
one
parents:
diff changeset
67 if(selector != null){
267f9748e826 (no commit message)
one
parents:
diff changeset
68 selector.wakeup();
267f9748e826 (no commit message)
one
parents:
diff changeset
69 }
267f9748e826 (no commit message)
one
parents:
diff changeset
70 }
267f9748e826 (no commit message)
one
parents:
diff changeset
71
267f9748e826 (no commit message)
one
parents:
diff changeset
72 public void run(){
267f9748e826 (no commit message)
one
parents:
diff changeset
73 /*
267f9748e826 (no commit message)
one
parents:
diff changeset
74 * Create Socket and connect to the session manager
267f9748e826 (no commit message)
one
parents:
diff changeset
75 */
267f9748e826 (no commit message)
one
parents:
diff changeset
76 try {
267f9748e826 (no commit message)
one
parents:
diff changeset
77 channel = REPSocketChannel.<REPCommand>create(new REPCommandPacker());
267f9748e826 (no commit message)
one
parents:
diff changeset
78 } catch (IOException e) {
267f9748e826 (no commit message)
one
parents:
diff changeset
79 e.printStackTrace();
267f9748e826 (no commit message)
one
parents:
diff changeset
80 return;
267f9748e826 (no commit message)
one
parents:
diff changeset
81 }
267f9748e826 (no commit message)
one
parents:
diff changeset
82 try {
267f9748e826 (no commit message)
one
parents:
diff changeset
83 InetSocketAddress semaIP = new InetSocketAddress("localhost", 8766);
267f9748e826 (no commit message)
one
parents:
diff changeset
84 while (!channel.connect(semaIP)){
267f9748e826 (no commit message)
one
parents:
diff changeset
85 Logger.print("SeMa not listen to socket yet, wait");
267f9748e826 (no commit message)
one
parents:
diff changeset
86 }
267f9748e826 (no commit message)
one
parents:
diff changeset
87 } catch (IOException e) {
267f9748e826 (no commit message)
one
parents:
diff changeset
88 e.printStackTrace();
267f9748e826 (no commit message)
one
parents:
diff changeset
89 return;
267f9748e826 (no commit message)
one
parents:
diff changeset
90 }
267f9748e826 (no commit message)
one
parents:
diff changeset
91 /*
267f9748e826 (no commit message)
one
parents:
diff changeset
92 * Start editor main loop
267f9748e826 (no commit message)
one
parents:
diff changeset
93 * public REPCommand(REP cmd,int sid,int eid, int seq, int lineno, String string)
267f9748e826 (no commit message)
one
parents:
diff changeset
94 */
267f9748e826 (no commit message)
one
parents:
diff changeset
95 try {
267f9748e826 (no commit message)
one
parents:
diff changeset
96 mainloop();
267f9748e826 (no commit message)
one
parents:
diff changeset
97 } catch (IOException e) {
267f9748e826 (no commit message)
one
parents:
diff changeset
98 }
267f9748e826 (no commit message)
one
parents:
diff changeset
99 }
267f9748e826 (no commit message)
one
parents:
diff changeset
100
267f9748e826 (no commit message)
one
parents:
diff changeset
101 /*
267f9748e826 (no commit message)
one
parents:
diff changeset
102 * Editor main loop with input lock
267f9748e826 (no commit message)
one
parents:
diff changeset
103 */
267f9748e826 (no commit message)
one
parents:
diff changeset
104 private void mainloop() throws IOException {
267f9748e826 (no commit message)
one
parents:
diff changeset
105
267f9748e826 (no commit message)
one
parents:
diff changeset
106 channel.configureBlocking(false);
267f9748e826 (no commit message)
one
parents:
diff changeset
107 selector = REPSelector.create();
267f9748e826 (no commit message)
one
parents:
diff changeset
108 channel.register(selector, SelectionKey.OP_READ);
267f9748e826 (no commit message)
one
parents:
diff changeset
109 while(running) {
267f9748e826 (no commit message)
one
parents:
diff changeset
110
267f9748e826 (no commit message)
one
parents:
diff changeset
111 synchronized(runners){
267f9748e826 (no commit message)
one
parents:
diff changeset
112 for(Runnable runner : runners){
267f9748e826 (no commit message)
one
parents:
diff changeset
113 runner.run();
267f9748e826 (no commit message)
one
parents:
diff changeset
114 }
267f9748e826 (no commit message)
one
parents:
diff changeset
115 runners.clear();
267f9748e826 (no commit message)
one
parents:
diff changeset
116 }
267f9748e826 (no commit message)
one
parents:
diff changeset
117
267f9748e826 (no commit message)
one
parents:
diff changeset
118 if (inputLock) {
267f9748e826 (no commit message)
one
parents:
diff changeset
119 // No user input during merge mode (optional)
267f9748e826 (no commit message)
one
parents:
diff changeset
120 if (selector.select(0)>0) {
267f9748e826 (no commit message)
one
parents:
diff changeset
121 handle(channel.read());
267f9748e826 (no commit message)
one
parents:
diff changeset
122 }
267f9748e826 (no commit message)
one
parents:
diff changeset
123 continue;
267f9748e826 (no commit message)
one
parents:
diff changeset
124 } else if (selector.select(timeout)<=0) {
267f9748e826 (no commit message)
one
parents:
diff changeset
125 if (syncCounter>0) {
267f9748e826 (no commit message)
one
parents:
diff changeset
126 syncText(); // send the master editor buffer to clients.
267f9748e826 (no commit message)
one
parents:
diff changeset
127 }
267f9748e826 (no commit message)
one
parents:
diff changeset
128 userInput();
267f9748e826 (no commit message)
one
parents:
diff changeset
129 }
267f9748e826 (no commit message)
one
parents:
diff changeset
130 // selector(timeout) returns 0, but it may contain readable channel..
267f9748e826 (no commit message)
one
parents:
diff changeset
131 for(REPSelectionKey<REPCommand> key : selector.selectedKeys1()) {
267f9748e826 (no commit message)
one
parents:
diff changeset
132 REPSocketChannel<REPCommand> ch = key.channel1();
267f9748e826 (no commit message)
one
parents:
diff changeset
133 handle(ch.read());
267f9748e826 (no commit message)
one
parents:
diff changeset
134 }
267f9748e826 (no commit message)
one
parents:
diff changeset
135 }
267f9748e826 (no commit message)
one
parents:
diff changeset
136 }
267f9748e826 (no commit message)
one
parents:
diff changeset
137
267f9748e826 (no commit message)
one
parents:
diff changeset
138 private void handle(REPCommand command) {
267f9748e826 (no commit message)
one
parents:
diff changeset
139 Logger.print(logTarget, command);
420
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
140
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
141 //check seq
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
142 if(eid == 1){
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
143 if(command.eid == 3){
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
144 if(tempseq > command.seq){
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
145 System.err.println(command);
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
146 }
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
147 tempseq = command.seq;
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
148 }
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
149 }
5c95a9020e31 Modify ServerMainLoop
one
parents: 419
diff changeset
150
419
7ff127c8ad64 (no commit message)
one
parents: 417
diff changeset
151 // if(inputLock) Logger.print(logTarget, command);
417
267f9748e826 (no commit message)
one
parents:
diff changeset
152 if(command == null) return;
267f9748e826 (no commit message)
one
parents:
diff changeset
153 switch(command.cmd){
267f9748e826 (no commit message)
one
parents:
diff changeset
154 case REPCMD_DELETE:
267f9748e826 (no commit message)
one
parents:
diff changeset
155 if(command.eid != eid){
267f9748e826 (no commit message)
one
parents:
diff changeset
156 String del = repText.delete(command.lineno);
267f9748e826 (no commit message)
one
parents:
diff changeset
157 command.setString(del);
267f9748e826 (no commit message)
one
parents:
diff changeset
158 }
267f9748e826 (no commit message)
one
parents:
diff changeset
159 forward(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
160 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
161 case REPCMD_INSERT:
267f9748e826 (no commit message)
one
parents:
diff changeset
162 if(command.eid != eid){
267f9748e826 (no commit message)
one
parents:
diff changeset
163 repText.insert(command.lineno, command.string);
267f9748e826 (no commit message)
one
parents:
diff changeset
164 }
267f9748e826 (no commit message)
one
parents:
diff changeset
165 forward(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
166 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
167 case REPCMD_NOP:
267f9748e826 (no commit message)
one
parents:
diff changeset
168 case REPCMD_INSERT_ACK:
267f9748e826 (no commit message)
one
parents:
diff changeset
169 case REPCMD_DELETE_ACK:
267f9748e826 (no commit message)
one
parents:
diff changeset
170 forward(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
171 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
172 case SMCMD_PUT_ACK:
267f9748e826 (no commit message)
one
parents:
diff changeset
173 sid = command.sid;
267f9748e826 (no commit message)
one
parents:
diff changeset
174 eid = command.eid;
267f9748e826 (no commit message)
one
parents:
diff changeset
175 name += "(eid="+eid+",sid="+sid+")";
267f9748e826 (no commit message)
one
parents:
diff changeset
176 inputLock = false;
267f9748e826 (no commit message)
one
parents:
diff changeset
177 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
178 case SMCMD_JOIN_ACK :
267f9748e826 (no commit message)
one
parents:
diff changeset
179 sid = command.sid;
267f9748e826 (no commit message)
one
parents:
diff changeset
180 eid = command.eid;
267f9748e826 (no commit message)
one
parents:
diff changeset
181 name += "(eid="+eid+",sid="+sid+")";
267f9748e826 (no commit message)
one
parents:
diff changeset
182 inputLock = false;
267f9748e826 (no commit message)
one
parents:
diff changeset
183 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
184 case SMCMD_START_MERGE :
267f9748e826 (no commit message)
one
parents:
diff changeset
185 // lock user input during merge (optional)
267f9748e826 (no commit message)
one
parents:
diff changeset
186 inputLock = hasInputLock;
267f9748e826 (no commit message)
one
parents:
diff changeset
187 command.cmd = REP.SMCMD_START_MERGE_ACK;
267f9748e826 (no commit message)
one
parents:
diff changeset
188 send(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
189 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
190 case SMCMD_END_MERGE :
267f9748e826 (no commit message)
one
parents:
diff changeset
191 inputLock = false;
267f9748e826 (no commit message)
one
parents:
diff changeset
192 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
193 case SMCMD_SYNC:
267f9748e826 (no commit message)
one
parents:
diff changeset
194 // start contents sync with newly joined editor
267f9748e826 (no commit message)
one
parents:
diff changeset
195 command.cmd = REP.SMCMD_SYNC_ACK;
267f9748e826 (no commit message)
one
parents:
diff changeset
196 forward(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
197 //if (cmd.eid==eid) {
267f9748e826 (no commit message)
one
parents:
diff changeset
198 if (master && syncEnable ) {
267f9748e826 (no commit message)
one
parents:
diff changeset
199 syncCounter = 1;
267f9748e826 (no commit message)
one
parents:
diff changeset
200 timeout = 1;
267f9748e826 (no commit message)
one
parents:
diff changeset
201 }
267f9748e826 (no commit message)
one
parents:
diff changeset
202 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
203 }
267f9748e826 (no commit message)
one
parents:
diff changeset
204 }
267f9748e826 (no commit message)
one
parents:
diff changeset
205
267f9748e826 (no commit message)
one
parents:
diff changeset
206 private void userInput() {
267f9748e826 (no commit message)
one
parents:
diff changeset
207 Logger.print();
267f9748e826 (no commit message)
one
parents:
diff changeset
208 REPCommand command = userCommand.poll();
267f9748e826 (no commit message)
one
parents:
diff changeset
209 if(command != null){
267f9748e826 (no commit message)
one
parents:
diff changeset
210 switch(command.cmd){
267f9748e826 (no commit message)
one
parents:
diff changeset
211 case REPCMD_DELETE_USER:
267f9748e826 (no commit message)
one
parents:
diff changeset
212 send(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
213 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
214 case REPCMD_INSERT_USER:
267f9748e826 (no commit message)
one
parents:
diff changeset
215 send(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
216 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
217 case SMCMD_PUT:
267f9748e826 (no commit message)
one
parents:
diff changeset
218 case SMCMD_JOIN:
267f9748e826 (no commit message)
one
parents:
diff changeset
219 send(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
220 break;
267f9748e826 (no commit message)
one
parents:
diff changeset
221 }
267f9748e826 (no commit message)
one
parents:
diff changeset
222 }else{
267f9748e826 (no commit message)
one
parents:
diff changeset
223 if(syncCounter == 0){
267f9748e826 (no commit message)
one
parents:
diff changeset
224 timeout = 0;
267f9748e826 (no commit message)
one
parents:
diff changeset
225 }
267f9748e826 (no commit message)
one
parents:
diff changeset
226 }
267f9748e826 (no commit message)
one
parents:
diff changeset
227 }
267f9748e826 (no commit message)
one
parents:
diff changeset
228
267f9748e826 (no commit message)
one
parents:
diff changeset
229 private void forward(REPCommand command) {
267f9748e826 (no commit message)
one
parents:
diff changeset
230 REPCommand cmd = new REPCommand(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
231 channel.write(cmd);
267f9748e826 (no commit message)
one
parents:
diff changeset
232 }
267f9748e826 (no commit message)
one
parents:
diff changeset
233
267f9748e826 (no commit message)
one
parents:
diff changeset
234 private void send(REPCommand command) {
267f9748e826 (no commit message)
one
parents:
diff changeset
235 REPCommand cmd = new REPCommand(command);
267f9748e826 (no commit message)
one
parents:
diff changeset
236 cmd.setSEQID(seq++);
267f9748e826 (no commit message)
one
parents:
diff changeset
237 cmd.setEID(eid);
267f9748e826 (no commit message)
one
parents:
diff changeset
238 cmd.setSID(sid);
267f9748e826 (no commit message)
one
parents:
diff changeset
239 channel.write(cmd);
267f9748e826 (no commit message)
one
parents:
diff changeset
240 }
267f9748e826 (no commit message)
one
parents:
diff changeset
241
267f9748e826 (no commit message)
one
parents:
diff changeset
242 private void syncText() {
267f9748e826 (no commit message)
one
parents:
diff changeset
243 if(syncCounter>repText.size()){
267f9748e826 (no commit message)
one
parents:
diff changeset
244 syncCounter = 0;
267f9748e826 (no commit message)
one
parents:
diff changeset
245 }else {
267f9748e826 (no commit message)
one
parents:
diff changeset
246 if(inputLock) return;
267f9748e826 (no commit message)
one
parents:
diff changeset
247 int i = syncCounter - 1;
267f9748e826 (no commit message)
one
parents:
diff changeset
248 REPCommand del = new REPCommand(REP.REPCMD_DELETE_USER, sid, eid, 0, i, repText.get(i));
267f9748e826 (no commit message)
one
parents:
diff changeset
249 REPCommand ins = new REPCommand(REP.REPCMD_INSERT_USER, sid, eid, 0, i, repText.get(i));
267f9748e826 (no commit message)
one
parents:
diff changeset
250 send(del);
267f9748e826 (no commit message)
one
parents:
diff changeset
251 send(ins);
267f9748e826 (no commit message)
one
parents:
diff changeset
252 syncCounter++;
267f9748e826 (no commit message)
one
parents:
diff changeset
253 }
267f9748e826 (no commit message)
one
parents:
diff changeset
254 }
267f9748e826 (no commit message)
one
parents:
diff changeset
255
267f9748e826 (no commit message)
one
parents:
diff changeset
256 public void setLogTarget(LogTarget target){
267f9748e826 (no commit message)
one
parents:
diff changeset
257 logTarget = target;
267f9748e826 (no commit message)
one
parents:
diff changeset
258 }
267f9748e826 (no commit message)
one
parents:
diff changeset
259
419
7ff127c8ad64 (no commit message)
one
parents: 417
diff changeset
260 public REPText getREPText() {
7ff127c8ad64 (no commit message)
one
parents: 417
diff changeset
261 return repText;
7ff127c8ad64 (no commit message)
one
parents: 417
diff changeset
262 }
7ff127c8ad64 (no commit message)
one
parents: 417
diff changeset
263
417
267f9748e826 (no commit message)
one
parents:
diff changeset
264 }