[517] | 1 | <?php
|
---|
| 2 | // Vertically-balanced Tree Topology Generator
|
---|
| 3 | // Author: Miroslav Hajda hajdam@users.sf.net
|
---|
| 4 |
|
---|
| 5 | include('../global.php');
|
---|
| 6 | global $Database, $debug;
|
---|
| 7 |
|
---|
[873] | 8 | if (array_key_exists('debug', $_GET)) $debug = $_GET['debug'];
|
---|
[517] | 9 | else $debug = 0;
|
---|
| 10 | //$debug = 0;
|
---|
| 11 |
|
---|
| 12 | class TreeItem {
|
---|
| 13 | /** Index prvku v databazi */
|
---|
| 14 | var $index = 0;
|
---|
| 15 | /** Pozice prvku zleva */
|
---|
| 16 | var $pos = 0;
|
---|
| 17 | /** Pozice prvku zprava */
|
---|
| 18 | var $rpos = 0;
|
---|
| 19 | /** Pozice prvku shora */
|
---|
| 20 | var $level = 0;
|
---|
| 21 | /** Počet potomků s potomky */
|
---|
| 22 | var $forkcnt = 0;
|
---|
| 23 | /** Pole potomků */
|
---|
| 24 | var $children = array();
|
---|
| 25 | /** Předek */
|
---|
| 26 | var $parentItem;
|
---|
| 27 | /** Změna pořadí prvků */
|
---|
| 28 | var $order = array();
|
---|
| 29 |
|
---|
| 30 | function getFirst() {
|
---|
| 31 | if (count($this->children)>0) {
|
---|
| 32 | if (count($this->order)>0) {
|
---|
| 33 | if (count($this->children[0]->children)>0) return $this->order[$this->children[0]->index];
|
---|
| 34 | }
|
---|
| 35 | return $this->children[0];
|
---|
| 36 | } else return null;
|
---|
| 37 | }
|
---|
| 38 |
|
---|
| 39 | function getLast() {
|
---|
| 40 | if (count($this->children)>0) {
|
---|
| 41 | if (count($this->order)>0) {
|
---|
| 42 | if (count($this->children[count($this->children)-1]->children)>0) return $this->order[$this->children[count($this->children)-1]->index];
|
---|
| 43 | }
|
---|
| 44 | return $this->children[count($this->children)-1];
|
---|
| 45 | } else return null;
|
---|
| 46 | }
|
---|
| 47 | }
|
---|
| 48 |
|
---|
| 49 | class TreeGen {
|
---|
| 50 |
|
---|
| 51 | /** Kořenový uzel */
|
---|
| 52 | var $rootNode;
|
---|
| 53 | /** Hranice generátorů pozic */
|
---|
| 54 | var $border = array();
|
---|
| 55 | /** Maximální šířka hranice */
|
---|
| 56 | var $maxborder = 0;
|
---|
| 57 | /** Mód provedených operací */
|
---|
| 58 | var $mode = 0;
|
---|
| 59 |
|
---|
| 60 | /** Vytvoří stromovou strukturu načtením záznamů z databáze */
|
---|
| 61 | function populate() {
|
---|
| 62 | global $Database;
|
---|
| 63 | $TopHostName = 'nix-router';
|
---|
| 64 | // rodičovský uzel
|
---|
| 65 | $parentNode = null;
|
---|
| 66 | // Aktuální uzel
|
---|
| 67 | $currentNode = null;
|
---|
| 68 | // Aktuální úroveň
|
---|
| 69 | $level = 0;
|
---|
| 70 | $this->border[0]=0;
|
---|
| 71 | $mark = array();
|
---|
| 72 | $markskip = 0;
|
---|
| 73 |
|
---|
| 74 | do {
|
---|
| 75 | if ($level == 0) {
|
---|
| 76 | $query = 'SELECT dev.id AS id FROM NetworkDevice dev WHERE dev.name = "'.$TopHostName.'" LIMIT 0,1';
|
---|
| 77 | } else {
|
---|
| 78 | $query = 'SELECT trg.device AS id FROM NetworkDevice dev, NetworkInterface ifc, NetworkLink lnk, NetworkInterface trg WHERE ifc.device = dev.id AND lnk.interface2 = ifc.id AND lnk.interface1 = trg.id AND dev.used=1 AND ';
|
---|
| 79 | $query .= ' dev.id = '.$parentNode->index.' ORDER BY id';
|
---|
| 80 | $query .= ' LIMIT '.(count($parentNode->children)+$markskip).',1';
|
---|
| 81 | }
|
---|
| 82 | $DbResult = $Database->query($query);
|
---|
| 83 | $item = $DbResult->fetch_array();
|
---|
| 84 | if ($item) {
|
---|
| 85 | // echo $item['id'].','.$parentNode->index.','.$level.'<br/>';
|
---|
| 86 | // flush();
|
---|
| 87 | if (!isset($mark[$item['id']])) {
|
---|
| 88 | $mark[$item['id']] = 1;
|
---|
| 89 | $currentNode = new TreeItem();
|
---|
| 90 | $currentNode->index = $item['id'];
|
---|
| 91 | $currentNode->level = $level;
|
---|
| 92 | $currentNode->parentItem = $parentNode;
|
---|
| 93 | if ($level==0) {
|
---|
| 94 | $this->rootNode = $currentNode;
|
---|
| 95 | } else {
|
---|
| 96 | if ($level>1 && count($parentNode->children)==0) $parentNode->parentItem->forkcnt++;
|
---|
| 97 | array_push($parentNode->children,$currentNode);
|
---|
| 98 | }
|
---|
| 99 | $parentNode = $currentNode;
|
---|
| 100 | $level++;
|
---|
| 101 | $this->border[$level] = 0;
|
---|
| 102 | $markskip = 0;
|
---|
| 103 | } else {
|
---|
| 104 | $markskip++;
|
---|
| 105 | }
|
---|
| 106 | } else {
|
---|
| 107 | $currentNode = $parentNode;
|
---|
| 108 | $parentNode = $currentNode->parentItem;
|
---|
| 109 | $level--;
|
---|
| 110 | $markskip = 0;
|
---|
| 111 | }
|
---|
[873] | 112 | } while ($level >= 1);
|
---|
[517] | 113 | }
|
---|
| 114 |
|
---|
| 115 | function calc_pos($node) {
|
---|
| 116 | if ($this->mode > 1) {
|
---|
| 117 | return 1.5 + $this->maxborder-$node->rpos+$node->pos;
|
---|
| 118 | } else return $node->pos;
|
---|
| 119 | }
|
---|
| 120 |
|
---|
| 121 | /** Store specific tree node to DB */
|
---|
| 122 | function store_node($node) {
|
---|
| 123 | global $Database;
|
---|
| 124 | $first = $node->getFirst();
|
---|
| 125 | if ($first) { $first = $this->calc_pos($first); } else $first = '-1';
|
---|
| 126 | $last = $node->getLast();
|
---|
| 127 | if ($last) { $last = $this->calc_pos($last); } else $last = '-1';
|
---|
| 128 | $Database->query("INSERT INTO NetworkTopology (Host, Depth, Pos, First, Last) '.
|
---|
| 129 | 'VALUES (".$node->index.','.$node->level.','.$this->calc_pos($node).','.$first.','.$last.");");
|
---|
[873] | 130 | foreach ($node->children as $key => $value) {
|
---|
[517] | 131 | $this->store_node($value);
|
---|
| 132 | }
|
---|
| 133 | }
|
---|
| 134 |
|
---|
| 135 | /** Store all nodes of tree to DB */
|
---|
| 136 | function store() {
|
---|
| 137 | global $Database;
|
---|
| 138 | $Database->query('DELETE FROM NetworkTopology;');
|
---|
| 139 | $this->store_node($this->rootNode);
|
---|
| 140 | }
|
---|
| 141 |
|
---|
| 142 | /** Build most left tree on node and all subnodes on given border */
|
---|
| 143 | function left_align($node) {
|
---|
| 144 | $node->pos = $this->border[$node->level];
|
---|
| 145 | $this->border[$node->level]++;
|
---|
| 146 | if (count($node->children)>0) {
|
---|
| 147 | if ($this->border[$node->level +1]>=$this->border[$node->level]) {
|
---|
| 148 | $node->pos = $this->border[$node->level+1];
|
---|
| 149 | $this->setborder($node->level, $this->border[$node->level+1]+1);
|
---|
| 150 | }
|
---|
[873] | 151 | foreach ($node->children as $key => $value) {
|
---|
[517] | 152 | if ($key == count($node->children)-1) {
|
---|
[873] | 153 | if ($this->border[$node->level] > $this->border[$node->level+1]) $this->setborder($node->level+1, $this->border[$node->level]-1);
|
---|
[517] | 154 | }
|
---|
| 155 | $this->left_align($value);
|
---|
| 156 | if ($key == 0) {
|
---|
[873] | 157 | if ($this->border[$node->level] <= $this->border[$node->level+1]) {
|
---|
[517] | 158 | $node->pos = $this->border[$node->level+1]-1;
|
---|
| 159 | $this->setborder($node->level, $this->border[$node->level+1]);
|
---|
| 160 | }
|
---|
| 161 | }
|
---|
| 162 | }
|
---|
| 163 | }
|
---|
| 164 | }
|
---|
| 165 |
|
---|
| 166 | /** Build most right tree on node and all subnodes on given border */
|
---|
| 167 | function right_align($node) {
|
---|
| 168 | $this->mode = 2;
|
---|
| 169 | $node->rpos = $this->border[$node->level];
|
---|
| 170 | $this->border[$node->level]++;
|
---|
| 171 | if (count($node->children)>0) {
|
---|
| 172 | if ($this->border[$node->level +1]>=$this->border[$node->level]) {
|
---|
| 173 | $node->rpos = $this->border[$node->level+1];
|
---|
| 174 | $this->setborder($node->level, $this->border[$node->level+1]+1);
|
---|
| 175 | }
|
---|
[873] | 176 | for ($key=count($node->children)-1;$key>=0;$key--) {
|
---|
[517] | 177 | $value = $node->children[$key];
|
---|
| 178 | if ((count($value->children)>0) && count($node->order)>0) {
|
---|
| 179 | $value = $node->order[$value->index];
|
---|
| 180 | }
|
---|
| 181 | if ($key == 0) {
|
---|
[873] | 182 | if ($this->border[$node->level] > $this->border[$node->level+1]) $this->setborder($node->level+1, $this->border[$node->level]-1);
|
---|
[517] | 183 | }
|
---|
| 184 | $this->right_align($value);
|
---|
| 185 | if ($key == count($node->children)-1) {
|
---|
[873] | 186 | if ($this->border[$node->level] <= $this->border[$node->level+1]) {
|
---|
[517] | 187 | $node->rpos = $this->border[$node->level+1]-1;
|
---|
| 188 | $this->setborder($node->level, $this->border[$node->level+1]);
|
---|
| 189 | }
|
---|
| 190 | }
|
---|
| 191 | }
|
---|
| 192 | }
|
---|
| 193 | }
|
---|
| 194 |
|
---|
| 195 |
|
---|
| 196 | /** Reset construction border **/
|
---|
| 197 | function reset_border() {
|
---|
[873] | 198 | foreach ($this->border as $key => $value) $this->border[$key] = 0;
|
---|
[517] | 199 | $this->maxborder = 0;
|
---|
| 200 | }
|
---|
| 201 |
|
---|
| 202 | /** Heuristic reordering of fork nodes */
|
---|
| 203 | function reorder_heur($node) {
|
---|
| 204 | global $debug;
|
---|
| 205 | $node->pos = $this->border[$node->level];
|
---|
| 206 | $this->border[$node->level]++;
|
---|
| 207 | $order = array(); // Seznam změněných indexů
|
---|
| 208 | if ($node->forkcnt>1) {
|
---|
| 209 | $preborder = $this->border;
|
---|
| 210 | $premax = $this->maxborder;
|
---|
| 211 | $bestmax = 0; // Nejmenší rozměr
|
---|
| 212 | $bestfit = 0; // Index nejvhodnějšího kandidáta
|
---|
| 213 | $forkmap = array(); // Seznam indexů vydličkových potomků
|
---|
| 214 | $target = 0; // Index cílového uzlu
|
---|
| 215 | $lastindex = 0; // Index poslední vydličky
|
---|
[873] | 216 | foreach ($node->children as $key => $value) {
|
---|
[517] | 217 | if (count($value->children)>0) {
|
---|
| 218 | array_push($forkmap,$value);
|
---|
| 219 | $order[$value->index]=0;
|
---|
| 220 | $lastindex = $value->index;
|
---|
| 221 | }
|
---|
| 222 | }
|
---|
[873] | 223 | for ($i=0;$i<$node->forkcnt-1;$i++) {
|
---|
| 224 | for ($j=0;$j<count($forkmap);$j++) {
|
---|
[517] | 225 | $this->border = $preborder;
|
---|
| 226 | $this->maxborder = $premax;
|
---|
| 227 | $k = 0; // index zpracovávané vydličky
|
---|
[873] | 228 | foreach ($node->children as $key => $value) {
|
---|
[517] | 229 | if (count($value->children)>0) {
|
---|
| 230 | if ($order[$value->index]) {
|
---|
| 231 | $value = $order[$value->index];
|
---|
| 232 | } else {
|
---|
| 233 | if ($k > 0) {
|
---|
| 234 | if ($k < $j) { $value = $forkmap[$k-1]; } else $value = $forkmap[$k];
|
---|
| 235 | } else {
|
---|
| 236 | $target = $value->index;
|
---|
| 237 | $value = $forkmap[$j];
|
---|
| 238 | }
|
---|
| 239 | $k++;
|
---|
| 240 | }
|
---|
| 241 | }
|
---|
| 242 | if ($key == count($node->children)-1) {
|
---|
[873] | 243 | if ($this->border[$node->level] > $this->border[$node->level+1]) $this->setborder($node->level+1, $this->border[$node->level]-1);
|
---|
[517] | 244 | }
|
---|
| 245 | $this->left_align($value);
|
---|
| 246 | if ($key == 0) {
|
---|
[873] | 247 | if ($this->border[$node->level] <= $this->border[$node->level+1]) {
|
---|
[517] | 248 | $node->pos = $this->border[$node->level+1]-1;
|
---|
| 249 | $this->setborder($node->level, $this->border[$node->level+1]);
|
---|
| 250 | }
|
---|
| 251 | }
|
---|
| 252 | }
|
---|
| 253 | if (($j==0) || ($this->maxborder < $bestmax)) {
|
---|
| 254 | $bestmax = $this->maxborder;
|
---|
| 255 | $bestfit = $j;
|
---|
| 256 | }
|
---|
| 257 | }
|
---|
| 258 | $order[$target]=$forkmap[$bestfit];
|
---|
| 259 | if ($debug) echo 'ORDER: '.$target.' > '.$forkmap[$bestfit]->index."\n";
|
---|
| 260 | array_splice($forkmap, $bestfit, 1);
|
---|
| 261 | }
|
---|
| 262 | $order[$lastindex]=$forkmap[0];
|
---|
| 263 | if ($debug) echo 'ORDER: '.$lastindex.' > '.$forkmap[0]->index."\n";
|
---|
| 264 | if ($debug) echo 'ORDERSTORE: '.$node->index."\n";
|
---|
| 265 | $node->order = $order;
|
---|
| 266 | $this->border = $preborder;
|
---|
| 267 | $this->maxborder = $premax;
|
---|
| 268 | }
|
---|
| 269 | if (count($node->children)>0) {
|
---|
| 270 | if ($this->border[$node->level +1]>=$this->border[$node->level]) {
|
---|
| 271 | $node->pos = $this->border[$node->level+1];
|
---|
| 272 | $this->setborder($node->level, $this->border[$node->level+1]+1);
|
---|
| 273 | }
|
---|
[873] | 274 | foreach ($node->children as $key => $value) {
|
---|
[517] | 275 | if ((count($value->children)>0) && count($order)>0) {
|
---|
| 276 | $value = $order[$value->index];
|
---|
| 277 | }
|
---|
| 278 | if ($key == count($node->children)-1) {
|
---|
[873] | 279 | if ($this->border[$node->level] > $this->border[$node->level+1]) $this->setborder($node->level+1, $this->border[$node->level]-1);
|
---|
[517] | 280 | }
|
---|
| 281 | $this->reorder($value);
|
---|
| 282 | if ($key == 0) {
|
---|
[873] | 283 | if ($this->border[$node->level] <= $this->border[$node->level+1]) {
|
---|
[517] | 284 | $node->pos = $this->border[$node->level+1]-1;
|
---|
| 285 | $this->setborder($node->level, $this->border[$node->level+1]);
|
---|
| 286 | }
|
---|
| 287 | }
|
---|
| 288 | }
|
---|
| 289 | }
|
---|
| 290 | }
|
---|
| 291 |
|
---|
| 292 | /** Build most left tree on node and all subnodes on given border without leafs */
|
---|
| 293 | function left_stub($node) {
|
---|
| 294 | $node->pos = $this->border[$node->level];
|
---|
| 295 | $this->border[$node->level]++;
|
---|
| 296 | if (count($node->children)>0) {
|
---|
| 297 | $stubborder = $this->border[$node->level +1] + count($node->children);
|
---|
| 298 | if ($this->border[$node->level +1]>=$this->border[$node->level]) {
|
---|
| 299 | $node->pos = $this->border[$node->level+1];
|
---|
| 300 | $this->setborder($node->level, $this->border[$node->level+1]+1);
|
---|
| 301 | }
|
---|
| 302 | $forkcnt = 0; // Fork counter
|
---|
[873] | 303 | foreach ($node->children as $key => $value) {
|
---|
[517] | 304 | if ($forkcnt == count($node->children)-1) {
|
---|
[873] | 305 | if ($this->border[$node->level] > $this->border[$node->level+1]) $this->setborder($node->level+1, $this->border[$node->level]-1);
|
---|
[517] | 306 | }
|
---|
| 307 | if (count($value->children)>0) {
|
---|
| 308 | $this->left_stub($value);
|
---|
| 309 | if ($forkcnt == 0) {
|
---|
[873] | 310 | if ($this->border[$node->level] <= $this->border[$node->level+1]) {
|
---|
[517] | 311 | $node->pos = $this->border[$node->level+1]-1;
|
---|
| 312 | $this->setborder($node->level, $this->border[$node->level+1]);
|
---|
| 313 | }
|
---|
| 314 | }
|
---|
| 315 | $forkcnt++;
|
---|
| 316 | }
|
---|
| 317 | }
|
---|
| 318 | if ($stubborder > $this->border[$node->level +1]) $this->setborder($node->level+1,$stubborder);
|
---|
| 319 | }
|
---|
| 320 | }
|
---|
| 321 |
|
---|
| 322 | /** Full single level reordering */
|
---|
| 323 | function reorder($node) {
|
---|
| 324 | global $debug;
|
---|
| 325 | $node->pos = $this->border[$node->level];
|
---|
| 326 | $this->border[$node->level]++;
|
---|
| 327 | $order = array(); // Seznam změněných indexů
|
---|
| 328 | if ($node->forkcnt>1) {
|
---|
| 329 | $preborder = $this->border;
|
---|
| 330 | $premax = $this->maxborder;
|
---|
| 331 | $bestmax = 0; // Nejmenší rozměr
|
---|
| 332 | $bestfit = 0; // Index nejvhodnějšího kandidáta
|
---|
| 333 | $forkmap = array(); // Seznam indexů vydličkových potomků
|
---|
| 334 | $target = 0; // Index cílového uzlu
|
---|
| 335 | $lastindex = 0; // Index poslední vydličky
|
---|
| 336 | $fact = 1; // Faktoriál kombinací vydliček
|
---|
[873] | 337 | foreach ($node->children as $key => $value) {
|
---|
[517] | 338 | if (count($value->children)>0) {
|
---|
| 339 | if ($key>0) $fact = $fact * ($key+1);
|
---|
| 340 | array_push($forkmap,$value);
|
---|
| 341 | $order[$value->index]=0;
|
---|
| 342 | $lastindex = $value->index;
|
---|
| 343 | }
|
---|
| 344 | }
|
---|
[873] | 345 | for ($i=0;$i<$node->forkcnt-1;$i++) {
|
---|
| 346 | for ($j=0;$j<count($forkmap);$j++) {
|
---|
[517] | 347 | $this->border = $preborder;
|
---|
| 348 | $this->maxborder = $premax;
|
---|
| 349 | $k = 0; // index zpracovávané vydličky
|
---|
[873] | 350 | foreach ($node->children as $key => $value) {
|
---|
[517] | 351 | if (count($value->children)>0) {
|
---|
| 352 | if ($order[$value->index]) {
|
---|
| 353 | $value = $order[$value->index];
|
---|
| 354 | } else {
|
---|
| 355 | if ($k > 0) {
|
---|
| 356 | if ($k < $j) { $value = $forkmap[$k-1]; } else $value = $forkmap[$k];
|
---|
| 357 | } else {
|
---|
| 358 | $target = $value->index;
|
---|
| 359 | $value = $forkmap[$j];
|
---|
| 360 | }
|
---|
| 361 | $k++;
|
---|
| 362 | }
|
---|
| 363 | }
|
---|
| 364 | if ($key == count($node->children)-1) {
|
---|
[873] | 365 | if ($this->border[$node->level] > $this->border[$node->level+1]) $this->setborder($node->level+1, $this->border[$node->level]-1);
|
---|
[517] | 366 | }
|
---|
| 367 | $this->left_align($value);
|
---|
| 368 | if ($key == 0) {
|
---|
[873] | 369 | if ($this->border[$node->level] <= $this->border[$node->level+1]) {
|
---|
[517] | 370 | $node->pos = $this->border[$node->level+1]-1;
|
---|
| 371 | $this->setborder($node->level, $this->border[$node->level+1]);
|
---|
| 372 | }
|
---|
| 373 | }
|
---|
| 374 | }
|
---|
| 375 | if (($j==0) || ($this->maxborder < $bestmax)) {
|
---|
| 376 | $bestmax = $this->maxborder;
|
---|
| 377 | $bestfit = $j;
|
---|
| 378 | }
|
---|
| 379 | }
|
---|
| 380 | $order[$target]=$forkmap[$bestfit];
|
---|
| 381 | if ($debug) echo 'ORDER: '.$target.' > '.$forkmap[$bestfit]->index."\n";
|
---|
| 382 | array_splice($forkmap, $bestfit, 1);
|
---|
| 383 | }
|
---|
| 384 | $order[$lastindex]=$forkmap[0];
|
---|
| 385 | if ($debug) echo 'ORDER: '.$lastindex.' > '.$forkmap[0]->index."\n";
|
---|
| 386 | if ($debug) echo 'ORDERSTORE: '.$node->index."\n";
|
---|
| 387 | $node->order = $order;
|
---|
| 388 | $this->border = $preborder;
|
---|
| 389 | $this->maxborder = $premax;
|
---|
| 390 | }
|
---|
| 391 | // Missing stub stuffing
|
---|
| 392 | if (count($node->children)>0) {
|
---|
| 393 | if ($this->border[$node->level +1]>=$this->border[$node->level]) {
|
---|
| 394 | $node->pos = $this->border[$node->level+1];
|
---|
| 395 | $this->setborder($node->level, $this->border[$node->level+1]+1);
|
---|
| 396 | }
|
---|
[873] | 397 | foreach ($node->children as $key => $value) {
|
---|
[517] | 398 | if ((count($value->children)>0) && count($order)>0) {
|
---|
| 399 | $value = $order[$value->index];
|
---|
| 400 | }
|
---|
| 401 | if ($key == count($node->children)-1) {
|
---|
[873] | 402 | if ($this->border[$node->level] > $this->border[$node->level+1]) $this->setborder($node->level+1, $this->border[$node->level]-1);
|
---|
[517] | 403 | }
|
---|
| 404 | $this->reorder($value);
|
---|
| 405 | if ($key == 0) {
|
---|
[873] | 406 | if ($this->border[$node->level] <= $this->border[$node->level+1]) {
|
---|
[517] | 407 | $node->pos = $this->border[$node->level+1]-1;
|
---|
| 408 | $this->setborder($node->level, $this->border[$node->level+1]);
|
---|
| 409 | }
|
---|
| 410 | }
|
---|
| 411 | }
|
---|
| 412 | }
|
---|
| 413 | }
|
---|
| 414 |
|
---|
| 415 | function setborder($level, $value) {
|
---|
| 416 | if ($value > $this->maxborder) $this->maxborder = $value;
|
---|
| 417 | $this->border[$level] = $value;
|
---|
| 418 | }
|
---|
| 419 | }
|
---|
| 420 |
|
---|
| 421 | // Generator Main Procedure
|
---|
| 422 | $mytree = new TreeGen();
|
---|
| 423 | $mytree->populate();
|
---|
| 424 | $mytree->left_align($mytree->rootNode);
|
---|
| 425 | //$mytree->reorder($mytree->rootNode);
|
---|
| 426 | //$mytree->left_stub($mytree->rootNode);
|
---|
| 427 | $mytree->reset_border();
|
---|
| 428 | $mytree->right_align($mytree->rootNode);
|
---|
| 429 | $mytree->store();
|
---|
| 430 |
|
---|
[548] | 431 | echo('Topologie byla vygenerovana.');
|
---|