diff options
author | cyuamber <xuranyjy@chinamobile.com> | 2019-09-26 16:53:28 +0800 |
---|---|---|
committer | xu ran <xuranyjy@chinamobile.com> | 2019-09-27 00:45:40 +0000 |
commit | 2fd289f8e4e211eb26752d04d8d9b394ab78470f (patch) | |
tree | 8d987aace682431d2818aaa301cc338a9f6b015a /usecaseui-portal/src/app/shared/components/e2e-creation | |
parent | 2b307fe51a873c200c22469327e6947095516288 (diff) |
feat:adjust the file schema of components related to service instances
Change-Id: I18f1674601536a59313528bb1e01fd6b4fffd4fd
Issue-ID: USECASEUI-307
Signed-off-by: cyuamber <xuranyjy@chinamobile.com>
Diffstat (limited to 'usecaseui-portal/src/app/shared/components/e2e-creation')
5 files changed, 0 insertions, 759 deletions
diff --git a/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.css b/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.css deleted file mode 100644 index 5dce6c92..00000000 --- a/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.css +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2019 CMCC, Inc. and others. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -.title { - font: 700 18px/18px "思源黑体"; - color: #4c5e70; - margin-bottom: 18px; -} -hr { - border: none; - height: 2px; - background-color: #dce1e7; - margin-bottom: 10px; -} -.model { - background-color: #fff; - height: 90%; - overflow-y: auto; -} -.model .back { - position: absolute; - top: 10px; - right: 20px; -} -.model .creation { - position: relative; - width: 60%; - height: 100%; - overflow-y: auto; - border-radius: 5px; - padding: 20px; -} -.model .creation .baseparms h3 { - color: #3fa8eb; - font: 700 16px "Arial"; -} -.model .creation .baseparms h4 { - font: 700 16px "Arial"; -} -.model .creation .baseparms ul li { - margin: 3px 0; -} -.model .creation .baseparms ul li span { - display: inline-block; - width: 40%; - font: 700 14px "Arial"; - vertical-align: middle; - overflow: hidden; - text-overflow: ellipsis; - text-align: right; -} -.model .creation .baseparms ul li input { - width: 165px; -} -.model .creation .submit { - position: absolute; - top: 10px; - right: 20px; -} -.model .chart { - width: 40%; - padding: 10px; - height: 100%; - border-left: 10px solid #f3f3f3; -} diff --git a/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.html b/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.html deleted file mode 100644 index da673bf0..00000000 --- a/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.html +++ /dev/null @@ -1,139 +0,0 @@ -<!-- - Copyright (C) 2019 CMCC, Inc. and others. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<!--<h3 class="title"> Services List </h3>--> -<div class="model creation-model"> - <!-- Create data --> - <div class="top-title"> - <h3 class="title fl">{{createParams.commonParams.templateType}} {{"i18nTextDefine_InstanceCreation" | translate}} </h3> - <div class="fl" style="width: 20%"> - <button class="submit" nz-button (click)="submit()"> - <span> {{"i18nTextDefine_Create" | translate}} </span> - </button> - <button class="back" nz-button (click)="goback()"></button> - </div> - </div> - <div class="e2ecreate-content"> - <div class="creation fl"> - <div *ngIf="createParams.commonParams.templateType=='E2E Service'" class="baseparms clearfix"> - <div class="vnf-box"> - <h3> {{"i18nTextDefine_Base" | translate}} </h3> - <ul class="clearfix"> - <li> - <span>Name:</span> - <input nz-input [(ngModel)]="service.name"> - </li> - <li> - <span>Description:</span> - <input nz-input [(ngModel)]="service.description"> - </li> - <li> - <span>COS:</span> - <input nz-input [(ngModel)]="service.COS"> - </li> - <li> - <span>EBS:</span> - <input nz-input [(ngModel)]="service.EBS"> - </li> - </ul> - </div> - <div class="vnf-box" *ngIf="templateParameters.inputs.length>0"> - <h3>{{"i18nTextDefine_templateInputs" | translate}}</h3> - <ul> - <li *ngFor="let parameter of templateParameters.inputs; let i = index;"> - <span *ngIf="parameter.type !== 'vf_location' && parameter.type !== 'sdn_controller'" title="{{parameter.name}}">{{parameter.name}}:</span> - <input *ngIf="parameter.type !== 'vf_location' && parameter.type !== 'sdn_controller'" nz-input [(ngModel)]="parameter.value"> - - <h5 *ngIf="parameter.type === 'vf_location'" style="padding-left:10px;">id: {{parameter.name}} - </h5> - <span *ngIf="parameter.type === 'vf_location'"> vf_location: </span> - <nz-select *ngIf="parameter.type === 'vf_location'" [(ngModel)]="parameter.value" nzAllowClear> - <nz-option *ngFor="let vim of vimInfos" [nzValue]="vim" [nzLabel]="vim.name"></nz-option> - </nz-select> - </li> - </ul> - </div> - <div class="vnf-box" *ngFor="let template of templateParameters.nestedTemplates;"> - <h3>{{template.name}}</h3> - <ul> - <li *ngFor="let input of template.inputs; let i = index;"> - <span *ngIf="input.type !== 'vf_location' && input.type !== 'sdn_controller'" title="{{input.name}}"> {{input.name}}: </span> - <input *ngIf="input.type !== 'vf_location' && input.type !== 'sdn_controller'" nz-input [(ngModel)]="input.value"> - - <h5 *ngIf="input.type === 'vf_location'" style="padding-left:10px;">id: {{input.name}}</h5> - <span *ngIf="input.type === 'vf_location'"> vf_location: </span> - <nz-select *ngIf="input.type === 'vf_location'" [(ngModel)]="input.value" nzAllowClear> - <nz-option *ngFor="let vim of vimInfos" [nzValue]="vim" [nzLabel]="vim.name"></nz-option> - </nz-select> - </li> - </ul> - </div> - </div> - - <div *ngIf="createParams.commonParams.templateType=='Network Service'" class="baseparms clearfix"> - <div class="vnf-box"> - <h3> {{"i18nTextDefine_Base" | translate}} </h3> - <ul class="clearfix"> - <li> - <span>Name:</span> - <input nz-input [(ngModel)]="ns_service.nsName"> - </li> - <li> - <span>Description:</span> - <input nz-input [(ngModel)]="ns_service.description"> - </li> - </ul> - </div> - <div class="vnf-box" *ngIf="nsTemplateParameters.inputs2.length>0"> - <h4>{{"i18nTextDefine_templateInputs" | translate}}</h4> - <ul> - <li *ngFor="let parameter of nsTemplateParameters.inputs2; let i = index;"> - <span *ngIf="parameter.type !== 'vf_location' && parameter.type !== 'sdn_controller'" title="{{parameter.name}}">{{parameter.name}}:</span> - <input *ngIf="parameter.type !== 'vf_location' && parameter.type !== 'sdn_controller'" nz-input [(ngModel)]="parameter.value"> - - <h5 *ngIf="parameter.type === 'vf_location'" style="padding-left:10px;">id: {{parameter.name}} - </h5> - <span *ngIf="parameter.type === 'vf_location'"> vf_location: </span> - <nz-select *ngIf="parameter.type === 'vf_location'" [(ngModel)]="parameter.value" nzAllowClear> - <nz-option *ngFor="let vim of vimInfos" [nzValue]="vim" [nzLabel]="vim.name"></nz-option> - </nz-select> - </li> - </ul> - </div> - <div class="vnf-box"> - <h4 *ngIf="nsTemplateParameters.vnfs.length>0">vnfs Inputs</h4> - <ul> - <li *ngFor="let vnf of nsTemplateParameters.vnfs;"> - <h5 style="padding-left:10px;">id: {{vnf.vnf_id}}</h5> - <span> vf_location: </span> - <nz-select [(ngModel)]="vnf.value" nzAllowClear> - <nz-option *ngFor="let vim of vimInfos" [nzValue]="vim" [nzLabel]="vim.name"></nz-option> - </nz-select> - </li> - </ul> - </div> - </div> - </div> - <div class="dividing-line fl"></div> - <!-- chart --> - <div class="chart fr"> - <div id="createChart"> - <svg width="100%" height="100%"> - </svg> - </div> - </div> - </div> - -</div>
\ No newline at end of file diff --git a/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.less b/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.less deleted file mode 100644 index 2964dad9..00000000 --- a/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.less +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright (C) 2019 CMCC, Inc. and others. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -.title { - font: 700 18px/18px "思源黑体"; - color: #4c5e70; - margin-bottom: 18px; -} -hr { - border: none; - height: 2px; - background-color: #dce1e7; - margin-bottom: 10px; -} -.model { - background-color: #F7F8FC; - height: 100%; - overflow-y: auto; - position: relative; - .top-title{ - width: 100%; - padding: 20px; - position: relative; - display: inline-block; - } - .submit{ - position: absolute; - width:84px; - height: 35px; - top: 10px; - right: 85px; - color: #fff; - font-size: 18px; - background:linear-gradient(90deg,rgba(99,194,246,1) 0%,rgba(62,155,255,1) 100%) !important; - border-radius:4px; - border: none!important; - border-color:rgba(0,0,0,0)!important; - } - .submit:hover{ - background:linear-gradient(90deg, rgb(103, 207, 246) 0%, rgb(69, 175, 255) 100%) !important; - border: none; - } - .back,.back:hover{ - position: absolute; - top: 10px; - right: 20px; - display: inline-block; - width: 35px; - height: 35px; - background:url("../../../../assets/images/Return-icon.png") no-repeat!important; - background-size: 100%!important; - border-radius:4px; - color: #D7D7D7; - cursor: pointer; - } - .back:hover{ - background: url("../../../../assets/images/Return-icon-active.png")!important; - background-size: 100%!important; - } - .top-title h3.title { - height: 35px; - width: 80%; - font-size:16px; - font-family:ArialMT; - color:#3C4F8C; - line-height:35px; - display: inline-block; - } - .e2ecreate-content{ - position: relative; - width: 98%; - height: 100%; - margin-left: 30px; - box-shadow:0px 10px 15px 2px rgba(222,222,222,0.5); - background: #fff; - border-radius:2px; - } - .creation{ - position: relative; - width: 58%; - height: 100%; - overflow-y: auto; - padding: 20px; - background: #fff; - .baseparms { - h3,h4{ - color: #06A7E2; - width: 96%; - height: 40px; - line-height: 35px; - font-size: 18px; - font-weight: 500; - margin: 10px auto; - border-bottom: 2px solid; - border-image: -webkit-linear-gradient(#07A9E1,#30D9C4) 100 100; - border-image: -moz-linear-gradient(#07A9E1,#30D9C4) 100 100; - border-image: linear-gradient(#07A9E1,#30D9C4) 100 100; - border-radius:2px; - } - h4 { - font: 700 16px "Arial"; - margin-left: 25px; - } - .vnf-box{ - clear: both; - } - ul{ - margin-left: 30px; - } - ul li { - margin: 10px 0; - width: 42%; - margin-right: 5%; - float: left; - text-align: left; - span { - display: inline-block; - width: 30%; - min-width: 80px; - font: 700 14px "Arial"; - overflow: hidden; - text-align: left; - word-break: break-all; - vertical-align: top; - } - input,nz-select{ - width: 49%; - margin-left:3% - } - } - } - } - .dividing-line{ - width: 0; - height: 85%; - margin: 4% 0; - border-left: 1px #cccccc dashed; - } - .chart { - width: 38%; - padding: 10px; - height: 95%; - margin: 0 auto; - #createChart{ - height: 100%; - width: 100%; - } - } -} diff --git a/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.spec.ts b/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.spec.ts deleted file mode 100644 index de00c43f..00000000 --- a/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { E2eCreationComponent } from './e2e-creation.component'; - -describe('E2eCreationComponent', () => { - let component: E2eCreationComponent; - let fixture: ComponentFixture<E2eCreationComponent>; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ E2eCreationComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(E2eCreationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.ts b/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.ts deleted file mode 100644 index accc6dbb..00000000 --- a/usecaseui-portal/src/app/shared/components/e2e-creation/e2e-creation.component.ts +++ /dev/null @@ -1,357 +0,0 @@ -/* - Copyright (C) 2019 CMCC, Inc. and others. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; -import { ServiceListService } from '../../../core/services/serviceList.service'; -import * as d3 from 'd3'; - -@Component({ - selector: 'app-e2e-creation', - templateUrl: './e2e-creation.component.html', - styleUrls: ['./e2e-creation.component.less'] -}) -export class E2eCreationComponent implements OnInit { - - constructor(private myhttp: ServiceListService) { } - - ngOnInit() { - this.gete2eTemParameters(this.e2e_ns_temParametersContent); - this.getVimInfo(); - this.getSdnControllers(); - console.log(this.createParams); - } - - @Output() e2eCloseCreate = new EventEmitter(); - @Output() nsCloseCreate = new EventEmitter(); - @Input() createParams; - @Input() e2e_ns_temParametersContent; - - - // e2e serviceTemplateParameters - templateParameters = { - invariantUUID: "", - uuid: "", - name: "", - type: "", - version: "", - description: "", - category: "", - subcategory: "", - customizationUuid: "", - inputs: [], - nestedTemplates: [] - }; - // ns serviceTemplateParameters - nsTemplateParameters = { - inputs: {}, - inputs2: [], - vnfs: [] - } - roote2e = { - "name": "e2e", - "type": "e2e", - "children": [] - }; - - rootns = { - "name": "ns", - "type": "ns", - "children": [] - }; - - imgmap = { - '1': '../../../../assets/images/create-e2e.png', - '2': '../../../../assets/images/create-ns.png', - '3': '../../../../assets/images/create-vnf.png', - }; - gete2eTemParameters(data) { //Get template parameters - let type = this.createParams.commonParams.templateType == "E2E Service" ? "e2e" : "ns"; - console.log(this.createParams); - console.log(data); - if (type == "e2e") { - this.templateParameters = data; - this.templateParameters.nestedTemplates.forEach((item) => { - item.inputs = item.inputs.filter((input) => { return input.type !== "sdn_controller" }); - }) - this.templateParameters.nestedTemplates.map((item, index) => { - let nsIndex = { - "name": "ns", - "type": "ns", - "children": [] - }; - nsIndex.children = item.nestedTemplates.map((item, index) => { - return { - "name": "vnf", - "type": "vnf", - } - }); - this.roote2e.children.push(nsIndex); - }); - console.log(this.templateParameters); - console.log(this.roote2e) - } else if (type == "ns") { - if (data["model"] != undefined && typeof data["model"] == 'string') { - this.nsTemplateParameters = JSON.parse(data["model"]); - console.log(data["model"]); - } else { - this.nsTemplateParameters = data; - } - console.log(this.nsTemplateParameters); - this.nsTemplateParameters["inputs2"] = []; - let inputs = this.nsTemplateParameters.inputs; - for (let key in inputs) { - this.nsTemplateParameters["inputs2"].push({ name: key, type: inputs[key].type, value: inputs[key].value }) - } - this.rootns.children = this.nsTemplateParameters.vnfs.map((item, index) => { - return { - "name": "vnf", - "type": "vnf", - } - }); - console.log(this.nsTemplateParameters); - } - - this.drawImage(type) - - } - vimInfos = []; - getVimInfo() { - this.myhttp.getVimInfo() - .subscribe((data) => { - this.vimInfos = data.map((item) => { return { name: item['cloud-owner'], id: item['cloud-region-id'] } }); - }) - }; - sdnControllers = []; - getSdnControllers() { - this.myhttp.getSdnControllers() - .subscribe((data) => { - this.sdnControllers = data.map((item) => { return { name: item['thirdparty-sdnc-id'], id: item['thirdparty-sdnc-id'] } }); - }) - } - - // e2e requstbody - service = { - name: "", - description: "", - COS: "", - EBS: "", - serviceInvariantUuid: "", - serviceUuid: "", // uuid ?? - globalSubscriberId: "", // "customer.id", - serviceType: "", // "serviceType.value", - parameters: { - locationConstraints: [ - - ], - resources: [], - requestInputs: {}, - } - - } - - // ns requstbody - ns_service = { - csarId: "", - nsName: "", - description: "", - context: { - globalCustomerId: "", - serviceType: "" - } - } - ns_service2 = { - locationConstraints: [ - - ], - additionalParamForNs: { - } - } - submit() { - let type = this.createParams.commonParams.templateType == "E2E Service" ? "e2e" : "ns"; - if (type == "e2e") { - this.service.serviceInvariantUuid = this.templateParameters.invariantUUID; - this.service.serviceUuid = this.templateParameters.uuid; - this.service.globalSubscriberId = this.createParams.commonParams.customer.id; - this.service.serviceType = this.createParams.commonParams.serviceType.name; - - this.templateParameters.inputs.forEach((ipnut) => { - this.service.parameters.requestInputs[ipnut.name] = ipnut.value == undefined ? ipnut.defaultValue : ipnut.value; - }) - - this.templateParameters.nestedTemplates.forEach((item) => { - let nsService = { - resourceName: item.name, - resourceInvariantUuid: item.invariantUUID, - resourceUuid: item.uuid, - resourceCustomizationUuid: item.customizationUuid, - parameters: { - locationConstraints: [], - resources: [], - requestInputs: {} - } - } - item.inputs.forEach((input) => { - if (input.type == "vf_location") { - let location = { - vnfProfileId: input.name, - locationConstraints: { - cloudOwner: input.value.name, - cloudRegionId: input.value.id - } - } - nsService.parameters.locationConstraints.push(location); - } else { - nsService.parameters.requestInputs[input.name] = input.value == undefined ? input.defaultValue : input.value; - } - }) - this.service.parameters.resources.push(nsService); - }) - console.log(this.service) - this.service.parameters.requestInputs['orchestrator'] = this.createParams.orchestrator.name; - if (this.createParams.isSol005Interface) { - this.service.parameters.requestInputs['isSol005Interface'] = this.createParams.isSol005Interface; - } - this.e2eCloseCreate.emit({ service: this.service }); - - } else if (type == "ns") { - //create ns instance - this.ns_service.csarId = this.createParams.template.id; - this.ns_service.context.globalCustomerId = this.createParams.commonParams.customer.id; - this.ns_service.context.serviceType = this.createParams.commonParams.serviceType.name; - - this.nsTemplateParameters.inputs2.forEach((input) => { - this.ns_service2.additionalParamForNs[input.name] = input.value == undefined ? input.defaultValue : input.value; - }) - this.nsTemplateParameters.vnfs.forEach((vnf) => { - let vnfparams = { - vnfProfileId: vnf.properties.id, - locationConstraints: { - cloudOwner: vnf.value.name, - cloudRegionId: vnf.value.id - } - } - this.ns_service2.locationConstraints.push(vnfparams); - }) - console.log(this.ns_service2); - - let requstbody = { - step1: this.ns_service, - step2: this.ns_service2 - } - this.nsCloseCreate.emit(requstbody); - } - - } - goback() { - this.e2eCloseCreate.emit(); - } - - - - drawImage(type) { - if (type == "e2e") { - this.render(this.roote2e, this.imgmap) - } else if (type == "ns") { - this.render(this.rootns, this.imgmap) - } - - - } - - render(data, imgmap) { - var width = document.getElementById("createChart").clientWidth, - height = document.getElementById("createChart").clientHeight; - var cluster = d3.layout.tree() - .size([width, height]); - var diagonal = d3.svg.diagonal() - .projection(function (d) { - return [d.x - 18, d.y + 40]; - }); - var svg = d3.select("svg"); - - //marker - var marker = - svg.append("marker") - .attr("id", "resolved") - .attr("markerUnits", "strokeWidth") - .attr("markerUnits", "userSpaceOnUse") - .attr("viewBox", "0 -5 10 10") - .attr("refX", 22) - .attr("refY", 0) - .attr("markerWidth", 20) - .attr("markerHeight", 20) - .attr("orient", "auto") - .attr("stroke-width", 1) - .append("circle") - .attr("cx", 5) - .attr("cy", 0) - .attr("r", 2) - .attr("stroke-width", 1) - .style("stroke", "#2F8BF7") - .attr('fill', 'white'); - var i = 0; - var nodes = cluster.nodes(data).reverse(); - nodes.forEach(function (d) { - d.y = d.depth * 200 + 100; - - }); - - var links = cluster.links(nodes); - - var linkEnter = svg.selectAll("path.link") - .data(links); - - linkEnter.enter().append("path") - .attr("class", "link") - .attr("d", diagonal) - .style("stroke", "#2F8BF7") - .style('stroke-width', '1px') - .attr("marker-end", "url(#resolved)") - .style("fill", "none") - // .style("fill-opacity", 1) - .attr("id", function (d, i) { - return "mypath" + i; - }); - - var node = svg.selectAll(".node") - .data(nodes) - .enter() - .append("g") - .attr("class", "node") - .attr("transform", function (d) { - return "translate(" + (d.x + -50) + "," + (d.y) + ")"; - }); - - node.append('image') - .attr('xlink:href', function (d) { - if (d.type == "e2e") { - return imgmap[1]; - } else if (d.type == "ns") { - return imgmap[2]; - } else if (d.type == "vnf") { - return imgmap[3]; - } - - }) - .style('width', '12%') - .style("cursor", "pointer") - .attr("x", 0) - .attr("y", 0) - .attr("rx", 3); - - - } - -} |